Xen 
 
Home About Xen.org Xen Xen Summit Wiki Mailing List Bug Tracker Xen Downloads
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 26 Oct 2006 12:10:54 +0000
Delivery-date: Thu, 26 Oct 2006 05:15:52 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID b725c9e51a7cebc8069c95986179a819ff6bf563
# Parent  5176c3ea32938ab37f9b60d3716de33ee3192d9e
# Parent  7da100019e00018346877608d9110f1bde8817d5
merge with xen-unstable.hg
---
 linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c      |    8 
 linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c      |   14 
 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c   |  142 +++--
 linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c   |   51 --
 linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c     |  136 +----
 linux-2.6-xen-sparse/drivers/xen/netback/common.h    |    2 
 linux-2.6-xen-sparse/drivers/xen/netback/interface.c |   26 -
 linux-2.6-xen-sparse/drivers/xen/netback/netback.c   |  162 +++---
 linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c    |   89 ---
 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c |  170 ++++--
 linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c   |  170 ++++--
 linux-2.6-xen-sparse/drivers/xen/tpmback/common.h    |    8 
 linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c |   19 
 linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c   |   14 
 linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h   |    1 
 linux-2.6-xen-sparse/include/xen/balloon.h           |   20 
 linux-2.6-xen-sparse/mm/memory.c                     |    5 
 tools/blktap/drivers/Makefile                        |    3 
 tools/blktap/drivers/blktapctrl.c                    |   16 
 tools/blktap/lib/blktaplib.h                         |    4 
 tools/blktap/lib/xenbus.c                            |  191 ++++---
 tools/blktap/lib/xs_api.c                            |  103 +---
 tools/blktap/lib/xs_api.h                            |    2 
 tools/examples/block                                 |    1 
 tools/examples/xend-config.sxp                       |    5 
 tools/examples/xmexample.hvm                         |    5 
 tools/firmware/acpi/acpi_dsdt.asl                    |   66 +-
 tools/firmware/acpi/acpi_dsdt.c                      |  470 +++++++++----------
 tools/firmware/hvmloader/smbios.c                    |    1 
 tools/ioemu/vl.c                                     |   35 +
 tools/ioemu/vl.h                                     |    4 
 tools/ioemu/vnc.c                                    |   14 
 tools/libxc/xc_load_elf.c                            |    2 
 tools/misc/mbootpack/Makefile                        |   17 
 tools/misc/mbootpack/buildimage.c                    |   19 
 tools/misc/mbootpack/mbootpack.c                     |   20 
 tools/misc/miniterm/miniterm.c                       |   25 -
 tools/python/xen/util/blkif.py                       |    2 
 tools/python/xen/xend/XendDomainInfo.py              |    2 
 tools/python/xen/xend/XendRoot.py                    |    6 
 tools/python/xen/xend/image.py                       |    5 
 tools/python/xen/xm/create.py                        |    9 
 tools/python/xen/xm/main.py                          |    5 
 tools/xenstore/xenstore_client.c                     |   21 
 tools/xenstore/xenstored_transaction.c               |    2 
 xen/arch/x86/Makefile                                |   17 
 xen/arch/x86/domain_build.c                          |    4 
 xen/arch/x86/hvm/hvm.c                               |    4 
 xen/arch/x86/hvm/svm/intr.c                          |    9 
 xen/arch/x86/hvm/svm/svm.c                           |   10 
 xen/arch/x86/hvm/vmx/vmx.c                           |  126 ++---
 xen/arch/x86/microcode.c                             |   11 
 xen/arch/x86/mm/shadow/multi.c                       |  138 ++---
 xen/arch/x86/platform_hypercall.c                    |   16 
 xen/arch/x86/x86_32/asm-offsets.c                    |    1 
 xen/arch/x86/x86_64/asm-offsets.c                    |    1 
 xen/common/elf.c                                     |    2 
 xen/include/asm-x86/hvm/vmx/vmcs.h                   |   15 
 xen/include/asm-x86/hvm/vmx/vmx.h                    |   32 -
 xen/include/asm-x86/msr.h                            |    8 
 xen/include/asm-x86/multicall.h                      |    2 
 xen/include/asm-x86/perfc_defn.h                     |    4 
 62 files changed, 1275 insertions(+), 1217 deletions(-)

diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c   Sun Oct 08 18:55:12 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c   Sat Oct 14 13:28:45 
2006 -0600
@@ -28,6 +28,8 @@ static int direct_remap_area_pte_fn(pte_
                                    void *data)
 {
        mmu_update_t **v = (mmu_update_t **)data;
+
+       BUG_ON(!pte_none(*pte));
 
        (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pmd_page)) <<
                     PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
@@ -110,11 +112,13 @@ int direct_remap_pfn_range(struct vm_are
                           pgprot_t prot,
                           domid_t  domid)
 {
-       /* Same as remap_pfn_range(). */
-       vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return remap_pfn_range(vma, address, mfn, size, prot);
 
        if (domid == DOMID_SELF)
                return -EINVAL;
+
+       vma->vm_flags |= VM_IO | VM_RESERVED;
 
        vma->vm_mm->context.has_foreign_mappings = 1;
 
diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c   Sun Oct 08 18:55:12 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c   Sat Oct 14 13:28:45 
2006 -0600
@@ -478,6 +478,7 @@ struct xen_ia64_privcmd_range {
 };
 
 struct xen_ia64_privcmd_vma {
+       int                             is_privcmd_mmapped;
        struct xen_ia64_privcmd_range*  range;
 
        unsigned long                   num_entries;
@@ -616,12 +617,15 @@ static void
 static void
 xen_ia64_privcmd_vma_open(struct vm_area_struct* vma)
 {
+       struct xen_ia64_privcmd_vma* old_privcmd_vma = (struct 
xen_ia64_privcmd_vma*)vma->vm_private_data;
        struct xen_ia64_privcmd_vma* privcmd_vma = (struct 
xen_ia64_privcmd_vma*)vma->vm_private_data;
        struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
 
        atomic_inc(&privcmd_range->ref_count);
        // vm_op->open() can't fail.
        privcmd_vma = kmalloc(sizeof(*privcmd_vma), GFP_KERNEL | __GFP_NOFAIL);
+       // copy original value if necessary
+       privcmd_vma->is_privcmd_mmapped = old_privcmd_vma->is_privcmd_mmapped;
 
        __xen_ia64_privcmd_vma_open(vma, privcmd_vma, privcmd_range);
 }
@@ -654,6 +658,14 @@ xen_ia64_privcmd_vma_close(struct vm_are
                kfree(privcmd_range->res);
                vfree(privcmd_range);
        }
+}
+
+int
+privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma)
+{
+       struct xen_ia64_privcmd_vma* privcmd_vma =
+               (struct xen_ia64_privcmd_vma *)vma->vm_private_data;
+       return (xchg(&privcmd_vma->is_privcmd_mmapped, 1) == 0);
 }
 
 int
@@ -681,6 +693,8 @@ privcmd_mmap(struct file * file, struct 
        if (privcmd_vma == NULL) {
                goto out_enomem1;
        }
+       privcmd_vma->is_privcmd_mmapped = 0;
+
        res = kzalloc(sizeof(*res), GFP_KERNEL);
        if (res == NULL) {
                goto out_enomem1;
diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Sun Oct 08 
18:55:12 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Sat Oct 14 
13:28:45 2006 -0600
@@ -534,74 +534,86 @@ static int dealloc_pte_fn(
        return 0;
 }
 
-struct page *balloon_alloc_empty_page_range(unsigned long nr_pages)
-{
-       unsigned long vstart, flags;
-       unsigned int  order = get_order(nr_pages * PAGE_SIZE);
-       int ret;
-       unsigned long i;
-       struct page *page;
-
-       vstart = __get_free_pages(GFP_KERNEL, order);
-       if (vstart == 0)
+struct page **alloc_empty_pages_and_pagevec(int nr_pages)
+{
+       unsigned long vaddr, flags;
+       struct page *page, **pagevec;
+       int i, ret;
+
+       pagevec = kmalloc(sizeof(page) * nr_pages, GFP_KERNEL);
+       if (pagevec == NULL)
                return NULL;
 
-       scrub_pages(vstart, 1 << order);
-
+       for (i = 0; i < nr_pages; i++) {
+               page = pagevec[i] = alloc_page(GFP_KERNEL);
+               if (page == NULL)
+                       goto err;
+
+               vaddr = (unsigned long)page_address(page);
+
+               scrub_pages(vaddr, 1);
+
+               balloon_lock(flags);
+
+               if (xen_feature(XENFEAT_auto_translated_physmap)) {
+                       unsigned long gmfn = page_to_pfn(page);
+                       struct xen_memory_reservation reservation = {
+                               .nr_extents   = 1,
+                               .extent_order = 0,
+                               .domid        = DOMID_SELF
+                       };
+                       set_xen_guest_handle(reservation.extent_start, &gmfn);
+                       ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+                                                  &reservation);
+                       if (ret == 1)
+                               ret = 0; /* success */
+               } else {
+                       ret = apply_to_page_range(&init_mm, vaddr, PAGE_SIZE,
+                                                 dealloc_pte_fn, NULL);
+               }
+
+               if (ret != 0) {
+                       balloon_unlock(flags);
+                       __free_page(page);
+                       goto err;
+               }
+
+               totalram_pages = --current_pages;
+
+               balloon_unlock(flags);
+       }
+
+ out:
+       schedule_work(&balloon_worker);
+       flush_tlb_all();
+       return pagevec;
+
+ err:
        balloon_lock(flags);
-       if (xen_feature(XENFEAT_auto_translated_physmap)) {
-               unsigned long gmfn = __pa(vstart) >> PAGE_SHIFT;
-               struct xen_memory_reservation reservation = {
-                       .nr_extents   = 1,
-                       .extent_order = order,
-                       .domid        = DOMID_SELF
-               };
-               set_xen_guest_handle(reservation.extent_start, &gmfn);
-               ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
-                                          &reservation);
-               if (ret == -ENOSYS)
-                       goto err;
-               BUG_ON(ret != 1);
-       } else {
-               ret = apply_to_page_range(&init_mm, vstart, PAGE_SIZE << order,
-                                         dealloc_pte_fn, NULL);
-               if (ret == -ENOSYS)
-                       goto err;
-               BUG_ON(ret);
-       }
-       current_pages -= 1UL << order;
-       totalram_pages = current_pages;
+       while (--i >= 0)
+               balloon_append(pagevec[i]);
        balloon_unlock(flags);
-
-       schedule_work(&balloon_worker);
-
-       flush_tlb_all();
-
-       page = virt_to_page(vstart);
-
-       for (i = 0; i < (1UL << order); i++)
-               set_page_count(page + i, 1);
-
-       return page;
-
- err:
-       free_pages(vstart, order);
+       kfree(pagevec);
+       pagevec = NULL;
+       goto out;
+}
+
+void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages)
+{
+       unsigned long flags;
+       int i;
+
+       if (pagevec == NULL)
+               return;
+
+       balloon_lock(flags);
+       for (i = 0; i < nr_pages; i++) {
+               BUG_ON(page_count(pagevec[i]) != 1);
+               balloon_append(pagevec[i]);
+       }
        balloon_unlock(flags);
-       return NULL;
-}
-
-void balloon_dealloc_empty_page_range(
-       struct page *page, unsigned long nr_pages)
-{
-       unsigned long i, flags;
-       unsigned int  order = get_order(nr_pages * PAGE_SIZE);
-
-       balloon_lock(flags);
-       for (i = 0; i < (1UL << order); i++) {
-               BUG_ON(page_count(page + i) != 1);
-               balloon_append(page + i);
-       }
-       balloon_unlock(flags);
+
+       kfree(pagevec);
 
        schedule_work(&balloon_worker);
 }
@@ -619,8 +631,8 @@ void balloon_release_driver_page(struct 
 }
 
 EXPORT_SYMBOL_GPL(balloon_update_driver_allowance);
-EXPORT_SYMBOL_GPL(balloon_alloc_empty_page_range);
-EXPORT_SYMBOL_GPL(balloon_dealloc_empty_page_range);
+EXPORT_SYMBOL_GPL(alloc_empty_pages_and_pagevec);
+EXPORT_SYMBOL_GPL(free_empty_pages_and_pagevec);
 EXPORT_SYMBOL_GPL(balloon_release_driver_page);
 
 MODULE_LICENSE("Dual BSD/GPL");
diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Sun Oct 08 
18:55:12 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Sat Oct 14 
13:28:45 2006 -0600
@@ -55,8 +55,6 @@ static int blkif_reqs = 64;
 static int blkif_reqs = 64;
 module_param_named(reqs, blkif_reqs, int, 0);
 MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate");
-
-static int mmap_pages;
 
 /* Run-time switchable: /sys/module/blkback/parameters/ */
 static unsigned int log_stats = 0;
@@ -87,8 +85,7 @@ static DECLARE_WAIT_QUEUE_HEAD(pending_f
 
 #define BLKBACK_INVALID_HANDLE (~0)
 
-static unsigned long mmap_vstart;
-static unsigned long *pending_vaddrs;
+static struct page **pending_pages;
 static grant_handle_t *pending_grant_handles;
 
 static inline int vaddr_pagenr(pending_req_t *req, int seg)
@@ -98,7 +95,8 @@ static inline int vaddr_pagenr(pending_r
 
 static inline unsigned long vaddr(pending_req_t *req, int seg)
 {
-       return pending_vaddrs[vaddr_pagenr(req, seg)];
+       unsigned long pfn = page_to_pfn(pending_pages[vaddr_pagenr(req, seg)]);
+       return (unsigned long)pfn_to_kaddr(pfn);
 }
 
 #define pending_handle(_req, _seg) \
@@ -506,52 +504,43 @@ static void make_response(blkif_t *blkif
 
 static int __init blkif_init(void)
 {
-       struct page *page;
-       int i;
+       int i, mmap_pages;
 
        if (!is_running_on_xen())
                return -ENODEV;
 
-       mmap_pages            = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
-
-       page = balloon_alloc_empty_page_range(mmap_pages);
-       if (page == NULL)
-               return -ENOMEM;
-       mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+       mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
 
        pending_reqs          = kmalloc(sizeof(pending_reqs[0]) *
                                        blkif_reqs, GFP_KERNEL);
        pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) *
                                        mmap_pages, GFP_KERNEL);
-       pending_vaddrs        = kmalloc(sizeof(pending_vaddrs[0]) *
-                                       mmap_pages, GFP_KERNEL);
-       if (!pending_reqs || !pending_grant_handles || !pending_vaddrs) {
-               kfree(pending_reqs);
-               kfree(pending_grant_handles);
-               kfree(pending_vaddrs);
-               printk("%s: out of memory\n", __FUNCTION__);
-               return -ENOMEM;
-       }
+       pending_pages         = alloc_empty_pages_and_pagevec(mmap_pages);
+
+       if (!pending_reqs || !pending_grant_handles || !pending_pages)
+               goto out_of_memory;
+
+       for (i = 0; i < mmap_pages; i++)
+               pending_grant_handles[i] = BLKBACK_INVALID_HANDLE;
 
        blkif_interface_init();
-       
-       printk("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
-              __FUNCTION__, blkif_reqs, mmap_pages, mmap_vstart);
-       BUG_ON(mmap_vstart == 0);
-       for (i = 0; i < mmap_pages; i++) {
-               pending_vaddrs[i] = mmap_vstart + (i << PAGE_SHIFT);
-               pending_grant_handles[i] = BLKBACK_INVALID_HANDLE;
-       }
 
        memset(pending_reqs, 0, sizeof(pending_reqs));
        INIT_LIST_HEAD(&pending_free);
 
        for (i = 0; i < blkif_reqs; i++)
                list_add_tail(&pending_reqs[i].free_list, &pending_free);
-    
+
        blkif_xenbus_init();
 
        return 0;
+
+ out_of_memory:
+       kfree(pending_reqs);
+       kfree(pending_grant_handles);
+       free_empty_pages_and_pagevec(pending_pages, mmap_pages);
+       printk("%s: out of memory\n", __FUNCTION__);
+       return -ENOMEM;
 }
 
 module_init(blkif_init);
diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Sun Oct 08 18:55:12 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Sat Oct 14 13:28:45 
2006 -0600
@@ -186,16 +186,18 @@ static inline unsigned int RTN_PEND_IDX(
 
 #define BLKBACK_INVALID_HANDLE (~0)
 
-typedef struct mmap_page {
-       unsigned long start;
-       struct page *mpage;
-} mmap_page_t;
-
-static mmap_page_t mmap_start[MAX_DYNAMIC_MEM];
+static struct page **foreign_pages[MAX_DYNAMIC_MEM];
+static inline unsigned long idx_to_kaddr(
+       unsigned int mmap_idx, unsigned int req_idx, unsigned int sg_idx)
+{
+       unsigned int arr_idx = req_idx*BLKIF_MAX_SEGMENTS_PER_REQUEST + sg_idx;
+       unsigned long pfn = page_to_pfn(foreign_pages[mmap_idx][arr_idx]);
+       return (unsigned long)pfn_to_kaddr(pfn);
+}
+
 static unsigned short mmap_alloc = 0;
 static unsigned short mmap_lock = 0;
 static unsigned short mmap_inuse = 0;
-static unsigned long *pending_addrs[MAX_DYNAMIC_MEM];
 
 /******************************************************************
  * GRANT HANDLES
@@ -726,63 +728,21 @@ static int req_increase(void)
 static int req_increase(void)
 {
        int i, j;
-       struct page *page;
-       int ret;
-
-       ret = -EINVAL;
+
        if (mmap_alloc >= MAX_PENDING_REQS || mmap_lock) 
-               goto done;
-
-#ifdef __ia64__
-       extern unsigned long alloc_empty_foreign_map_page_range(
-               unsigned long pages);
-       mmap_start[mmap_alloc].start = (unsigned long)
-               alloc_empty_foreign_map_page_range(mmap_pages);
-#else /* ! ia64 */
-       page = balloon_alloc_empty_page_range(mmap_pages);
-       ret = -ENOMEM;
-       if (page == NULL) {
-               printk("%s balloon_alloc_empty_page_range gave NULL\n", 
__FUNCTION__);
-               goto done;
-       }
-
-       /* Pin all of the pages. */
-       for (i=0; i<mmap_pages; i++)
-               get_page(&page[i]);
-
-       mmap_start[mmap_alloc].start = 
-               (unsigned long)pfn_to_kaddr(page_to_pfn(page));
-       mmap_start[mmap_alloc].mpage = page;
-
-#endif
-
-       pending_reqs[mmap_alloc]  = kzalloc(sizeof(pending_req_t) *
-                                       blkif_reqs, GFP_KERNEL);
-       pending_addrs[mmap_alloc] = kzalloc(sizeof(unsigned long) *
-                                       mmap_pages, GFP_KERNEL);
-
-       ret = -ENOMEM;
-       if (!pending_reqs[mmap_alloc] || !pending_addrs[mmap_alloc]) {
-               kfree(pending_reqs[mmap_alloc]);
-               kfree(pending_addrs[mmap_alloc]);
-               WPRINTK("%s: out of memory\n", __FUNCTION__);
-               ret = -ENOMEM;
-               goto done;
-       }
-
-       ret = 0;
-
-       DPRINTK("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
-               __FUNCTION__, blkif_reqs, mmap_pages, 
-              mmap_start[mmap_alloc].start);
-
-       BUG_ON(mmap_start[mmap_alloc].start == 0);
-
-       for (i = 0; i < mmap_pages; i++) 
-               pending_addrs[mmap_alloc][i] = 
-                       mmap_start[mmap_alloc].start + (i << PAGE_SHIFT);
-
-       for (i = 0; i < MAX_PENDING_REQS ; i++) {
+               return -EINVAL;
+
+       pending_reqs[mmap_alloc]  = kzalloc(sizeof(pending_req_t)
+                                           * blkif_reqs, GFP_KERNEL);
+       foreign_pages[mmap_alloc] = alloc_empty_pages_and_pagevec(mmap_pages);
+
+       if (!pending_reqs[mmap_alloc] || !foreign_pages[mmap_alloc])
+               goto out_of_memory;
+
+       DPRINTK("%s: reqs=%d, pages=%d\n",
+               __FUNCTION__, blkif_reqs, mmap_pages);
+
+       for (i = 0; i < MAX_PENDING_REQS; i++) {
                list_add_tail(&pending_reqs[mmap_alloc][i].free_list, 
                              &pending_free);
                pending_reqs[mmap_alloc][i].mem_idx = mmap_alloc;
@@ -793,30 +753,24 @@ static int req_increase(void)
 
        mmap_alloc++;
        DPRINTK("# MMAPs increased to %d\n",mmap_alloc);
-done:
-       return ret;
+       return 0;
+
+ out_of_memory:
+       free_empty_pages_and_pagevec(foreign_pages[mmap_alloc], mmap_pages);
+       kfree(pending_reqs[mmap_alloc]);
+       WPRINTK("%s: out of memory\n", __FUNCTION__);
+       return -ENOMEM;
 }
 
 static void mmap_req_del(int mmap)
 {
-       int i;
-       struct page *page;
-
-       /*Spinlock already acquired*/
+       BUG_ON(!spin_is_locked(&pending_free_lock));
+
        kfree(pending_reqs[mmap]);
-       kfree(pending_addrs[mmap]);
-
-#ifdef __ia64__
-       /*Not sure what goes here yet!*/
-#else
-
-       /* Unpin all of the pages. */
-       page = mmap_start[mmap].mpage;
-       for (i=0; i<mmap_pages; i++)
-               put_page(&page[i]);
-
-       balloon_dealloc_empty_page_range(mmap_start[mmap].mpage, mmap_pages);
-#endif
+       pending_reqs[mmap] = NULL;
+
+       free_empty_pages_and_pagevec(foreign_pages[mmap_alloc], mmap_pages);
+       foreign_pages[mmap] = NULL;
 
        mmap_lock = 0;
        DPRINTK("# MMAPs decreased to %d\n",mmap_alloc);
@@ -887,7 +841,7 @@ static void fast_flush_area(pending_req_
        mmap_idx = req->mem_idx;
 
        for (i = 0; i < req->nr_pages; i++) {
-               kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, k_idx, i);
+               kvaddr = idx_to_kaddr(mmap_idx, k_idx, i);
                uvaddr = MMAP_VADDR(info->user_vstart, u_idx, i);
 
                khandle = &pending_handle(mmap_idx, k_idx, i);
@@ -896,7 +850,7 @@ static void fast_flush_area(pending_req_
                        continue;
                }
                gnttab_set_unmap_op(&unmap[invcount], 
-                       MMAP_VADDR(mmap_start[mmap_idx].start, k_idx, i), 
+                                   idx_to_kaddr(mmap_idx, k_idx, i), 
                                    GNTMAP_host_map, khandle->kernel);
                invcount++;
 
@@ -1030,9 +984,8 @@ static int blktap_read_ufe_ring(tap_blki
                        struct page *pg;
                        int offset;
 
-                       uvaddr  = MMAP_VADDR(info->user_vstart, usr_idx, j);
-                       kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, 
-                                           pending_idx, j);
+                       uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, j);
+                       kvaddr = idx_to_kaddr(mmap_idx, pending_idx, j);
 
                        pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
                        ClearPageReserved(pg);
@@ -1214,8 +1167,7 @@ static void dispatch_rw_block_io(blkif_t
                uint32_t flags;
 
                uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i);
-               kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, 
-                                   pending_idx, i);
+               kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
                page = virt_to_page(kvaddr);
 
                sector = req->sector_number + (8*i);
@@ -1267,8 +1219,7 @@ static void dispatch_rw_block_io(blkif_t
                struct page *pg;
 
                uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i/2);
-               kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, 
-                                   pending_idx, i/2);
+               kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i/2);
 
                if (unlikely(map[i].status != 0)) {
                        WPRINTK("invalid kernel buffer -- "
@@ -1298,8 +1249,7 @@ static void dispatch_rw_block_io(blkif_t
                unsigned long kvaddr;
                struct page *pg;
 
-               kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, 
-                                   pending_idx, i);
+               kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
                pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
                SetPageReserved(pg);
        }
diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Sun Oct 08 18:55:12 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Sat Oct 14 13:28:45 
2006 -0600
@@ -106,7 +106,7 @@ typedef struct netif_st {
 
 void netif_disconnect(netif_t *netif);
 
-netif_t *netif_alloc(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
+netif_t *netif_alloc(domid_t domid, unsigned int handle);
 int netif_map(netif_t *netif, unsigned long tx_ring_ref,
              unsigned long rx_ring_ref, unsigned int evtchn);
 
diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Sun Oct 08 
18:55:12 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Sat Oct 14 
13:28:45 2006 -0600
@@ -62,6 +62,7 @@ static void __netif_down(netif_t *netif)
 {
        disable_irq(netif->irq);
        netif_deschedule_work(netif);
+       del_timer_sync(&netif->credit_timeout);
 }
 
 static int net_open(struct net_device *dev)
@@ -125,7 +126,7 @@ static struct ethtool_ops network_ethtoo
        .get_link = ethtool_op_get_link,
 };
 
-netif_t *netif_alloc(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN])
+netif_t *netif_alloc(domid_t domid, unsigned int handle)
 {
        int err = 0, i;
        struct net_device *dev;
@@ -152,6 +153,7 @@ netif_t *netif_alloc(domid_t domid, unsi
        netif->credit_bytes = netif->remaining_credit = ~0UL;
        netif->credit_usec  = 0UL;
        init_timer(&netif->credit_timeout);
+       netif->credit_timeout.expires = jiffies;
 
        dev->hard_start_xmit = netif_be_start_xmit;
        dev->get_stats       = netif_be_get_stats;
@@ -167,20 +169,14 @@ netif_t *netif_alloc(domid_t domid, unsi
                printk(KERN_WARNING "netbk: WARNING: device '%s' has non-zero "
                       "queue length (%lu)!\n", dev->name, dev->tx_queue_len);
 
-       for (i = 0; i < ETH_ALEN; i++)
-               if (be_mac[i] != 0)
-                       break;
-       if (i == ETH_ALEN) {
-               /*
-                * Initialise a dummy MAC address. We choose the numerically
-                * largest non-broadcast address to prevent the address getting
-                * stolen by an Ethernet bridge for STP purposes.
-                * (FE:FF:FF:FF:FF:FF)
-                */ 
-               memset(dev->dev_addr, 0xFF, ETH_ALEN);
-               dev->dev_addr[0] &= ~0x01;
-       } else
-               memcpy(dev->dev_addr, be_mac, ETH_ALEN);
+       /*
+        * Initialise a dummy MAC address. We choose the numerically
+        * largest non-broadcast address to prevent the address getting
+        * stolen by an Ethernet bridge for STP purposes.
+        * (FE:FF:FF:FF:FF:FF)
+        */ 
+       memset(dev->dev_addr, 0xFF, ETH_ALEN);
+       dev->dev_addr[0] &= ~0x01;
 
        rtnl_lock();
        err = register_netdevice(dev);
diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Sun Oct 08 
18:55:12 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Sat Oct 14 
13:28:45 2006 -0600
@@ -70,14 +70,15 @@ static struct timer_list net_timer;
 
 static struct sk_buff_head rx_queue;
 
-static unsigned long mmap_vstart;
-#define MMAP_VADDR(_req) (mmap_vstart + ((_req) * PAGE_SIZE))
-
-static void *rx_mmap_area;
+static struct page **mmap_pages;
+static inline unsigned long idx_to_kaddr(unsigned int idx)
+{
+       return (unsigned long)pfn_to_kaddr(page_to_pfn(mmap_pages[idx]));
+}
 
 #define PKT_PROT_LEN 64
 
-static struct {
+static struct pending_tx_info {
        netif_tx_request_t req;
        netif_t *netif;
 } pending_tx_info[MAX_PENDING_REQS];
@@ -373,14 +374,22 @@ static u16 netbk_gop_frag(netif_t *netif
                   flipped. */
                meta->copy = 1;
                copy_gop = npo->copy + npo->copy_prod++;
-               copy_gop->source.domid = DOMID_SELF;
+               copy_gop->flags = GNTCOPY_dest_gref;
+               if (PageForeign(page)) {
+                       struct pending_tx_info *src_pend =
+                               &pending_tx_info[page->index];
+                       copy_gop->source.domid = src_pend->netif->domid;
+                       copy_gop->source.u.ref = src_pend->req.gref;
+                       copy_gop->flags |= GNTCOPY_source_gref;
+               } else {
+                       copy_gop->source.domid = DOMID_SELF;
+                       copy_gop->source.u.gmfn = old_mfn;
+               }
                copy_gop->source.offset = offset;
-               copy_gop->source.u.gmfn = old_mfn;
                copy_gop->dest.domid = netif->domid;
                copy_gop->dest.offset = 0;
                copy_gop->dest.u.ref = req->gref;
                copy_gop->len = size;
-               copy_gop->flags = GNTCOPY_dest_gref;
        } else {
                meta->copy = 0;
                if (!xen_feature(XENFEAT_auto_translated_physmap)) {
@@ -792,10 +801,27 @@ void netif_deschedule_work(netif_t *neti
 }
 
 
+static void tx_add_credit(netif_t *netif)
+{
+       unsigned long max_burst;
+
+       /*
+        * Allow a burst big enough to transmit a jumbo packet of up to 128kB.
+        * Otherwise the interface can seize up due to insufficient credit.
+        */
+       max_burst = RING_GET_REQUEST(&netif->tx, netif->tx.req_cons)->size;
+       max_burst = min(max_burst, 131072UL);
+       max_burst = max(max_burst, netif->credit_bytes);
+
+       netif->remaining_credit = min(netif->remaining_credit +
+                                     netif->credit_bytes,
+                                     max_burst);
+}
+
 static void tx_credit_callback(unsigned long data)
 {
        netif_t *netif = (netif_t *)data;
-       netif->remaining_credit = netif->credit_bytes;
+       tx_add_credit(netif);
        netif_schedule_work(netif);
 }
 
@@ -819,7 +845,7 @@ inline static void net_tx_action_dealloc
        gop = tx_unmap_ops;
        while (dc != dp) {
                pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
-               gnttab_set_unmap_op(gop, MMAP_VADDR(pending_idx),
+               gnttab_set_unmap_op(gop, idx_to_kaddr(pending_idx),
                                    GNTMAP_host_map,
                                    grant_tx_handle[pending_idx]);
                gop++;
@@ -857,20 +883,28 @@ static void netbk_tx_err(netif_t *netif,
        netif_put(netif);
 }
 
-static int netbk_count_requests(netif_t *netif, netif_tx_request_t *txp,
-                               int work_to_do)
-{
-       netif_tx_request_t *first = txp;
+static int netbk_count_requests(netif_t *netif, netif_tx_request_t *first,
+                               netif_tx_request_t *txp, int work_to_do)
+{
        RING_IDX cons = netif->tx.req_cons;
        int frags = 0;
 
-       while (txp->flags & NETTXF_more_data) {
+       if (!(first->flags & NETTXF_more_data))
+               return 0;
+
+       do {
                if (frags >= work_to_do) {
                        DPRINTK("Need more frags\n");
                        return -frags;
                }
 
-               txp = RING_GET_REQUEST(&netif->tx, cons + frags);
+               if (unlikely(frags >= MAX_SKB_FRAGS)) {
+                       DPRINTK("Too many frags\n");
+                       return -frags;
+               }
+
+               memcpy(txp, RING_GET_REQUEST(&netif->tx, cons + frags),
+                      sizeof(*txp));
                if (txp->size > first->size) {
                        DPRINTK("Frags galore\n");
                        return -frags;
@@ -884,30 +918,28 @@ static int netbk_count_requests(netif_t 
                                txp->offset, txp->size);
                        return -frags;
                }
-       }
+       } while ((txp++)->flags & NETTXF_more_data);
 
        return frags;
 }
 
 static gnttab_map_grant_ref_t *netbk_get_requests(netif_t *netif,
                                                  struct sk_buff *skb,
+                                                 netif_tx_request_t *txp,
                                                  gnttab_map_grant_ref_t *mop)
 {
        struct skb_shared_info *shinfo = skb_shinfo(skb);
        skb_frag_t *frags = shinfo->frags;
-       netif_tx_request_t *txp;
        unsigned long pending_idx = *((u16 *)skb->data);
-       RING_IDX cons = netif->tx.req_cons;
        int i, start;
 
        /* Skip first skb fragment if it is on same page as header fragment. */
        start = ((unsigned long)shinfo->frags[0].page == pending_idx);
 
-       for (i = start; i < shinfo->nr_frags; i++) {
-               txp = RING_GET_REQUEST(&netif->tx, cons++);
+       for (i = start; i < shinfo->nr_frags; i++, txp++) {
                pending_idx = pending_ring[MASK_PEND_IDX(pending_cons++)];
 
-               gnttab_set_map_op(mop++, MMAP_VADDR(pending_idx),
+               gnttab_set_map_op(mop++, idx_to_kaddr(pending_idx),
                                  GNTMAP_host_map | GNTMAP_readonly,
                                  txp->gref, netif->domid);
 
@@ -940,7 +972,7 @@ static int netbk_tx_check_mop(struct sk_
                netif_put(netif);
        } else {
                set_phys_to_machine(
-                       __pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT,
+                       __pa(idx_to_kaddr(pending_idx)) >> PAGE_SHIFT,
                        FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT));
                grant_tx_handle[pending_idx] = mop->handle;
        }
@@ -957,7 +989,7 @@ static int netbk_tx_check_mop(struct sk_
                newerr = (++mop)->status;
                if (likely(!newerr)) {
                        set_phys_to_machine(
-                               __pa(MMAP_VADDR(pending_idx))>>PAGE_SHIFT,
+                               __pa(idx_to_kaddr(pending_idx))>>PAGE_SHIFT,
                                FOREIGN_FRAME(mop->dev_bus_addr>>PAGE_SHIFT));
                        grant_tx_handle[pending_idx] = mop->handle;
                        /* Had a previous error? Invalidate this fragment. */
@@ -1005,7 +1037,7 @@ static void netbk_fill_frags(struct sk_b
 
                pending_idx = (unsigned long)frag->page;
                txp = &pending_tx_info[pending_idx].req;
-               frag->page = virt_to_page(MMAP_VADDR(pending_idx));
+               frag->page = virt_to_page(idx_to_kaddr(pending_idx));
                frag->size = txp->size;
                frag->page_offset = txp->offset;
 
@@ -1018,7 +1050,7 @@ int netbk_get_extras(netif_t *netif, str
 int netbk_get_extras(netif_t *netif, struct netif_extra_info *extras,
                     int work_to_do)
 {
-       struct netif_extra_info *extra;
+       struct netif_extra_info extra;
        RING_IDX cons = netif->tx.req_cons;
 
        do {
@@ -1027,18 +1059,18 @@ int netbk_get_extras(netif_t *netif, str
                        return -EBADR;
                }
 
-               extra = (struct netif_extra_info *)
-                       RING_GET_REQUEST(&netif->tx, cons);
-               if (unlikely(!extra->type ||
-                            extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
+               memcpy(&extra, RING_GET_REQUEST(&netif->tx, cons),
+                      sizeof(extra));
+               if (unlikely(!extra.type ||
+                            extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
                        netif->tx.req_cons = ++cons;
-                       DPRINTK("Invalid extra type: %d\n", extra->type);
+                       DPRINTK("Invalid extra type: %d\n", extra.type);
                        return -EINVAL;
                }
 
-               memcpy(&extras[extra->type - 1], extra, sizeof(*extra));
+               memcpy(&extras[extra.type - 1], &extra, sizeof(extra));
                netif->tx.req_cons = ++cons;
-       } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE);
+       } while (extra.flags & XEN_NETIF_EXTRA_FLAG_MORE);
 
        return work_to_do;
 }
@@ -1073,6 +1105,7 @@ static void net_tx_action(unsigned long 
        struct sk_buff *skb;
        netif_t *netif;
        netif_tx_request_t txreq;
+       netif_tx_request_t txfrags[MAX_SKB_FRAGS];
        struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
        u16 pending_idx;
        RING_IDX i;
@@ -1101,6 +1134,7 @@ static void net_tx_action(unsigned long 
                i = netif->tx.req_cons;
                rmb(); /* Ensure that we see the request before we copy it. */
                memcpy(&txreq, RING_GET_REQUEST(&netif->tx, i), sizeof(txreq));
+
                /* Credit-based scheduling. */
                if (txreq.size > netif->remaining_credit) {
                        unsigned long now = jiffies;
@@ -1109,25 +1143,27 @@ static void net_tx_action(unsigned long 
                                msecs_to_jiffies(netif->credit_usec / 1000);
 
                        /* Timer could already be pending in rare cases. */
-                       if (timer_pending(&netif->credit_timeout))
-                               break;
+                       if (timer_pending(&netif->credit_timeout)) {
+                               netif_put(netif);
+                               continue;
+                       }
 
                        /* Passed the point where we can replenish credit? */
                        if (time_after_eq(now, next_credit)) {
                                netif->credit_timeout.expires = now;
-                               netif->remaining_credit = netif->credit_bytes;
+                               tx_add_credit(netif);
                        }
 
                        /* Still too big to send right now? Set a callback. */
                        if (txreq.size > netif->remaining_credit) {
-                               netif->remaining_credit = 0;
                                netif->credit_timeout.data     =
                                        (unsigned long)netif;
                                netif->credit_timeout.function =
                                        tx_credit_callback;
                                __mod_timer(&netif->credit_timeout,
                                            next_credit);
-                               break;
+                               netif_put(netif);
+                               continue;
                        }
                }
                netif->remaining_credit -= txreq.size;
@@ -1146,18 +1182,12 @@ static void net_tx_action(unsigned long 
                        }
                }
 
-               ret = netbk_count_requests(netif, &txreq, work_to_do);
+               ret = netbk_count_requests(netif, &txreq, txfrags, work_to_do);
                if (unlikely(ret < 0)) {
                        netbk_tx_err(netif, &txreq, i - ret);
                        continue;
                }
                i += ret;
-
-               if (unlikely(ret > MAX_SKB_FRAGS)) {
-                       DPRINTK("Too many frags\n");
-                       netbk_tx_err(netif, &txreq, i);
-                       continue;
-               }
 
                if (unlikely(txreq.size < ETH_HLEN)) {
                        DPRINTK("Bad packet size: %d\n", txreq.size);
@@ -1201,7 +1231,7 @@ static void net_tx_action(unsigned long 
                        }
                }
 
-               gnttab_set_map_op(mop, MMAP_VADDR(pending_idx),
+               gnttab_set_map_op(mop, idx_to_kaddr(pending_idx),
                                  GNTMAP_host_map | GNTMAP_readonly,
                                  txreq.gref, netif->domid);
                mop++;
@@ -1227,7 +1257,7 @@ static void net_tx_action(unsigned long 
 
                pending_cons++;
 
-               mop = netbk_get_requests(netif, skb, mop);
+               mop = netbk_get_requests(netif, skb, txfrags, mop);
 
                netif->tx.req_cons = i;
                netif_schedule_work(netif);
@@ -1260,8 +1290,8 @@ static void net_tx_action(unsigned long 
                }
 
                data_len = skb->len;
-               memcpy(skb->data, 
-                      (void *)(MMAP_VADDR(pending_idx)|txp->offset),
+               memcpy(skb->data,
+                      (void *)(idx_to_kaddr(pending_idx)|txp->offset),
                       data_len);
                if (data_len < txp->size) {
                        /* Append the packet payload as a fragment. */
@@ -1315,18 +1345,10 @@ static void netif_idx_release(u16 pendin
 
 static void netif_page_release(struct page *page)
 {
-       u16 pending_idx = page - virt_to_page(mmap_vstart);
-
        /* Ready for next use. */
        set_page_count(page, 1);
 
-       netif_idx_release(pending_idx);
-}
-
-static void netif_rx_page_release(struct page *page)
-{
-       /* Ready for next use. */
-       set_page_count(page, 1);
+       netif_idx_release(page->index);
 }
 
 irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs)
@@ -1446,27 +1468,17 @@ static int __init netback_init(void)
        init_timer(&net_timer);
        net_timer.data = 0;
        net_timer.function = net_alarm;
-    
-       page = balloon_alloc_empty_page_range(MAX_PENDING_REQS);
-       if (page == NULL)
+
+       mmap_pages = alloc_empty_pages_and_pagevec(MAX_PENDING_REQS);
+       if (mmap_pages == NULL) {
+               printk("%s: out of memory\n", __FUNCTION__);
                return -ENOMEM;
-
-       mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+       }
 
        for (i = 0; i < MAX_PENDING_REQS; i++) {
-               page = virt_to_page(MMAP_VADDR(i));
-               set_page_count(page, 1);
+               page = mmap_pages[i];
                SetPageForeign(page, netif_page_release);
-       }
-
-       page = balloon_alloc_empty_page_range(NET_RX_RING_SIZE);
-       BUG_ON(page == NULL);
-       rx_mmap_area = pfn_to_kaddr(page_to_pfn(page));
-
-       for (i = 0; i < NET_RX_RING_SIZE; i++) {
-               page = virt_to_page(rx_mmap_area + (i * PAGE_SIZE));
-               set_page_count(page, 1);
-               SetPageForeign(page, netif_rx_page_release);
+               page->index = i;
        }
 
        pending_cons = 0;
diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Sun Oct 08 18:55:12 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Sat Oct 14 13:28:45 
2006 -0600
@@ -28,29 +28,20 @@
     printk("netback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
 #endif
 
-struct backend_info
-{
+struct backend_info {
        struct xenbus_device *dev;
        netif_t *netif;
-       struct xenbus_watch backend_watch;
        enum xenbus_state frontend_state;
 };
 
 static int connect_rings(struct backend_info *);
 static void connect(struct backend_info *);
-static void maybe_connect(struct backend_info *);
-static void backend_changed(struct xenbus_watch *, const char **,
-                           unsigned int);
+static void backend_create_netif(struct backend_info *be);
 
 static int netback_remove(struct xenbus_device *dev)
 {
        struct backend_info *be = dev->dev.driver_data;
 
-       if (be->backend_watch.node) {
-               unregister_xenbus_watch(&be->backend_watch);
-               kfree(be->backend_watch.node);
-               be->backend_watch.node = NULL;
-       }
        if (be->netif) {
                netif_disconnect(be->netif);
                be->netif = NULL;
@@ -63,8 +54,7 @@ static int netback_remove(struct xenbus_
 
 /**
  * Entry point to this code when a new device is created.  Allocate the basic
- * structures, and watch the store waiting for the hotplug scripts to tell us
- * the device's handle.  Switch to InitWait.
+ * structures and switch to InitWait.
  */
 static int netback_probe(struct xenbus_device *dev,
                         const struct xenbus_device_id *id)
@@ -83,11 +73,6 @@ static int netback_probe(struct xenbus_d
        be->dev = dev;
        dev->dev.driver_data = be;
 
-       err = xenbus_watch_path2(dev, dev->nodename, "handle",
-                                &be->backend_watch, backend_changed);
-       if (err)
-               goto fail;
-
        do {
                err = xenbus_transaction_start(&xbt);
                if (err) {
@@ -108,7 +93,8 @@ static int netback_probe(struct xenbus_d
                        goto abort_transaction;
                }
 
-               err = xenbus_printf(xbt, dev->nodename, "feature-rx-copy", 
"%d", 1);
+               err = xenbus_printf(xbt, dev->nodename,
+                                   "feature-rx-copy", "%d", 1);
                if (err) {
                        message = "writing feature-copying";
                        goto abort_transaction;
@@ -123,9 +109,11 @@ static int netback_probe(struct xenbus_d
        }
 
        err = xenbus_switch_state(dev, XenbusStateInitWait);
-       if (err) {
+       if (err)
                goto fail;
-       }
+
+       /* This kicks hotplug scripts, so do it immediately. */
+       backend_create_netif(be);
 
        return 0;
 
@@ -175,48 +163,30 @@ static int netback_uevent(struct xenbus_
 }
 
 
-/**
- * Callback received when the hotplug scripts have placed the handle node.
- * Read it, and create a netif structure.  If the frontend is ready, connect.
- */
-static void backend_changed(struct xenbus_watch *watch,
-                           const char **vec, unsigned int len)
+static void backend_create_netif(struct backend_info *be)
 {
        int err;
        long handle;
-       struct backend_info *be
-               = container_of(watch, struct backend_info, backend_watch);
        struct xenbus_device *dev = be->dev;
 
-       DPRINTK("");
+       if (be->netif != NULL)
+               return;
 
        err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle);
-       if (XENBUS_EXIST_ERR(err)) {
-               /* Since this watch will fire once immediately after it is
-                  registered, we expect this.  Ignore it, and wait for the
-                  hotplug scripts. */
-               return;
-       }
        if (err != 1) {
                xenbus_dev_fatal(dev, err, "reading handle");
                return;
        }
 
-       if (be->netif == NULL) {
-               u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
-
-               be->netif = netif_alloc(dev->otherend_id, handle, be_mac);
-               if (IS_ERR(be->netif)) {
-                       err = PTR_ERR(be->netif);
-                       be->netif = NULL;
-                       xenbus_dev_fatal(dev, err, "creating interface");
-                       return;
-               }
-
-               kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE);
-
-               maybe_connect(be);
-       }
+       be->netif = netif_alloc(dev->otherend_id, handle);
+       if (IS_ERR(be->netif)) {
+               err = PTR_ERR(be->netif);
+               be->netif = NULL;
+               xenbus_dev_fatal(dev, err, "creating interface");
+               return;
+       }
+
+       kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE);
 }
 
 
@@ -249,11 +219,9 @@ static void frontend_changed(struct xenb
                break;
 
        case XenbusStateConnected:
-               if (!be->netif) {
-                       /* reconnect: setup be->netif */
-                       backend_changed(&be->backend_watch, NULL, 0);
-               }
-               maybe_connect(be);
+               backend_create_netif(be);
+               if (be->netif)
+                       connect(be);
                break;
 
        case XenbusStateClosing:
@@ -279,15 +247,6 @@ static void frontend_changed(struct xenb
 }
 
 
-/* ** Connection ** */
-
-
-static void maybe_connect(struct backend_info *be)
-{
-       if (be->netif && (be->frontend_state == XenbusStateConnected))
-               connect(be);
-}
-
 static void xen_net_read_rate(struct xenbus_device *dev,
                              unsigned long *bytes, unsigned long *usec)
 {
diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Sun Oct 08 
18:55:12 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Sat Oct 14 
13:28:45 2006 -0600
@@ -47,6 +47,7 @@
 #include <linux/in.h>
 #include <linux/if_ether.h>
 #include <linux/io.h>
+#include <linux/moduleparam.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <net/arp.h>
@@ -85,17 +86,42 @@ static const int MODPARM_rx_flip = 0;
 #define RX_COPY_THRESHOLD 256
 
 /* If we don't have GSO, fake things up so that we never try to use it. */
-#ifndef NETIF_F_GSO
-#define netif_needs_gso(dev, skb)      0
-#define dev_disable_gso_features(dev)  ((void)0)
-#else
+#if defined(NETIF_F_GSO)
 #define HAVE_GSO                       1
+#define HAVE_TSO                       1 /* TSO is a subset of GSO */
 static inline void dev_disable_gso_features(struct net_device *dev)
 {
        /* Turn off all GSO bits except ROBUST. */
        dev->features &= (1 << NETIF_F_GSO_SHIFT) - 1;
        dev->features |= NETIF_F_GSO_ROBUST;
 }
+#elif defined(NETIF_F_TSO)
+#define HAVE_TSO                       1
+#define gso_size tso_size
+#define gso_segs tso_segs
+static inline void dev_disable_gso_features(struct net_device *dev)
+{
+       /* Turn off all TSO bits. */
+       dev->features &= ~NETIF_F_TSO;
+}
+static inline int skb_is_gso(const struct sk_buff *skb)
+{
+        return skb_shinfo(skb)->tso_size;
+}
+static inline int skb_gso_ok(struct sk_buff *skb, int features)
+{
+        return (features & NETIF_F_TSO);
+}
+
+static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
+{
+        return skb_is_gso(skb) &&
+               (!skb_gso_ok(skb, dev->features) ||
+                unlikely(skb->ip_summed != CHECKSUM_HW));
+}
+#else
+#define netif_needs_gso(dev, skb)      0
+#define dev_disable_gso_features(dev)  ((void)0)
 #endif
 
 #define GRANT_INVALID_REF      0
@@ -115,7 +141,6 @@ struct netfront_info {
        spinlock_t   tx_lock;
        spinlock_t   rx_lock;
 
-       unsigned int handle;
        unsigned int evtchn, irq;
        unsigned int copying_receiver;
 
@@ -139,7 +164,7 @@ struct netfront_info {
        grant_ref_t gref_tx_head;
        grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1];
        grant_ref_t gref_rx_head;
-       grant_ref_t grant_rx_ref[NET_TX_RING_SIZE];
+       grant_ref_t grant_rx_ref[NET_RX_RING_SIZE];
 
        struct xenbus_device *xbdev;
        int tx_ring_ref;
@@ -204,9 +229,8 @@ static inline grant_ref_t xennet_get_rx_
 #define WPRINTK(fmt, args...)                          \
        printk(KERN_WARNING "netfront: " fmt, ##args)
 
-static int talk_to_backend(struct xenbus_device *, struct netfront_info *);
 static int setup_device(struct xenbus_device *, struct netfront_info *);
-static struct net_device *create_netdev(int, int, struct xenbus_device *);
+static struct net_device *create_netdev(struct xenbus_device *);
 
 static void netfront_closing(struct xenbus_device *);
 
@@ -216,7 +240,7 @@ static void close_netdev(struct netfront
 static void close_netdev(struct netfront_info *);
 static void netif_free(struct netfront_info *);
 
-static void network_connect(struct net_device *);
+static int network_connect(struct net_device *);
 static void network_tx_buf_gc(struct net_device *);
 static void network_alloc_rx_buffers(struct net_device *);
 static int send_fake_arp(struct net_device *);
@@ -239,8 +263,7 @@ static inline int xennet_can_sg(struct n
 /**
  * Entry point to this code when a new device is created.  Allocate the basic
  * structures and the ring buffers for communication with the backend, and
- * inform the backend of the appropriate details for those.  Switch to
- * Connected state.
+ * inform the backend of the appropriate details for those.
  */
 static int __devinit netfront_probe(struct xenbus_device *dev,
                                    const struct xenbus_device_id *id)
@@ -248,32 +271,8 @@ static int __devinit netfront_probe(stru
        int err;
        struct net_device *netdev;
        struct netfront_info *info;
-       unsigned int handle, feature_rx_copy, feature_rx_flip, use_copy;
-
-       err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%u", &handle);
-       if (err != 1) {
-               xenbus_dev_fatal(dev, err, "reading handle");
-               return err;
-       }
-
-       err = xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-copy", "%u",
-                          &feature_rx_copy);
-       if (err != 1)
-               feature_rx_copy = 0;
-       err = xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-flip", "%u",
-                          &feature_rx_flip);
-       if (err != 1)
-               feature_rx_flip = 1;
-
-       /*
-        * Copy packets on receive path if:
-        *  (a) This was requested by user, and the backend supports it; or
-        *  (b) Flipping was requested, but this is unsupported by the backend.
-        */
-       use_copy = (MODPARM_rx_copy && feature_rx_copy) ||
-               (MODPARM_rx_flip && !feature_rx_flip);
-
-       netdev = create_netdev(handle, use_copy, dev);
+
+       netdev = create_netdev(dev);
        if (IS_ERR(netdev)) {
                err = PTR_ERR(netdev);
                xenbus_dev_fatal(dev, err, "creating netdev");
@@ -283,23 +282,13 @@ static int __devinit netfront_probe(stru
        info = netdev_priv(netdev);
        dev->dev.driver_data = info;
 
-       err = talk_to_backend(dev, info);
-       if (err)
-               goto fail_backend;
-
        err = open_netdev(info);
        if (err)
-               goto fail_open;
-
-       IPRINTK("Created netdev %s with %sing receive path.\n",
-               netdev->name, info->copying_receiver ? "copy" : "flipp");
+               goto fail;
 
        return 0;
 
- fail_open:
-       xennet_sysfs_delif(info->netdev);
-       unregister_netdev(netdev);
- fail_backend:
+ fail:
        free_netdev(netdev);
        dev->dev.driver_data = NULL;
        return err;
@@ -319,7 +308,7 @@ static int netfront_resume(struct xenbus
        DPRINTK("%s\n", dev->nodename);
 
        netif_disconnect_backend(info);
-       return talk_to_backend(dev, info);
+       return 0;
 }
 
 static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
@@ -408,7 +397,7 @@ again:
                goto abort_transaction;
        }
 
-#ifdef HAVE_GSO
+#ifdef HAVE_TSO
        err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", 1);
        if (err) {
                message = "writing feature-gso-tcpv4";
@@ -430,7 +419,7 @@ again:
        xenbus_transaction_end(xbt, 1);
        xenbus_dev_fatal(dev, err, "%s", message);
  destroy_ring:
-       netif_free(info);
+       netif_disconnect_backend(info);
  out:
        return err;
 }
@@ -520,7 +509,10 @@ static void backend_changed(struct xenbu
                break;
 
        case XenbusStateInitWait:
-               network_connect(netdev);
+               if (network_connect(netdev) != 0) {
+                       netif_free(np);
+                       break;
+               }
                xenbus_switch_state(dev, XenbusStateConnected);
                (void)send_fake_arp(netdev);
                break;
@@ -940,7 +932,7 @@ static int network_start_xmit(struct sk_
                tx->flags |= NETTXF_data_validated;
 #endif
 
-#ifdef HAVE_GSO
+#ifdef HAVE_TSO
        if (skb_shinfo(skb)->gso_size) {
                struct netif_extra_info *gso = (struct netif_extra_info *)
                        RING_GET_REQUEST(&np->tx, ++i);
@@ -1094,6 +1086,7 @@ static int xennet_get_responses(struct n
                        if (net_ratelimit())
                                WPRINTK("rx->offset: %x, size: %u\n",
                                        rx->offset, rx->status);
+                       xennet_move_rx_slot(np, skb, ref);
                        err = -EINVAL;
                        goto next;
                }
@@ -1104,7 +1097,8 @@ static int xennet_get_responses(struct n
                 * situation to the system controller to reboot the backed.
                 */
                if (ref == GRANT_INVALID_REF) {
-                       WPRINTK("Bad rx response id %d.\n", rx->id);
+                       if (net_ratelimit())
+                               WPRINTK("Bad rx response id %d.\n", rx->id);
                        err = -EINVAL;
                        goto next;
                }
@@ -1176,6 +1170,9 @@ next:
                err = -E2BIG;
        }
 
+       if (unlikely(err))
+               np->rx.rsp_cons = cons + frags;
+
        *pages_flipped_p = pages_flipped;
 
        return err;
@@ -1228,12 +1225,14 @@ static int xennet_set_skb_gso(struct sk_
                return -EINVAL;
        }
 
+#ifdef HAVE_TSO
+       skb_shinfo(skb)->gso_size = gso->u.gso.size;
 #ifdef HAVE_GSO
-       skb_shinfo(skb)->gso_size = gso->u.gso.size;
        skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
 
        /* Header must be checked, and gso_segs computed. */
        skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+#endif
        skb_shinfo(skb)->gso_segs = 0;
 
        return 0;
@@ -1278,9 +1277,9 @@ static int netif_poll(struct net_device 
        rp = np->rx.sring->rsp_prod;
        rmb(); /* Ensure we see queued responses up to 'rp'. */
 
-       for (i = np->rx.rsp_cons, work_done = 0;
-            (i != rp) && (work_done < budget);
-            np->rx.rsp_cons = ++i, work_done++) {
+       i = np->rx.rsp_cons;
+       work_done = 0;
+       while ((i != rp) && (work_done < budget)) {
                memcpy(rx, RING_GET_RESPONSE(&np->rx, i), sizeof(*rx));
                memset(extras, 0, sizeof(extras));
 
@@ -1288,12 +1287,11 @@ static int netif_poll(struct net_device 
                                           &pages_flipped);
 
                if (unlikely(err)) {
-err:
-                       i = np->rx.rsp_cons + skb_queue_len(&tmpq) - 1;
-                       work_done--;
+err:   
                        while ((skb = __skb_dequeue(&tmpq)))
                                __skb_queue_tail(&errq, skb);
                        np->stats.rx_errors++;
+                       i = np->rx.rsp_cons;
                        continue;
                }
 
@@ -1305,6 +1303,7 @@ err:
 
                        if (unlikely(xennet_set_skb_gso(skb, gso))) {
                                __skb_queue_head(&tmpq, skb);
+                               np->rx.rsp_cons += skb_queue_len(&tmpq);
                                goto err;
                        }
                }
@@ -1368,6 +1367,9 @@ err:
                np->stats.rx_bytes += skb->len;
 
                __skb_queue_tail(&rxq, skb);
+
+               np->rx.rsp_cons = ++i;
+               work_done++;
        }
 
        if (pages_flipped) {
@@ -1584,7 +1586,7 @@ static int xennet_set_sg(struct net_devi
 
 static int xennet_set_tso(struct net_device *dev, u32 data)
 {
-#ifdef HAVE_GSO
+#ifdef HAVE_TSO
        if (data) {
                struct netfront_info *np = netdev_priv(dev);
                int val;
@@ -1615,15 +1617,40 @@ static void xennet_set_features(struct n
                xennet_set_tso(dev, 1);
 }
 
-static void network_connect(struct net_device *dev)
+static int network_connect(struct net_device *dev)
 {
        struct netfront_info *np = netdev_priv(dev);
-       int i, requeue_idx;
+       int i, requeue_idx, err;
        struct sk_buff *skb;
        grant_ref_t ref;
        netif_rx_request_t *req;
+       unsigned int feature_rx_copy, feature_rx_flip;
+
+       err = xenbus_scanf(XBT_NIL, np->xbdev->otherend,
+                          "feature-rx-copy", "%u", &feature_rx_copy);
+       if (err != 1)
+               feature_rx_copy = 0;
+       err = xenbus_scanf(XBT_NIL, np->xbdev->otherend,
+                          "feature-rx-flip", "%u", &feature_rx_flip);
+       if (err != 1)
+               feature_rx_flip = 1;
+
+       /*
+        * Copy packets on receive path if:
+        *  (a) This was requested by user, and the backend supports it; or
+        *  (b) Flipping was requested, but this is unsupported by the backend.
+        */
+       np->copying_receiver = ((MODPARM_rx_copy && feature_rx_copy) ||
+                               (MODPARM_rx_flip && !feature_rx_flip));
+
+       err = talk_to_backend(np->xbdev, np);
+       if (err)
+               return err;
 
        xennet_set_features(dev);
+
+       IPRINTK("device %s has %sing receive path.\n",
+               dev->name, np->copying_receiver ? "copy" : "flipp");
 
        spin_lock_irq(&np->tx_lock);
        spin_lock(&np->rx_lock);
@@ -1680,6 +1707,8 @@ static void network_connect(struct net_d
 
        spin_unlock(&np->rx_lock);
        spin_unlock_irq(&np->tx_lock);
+
+       return 0;
 }
 
 static void netif_uninit(struct net_device *dev)
@@ -1845,8 +1874,7 @@ static void network_set_multicast_list(s
 {
 }
 
-static struct net_device * __devinit
-create_netdev(int handle, int copying_receiver, struct xenbus_device *dev)
+static struct net_device * __devinit create_netdev(struct xenbus_device *dev)
 {
        int i, err = 0;
        struct net_device *netdev = NULL;
@@ -1860,9 +1888,7 @@ create_netdev(int handle, int copying_re
        }
 
        np                   = netdev_priv(netdev);
-       np->handle           = handle;
        np->xbdev            = dev;
-       np->copying_receiver = copying_receiver;
 
        netif_carrier_off(netdev);
 
@@ -1993,10 +2019,12 @@ static int open_netdev(struct netfront_i
 
        err = xennet_sysfs_addif(info->netdev);
        if (err) {
-               /* This can be non-fatal: it only means no tuning parameters */
+               unregister_netdev(info->netdev);
                printk(KERN_WARNING "%s: add sysfs failed err=%d\n",
                       __FUNCTION__, err);
-       }
+               return err;
+       }
+
        return 0;
 }
 
diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Sun Oct 08 
18:55:12 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Sat Oct 14 
13:28:45 2006 -0600
@@ -34,6 +34,10 @@
 
 static struct proc_dir_entry *privcmd_intf;
 static struct proc_dir_entry *capabilities_intf;
+
+#ifndef HAVE_ARCH_PRIVCMD_MMAP
+static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma);
+#endif
 
 static int privcmd_ioctl(struct inode *inode, struct file *file,
                         unsigned int cmd, unsigned long data)
@@ -89,10 +93,12 @@ static int privcmd_ioctl(struct inode *i
        break;
 
        case IOCTL_PRIVCMD_MMAP: {
-#define PRIVCMD_MMAP_SZ 32
                privcmd_mmap_t mmapcmd;
-               privcmd_mmap_entry_t msg[PRIVCMD_MMAP_SZ];
+               privcmd_mmap_entry_t msg;
                privcmd_mmap_entry_t __user *p;
+               struct mm_struct *mm = current->mm;
+               struct vm_area_struct *vma;
+               unsigned long va;
                int i, rc;
 
                if (!is_initial_xendomain())
@@ -102,47 +108,60 @@ static int privcmd_ioctl(struct inode *i
                        return -EFAULT;
 
                p = mmapcmd.entry;
-
-               for (i = 0; i < mmapcmd.num;
-                    i += PRIVCMD_MMAP_SZ, p += PRIVCMD_MMAP_SZ) {
-                       int j, n = ((mmapcmd.num-i)>PRIVCMD_MMAP_SZ)?
-                               PRIVCMD_MMAP_SZ:(mmapcmd.num-i);
-
-                       if (copy_from_user(&msg, p,
-                                          n*sizeof(privcmd_mmap_entry_t)))
-                               return -EFAULT;
-     
-                       for (j = 0; j < n; j++) {
-                               struct vm_area_struct *vma = 
-                                       find_vma( current->mm, msg[j].va );
-
-                               if (!vma)
-                                       return -EINVAL;
-
-                               if (msg[j].va > PAGE_OFFSET)
-                                       return -EINVAL;
-
-                               if ((msg[j].va + (msg[j].npages << PAGE_SHIFT))
-                                   > vma->vm_end )
-                                       return -EINVAL;
-
-                               if ((rc = direct_remap_pfn_range(
-                                       vma,
-                                       msg[j].va&PAGE_MASK, 
-                                       msg[j].mfn, 
-                                       msg[j].npages<<PAGE_SHIFT, 
-                                       vma->vm_page_prot,
-                                       mmapcmd.dom)) < 0)
-                                       return rc;
-                       }
-               }
-               ret = 0;
+               if (copy_from_user(&msg, p, sizeof(msg)))
+                       return -EFAULT;
+
+               down_read(&mm->mmap_sem);
+
+               vma = find_vma(mm, msg.va);
+               rc = -EINVAL;
+               if (!vma || (msg.va != vma->vm_start) ||
+                   !privcmd_enforce_singleshot_mapping(vma))
+                       goto mmap_out;
+
+               va = vma->vm_start;
+
+               for (i = 0; i < mmapcmd.num; i++) {
+                       rc = -EFAULT;
+                       if (copy_from_user(&msg, p, sizeof(msg)))
+                               goto mmap_out;
+
+                       /* Do not allow range to wrap the address space. */
+                       rc = -EINVAL;
+                       if ((msg.npages > (LONG_MAX >> PAGE_SHIFT)) ||
+                           ((unsigned long)(msg.npages << PAGE_SHIFT) >= -va))
+                               goto mmap_out;
+
+                       /* Range chunks must be contiguous in va space. */
+                       if ((msg.va != va) ||
+                           ((msg.va+(msg.npages<<PAGE_SHIFT)) > vma->vm_end))
+                               goto mmap_out;
+
+                       if ((rc = direct_remap_pfn_range(
+                               vma,
+                               msg.va & PAGE_MASK, 
+                               msg.mfn, 
+                               msg.npages << PAGE_SHIFT, 
+                               vma->vm_page_prot,
+                               mmapcmd.dom)) < 0)
+                               goto mmap_out;
+
+                       p++;
+                       va += msg.npages << PAGE_SHIFT;
+               }
+
+               rc = 0;
+
+       mmap_out:
+               up_read(&mm->mmap_sem);
+               ret = rc;
        }
        break;
 
        case IOCTL_PRIVCMD_MMAPBATCH: {
                privcmd_mmapbatch_t m;
-               struct vm_area_struct *vma = NULL;
+               struct mm_struct *mm = current->mm;
+               struct vm_area_struct *vma;
                xen_pfn_t __user *p;
                unsigned long addr, mfn;
                int i;
@@ -150,37 +169,31 @@ static int privcmd_ioctl(struct inode *i
                if (!is_initial_xendomain())
                        return -EPERM;
 
-               if (copy_from_user(&m, udata, sizeof(m))) {
-                       ret = -EFAULT;
-                       goto batch_err;
-               }
-
-               if (m.dom == DOMID_SELF) {
-                       ret = -EINVAL;
-                       goto batch_err;
-               }
-
-               vma = find_vma(current->mm, m.addr);
-               if (!vma) {
-                       ret = -EINVAL;
-                       goto batch_err;
-               }
-
-               if (m.addr > PAGE_OFFSET) {
-                       ret = -EFAULT;
-                       goto batch_err;
-               }
-
-               if ((m.addr + (m.num<<PAGE_SHIFT)) > vma->vm_end) {
-                       ret = -EFAULT;
-                       goto batch_err;
+               if (copy_from_user(&m, udata, sizeof(m)))
+                       return -EFAULT;
+
+               if ((m.num <= 0) || (m.num > (LONG_MAX >> PAGE_SHIFT)))
+                       return -EINVAL;
+
+               down_read(&mm->mmap_sem);
+
+               vma = find_vma(mm, m.addr);
+               if (!vma ||
+                   (m.addr != vma->vm_start) ||
+                   ((m.addr + ((unsigned long)m.num<<PAGE_SHIFT)) !=
+                    vma->vm_end) ||
+                   !privcmd_enforce_singleshot_mapping(vma)) {
+                       up_read(&mm->mmap_sem);
+                       return -EINVAL;
                }
 
                p = m.arr;
                addr = m.addr;
                for (i = 0; i < m.num; i++, addr += PAGE_SIZE, p++) {
-                       if (get_user(mfn, p))
+                       if (get_user(mfn, p)) {
+                               up_read(&mm->mmap_sem);
                                return -EFAULT;
+                       }
 
                        ret = direct_remap_pfn_range(vma, addr & PAGE_MASK,
                                                     mfn, PAGE_SIZE,
@@ -189,15 +202,8 @@ static int privcmd_ioctl(struct inode *i
                                put_user(0xF0000000 | mfn, p);
                }
 
+               up_read(&mm->mmap_sem);
                ret = 0;
-               break;
-
-       batch_err:
-               printk("batch_err ret=%d vma=%p addr=%lx "
-                      "num=%d arr=%p %lx-%lx\n", 
-                      ret, vma, (unsigned long)m.addr, m.num, m.arr,
-                      vma ? vma->vm_start : 0, vma ? vma->vm_end : 0);
-               break;
        }
        break;
 
@@ -210,12 +216,34 @@ static int privcmd_ioctl(struct inode *i
 }
 
 #ifndef HAVE_ARCH_PRIVCMD_MMAP
+static struct page *privcmd_nopage(struct vm_area_struct *vma,
+                                  unsigned long address,
+                                  int *type)
+{
+       return NOPAGE_SIGBUS;
+}
+
+static struct vm_operations_struct privcmd_vm_ops = {
+       .nopage = privcmd_nopage
+};
+
 static int privcmd_mmap(struct file * file, struct vm_area_struct * vma)
 {
+       /* Unsupported for auto-translate guests. */
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return -ENOSYS;
+
        /* DONTCOPY is essential for Xen as copy_page_range is broken. */
        vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
+       vma->vm_ops = &privcmd_vm_ops;
+       vma->vm_private_data = NULL;
 
        return 0;
+}
+
+static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma)
+{
+       return (xchg(&vma->vm_private_data, (void *)1) == NULL);
 }
 #endif
 
diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Sun Oct 08 18:55:12 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Sat Oct 14 13:28:45 
2006 -0600
@@ -46,11 +46,10 @@ typedef struct tpmif_st {
        atomic_t refcnt;
 
        struct backend_info *bi;
-       unsigned long mmap_vstart;
 
        grant_handle_t shmem_handle;
        grant_ref_t shmem_ref;
-       struct page *pagerange;
+       struct page **mmap_pages;
 
        char devname[20];
 } tpmif_t;
@@ -80,6 +79,9 @@ int vtpm_release_packets(tpmif_t * tpmif
 
 extern int num_frontends;
 
-#define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE))
+static inline unsigned long idx_to_kaddr(tpmif_t *t, unsigned int idx)
+{
+       return (unsigned long)pfn_to_kaddr(page_to_pfn(t->mmap_pages[idx]));
+}
 
 #endif /* __TPMIF__BACKEND__COMMON_H__ */
diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Sun Oct 08 
18:55:12 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Sat Oct 14 
13:28:45 2006 -0600
@@ -25,8 +25,8 @@ static tpmif_t *alloc_tpmif(domid_t domi
        tpmif_t *tpmif;
 
        tpmif = kmem_cache_alloc(tpmif_cachep, GFP_KERNEL);
-       if (!tpmif)
-               return ERR_PTR(-ENOMEM);
+       if (tpmif == NULL)
+               goto out_of_memory;
 
        memset(tpmif, 0, sizeof (*tpmif));
        tpmif->domid = domid;
@@ -35,22 +35,27 @@ static tpmif_t *alloc_tpmif(domid_t domi
        snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid);
        atomic_set(&tpmif->refcnt, 1);
 
-       tpmif->pagerange = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE);
-       BUG_ON(tpmif->pagerange == NULL);
-       tpmif->mmap_vstart = (unsigned long)pfn_to_kaddr(
-                                           page_to_pfn(tpmif->pagerange));
+       tpmif->mmap_pages = alloc_empty_pages_and_pagevec(TPMIF_TX_RING_SIZE);
+       if (tpmif->mmap_pages == NULL)
+               goto out_of_memory;
 
        list_add(&tpmif->tpmif_list, &tpmif_list);
        num_frontends++;
 
        return tpmif;
+
+ out_of_memory:
+       if (tpmif != NULL)
+               kmem_cache_free(tpmif_cachep, tpmif);
+       printk("%s: out of memory\n", __FUNCTION__);
+       return ERR_PTR(-ENOMEM);
 }
 
 static void free_tpmif(tpmif_t * tpmif)
 {
        num_frontends--;
        list_del(&tpmif->tpmif_list);
-       balloon_dealloc_empty_page_range(tpmif->pagerange, TPMIF_TX_RING_SIZE);
+       free_empty_pages_and_pagevec(tpmif->mmap_pages, TPMIF_TX_RING_SIZE);
        kmem_cache_free(tpmif_cachep, tpmif);
 }
 
diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Sun Oct 08 
18:55:12 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Sat Oct 14 
13:28:45 2006 -0600
@@ -253,7 +253,7 @@ int _packet_write(struct packet *pak,
                        return 0;
                }
 
-               gnttab_set_map_op(&map_op, MMAP_VADDR(tpmif, i),
+               gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i),
                                  GNTMAP_host_map, tx->ref, tpmif->domid);
 
                if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
@@ -270,7 +270,7 @@ int _packet_write(struct packet *pak,
 
                tocopy = min_t(size_t, size - offset, PAGE_SIZE);
 
-               if (copy_from_buffer((void *)(MMAP_VADDR(tpmif, i) |
+               if (copy_from_buffer((void *)(idx_to_kaddr(tpmif, i) |
                                              (tx->addr & ~PAGE_MASK)),
                                     &data[offset], tocopy, isuserbuffer)) {
                        tpmif_put(tpmif);
@@ -278,7 +278,7 @@ int _packet_write(struct packet *pak,
                }
                tx->size = tocopy;
 
-               gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i),
+               gnttab_set_unmap_op(&unmap_op, idx_to_kaddr(tpmif, i),
                                    GNTMAP_host_map, handle);
 
                if (unlikely
@@ -391,7 +391,7 @@ static int packet_read_shmem(struct pack
 
                tx = &tpmif->tx->ring[i].req;
 
-               gnttab_set_map_op(&map_op, MMAP_VADDR(tpmif, i),
+               gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i),
                                  GNTMAP_host_map, tx->ref, tpmif->domid);
 
                if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
@@ -414,10 +414,10 @@ static int packet_read_shmem(struct pack
                }
 
                DPRINTK("Copying from mapped memory at %08lx\n",
-                       (unsigned long)(MMAP_VADDR(tpmif, i) |
+                       (unsigned long)(idx_to_kaddr(tpmif, i) |
                                        (tx->addr & ~PAGE_MASK)));
 
-               src = (void *)(MMAP_VADDR(tpmif, i) |
+               src = (void *)(idx_to_kaddr(tpmif, i) |
                               ((tx->addr & ~PAGE_MASK) + pg_offset));
                if (copy_to_buffer(&buffer[offset],
                                   src, to_copy, isuserbuffer)) {
@@ -428,7 +428,7 @@ static int packet_read_shmem(struct pack
                        tpmif->domid, buffer[offset], buffer[offset + 1],
                        buffer[offset + 2], buffer[offset + 3]);
 
-               gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i),
+               gnttab_set_unmap_op(&unmap_op, idx_to_kaddr(tpmif, i),
                                    GNTMAP_host_map, handle);
 
                if (unlikely
diff -r 5176c3ea3293 -r b725c9e51a7c 
linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h        Sun Oct 08 
18:55:12 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h        Sat Oct 14 
13:28:45 2006 -0600
@@ -127,6 +127,7 @@ int direct_remap_pfn_range(struct vm_are
                           pgprot_t prot,
                           domid_t  domid);
 struct file;
+int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma);
 int privcmd_mmap(struct file * file, struct vm_area_struct * vma);
 #define HAVE_ARCH_PRIVCMD_MMAP
 
diff -r 5176c3ea3293 -r b725c9e51a7c linux-2.6-xen-sparse/include/xen/balloon.h
--- a/linux-2.6-xen-sparse/include/xen/balloon.h        Sun Oct 08 18:55:12 
2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/balloon.h        Sat Oct 14 13:28:45 
2006 -0600
@@ -38,23 +38,13 @@
  * Inform the balloon driver that it should allow some slop for device-driver
  * memory activities.
  */
-void
-balloon_update_driver_allowance(
-       long delta);
+void balloon_update_driver_allowance(long delta);
 
-/* Allocate an empty low-memory page range. */
-struct page *
-balloon_alloc_empty_page_range(
-       unsigned long nr_pages);
+/* Allocate/free a set of empty pages in low memory (i.e., no RAM mapped). */
+struct page **alloc_empty_pages_and_pagevec(int nr_pages);
+void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages);
 
-/* Deallocate an empty page range, adding to the balloon. */
-void
-balloon_dealloc_empty_page_range(
-       struct page *page, unsigned long nr_pages);
-
-void
-balloon_release_driver_page(
-       struct page *page);
+void balloon_release_driver_page(struct page *page);
 
 /*
  * Prevent the balloon driver from changing the memory reservation during
diff -r 5176c3ea3293 -r b725c9e51a7c linux-2.6-xen-sparse/mm/memory.c
--- a/linux-2.6-xen-sparse/mm/memory.c  Sun Oct 08 18:55:12 2006 -0600
+++ b/linux-2.6-xen-sparse/mm/memory.c  Sat Oct 14 13:28:45 2006 -0600
@@ -390,7 +390,7 @@ struct page *vm_normal_page(struct vm_ar
 
        if (vma->vm_flags & VM_PFNMAP) {
                unsigned long off = (addr - vma->vm_start) >> PAGE_SHIFT;
-               if ((pfn == vma->vm_pgoff + off) || !pfn_valid(pfn))
+               if (pfn == vma->vm_pgoff + off)
                        return NULL;
                if (!is_cow_mapping(vma->vm_flags))
                        return NULL;
@@ -405,7 +405,8 @@ struct page *vm_normal_page(struct vm_ar
         * Remove this test eventually!
         */
        if (unlikely(!pfn_valid(pfn))) {
-               print_bad_pte(vma, pte, addr);
+               if (!(vma->vm_flags & VM_RESERVED))
+                       print_bad_pte(vma, pte, addr);
                return NULL;
        }
 
diff -r 5176c3ea3293 -r b725c9e51a7c tools/blktap/drivers/Makefile
--- a/tools/blktap/drivers/Makefile     Sun Oct 08 18:55:12 2006 -0600
+++ b/tools/blktap/drivers/Makefile     Sat Oct 14 13:28:45 2006 -0600
@@ -10,11 +10,8 @@ INSTALL_DIR  = /usr/sbin
 INSTALL_DIR  = /usr/sbin
 LIBAIO_DIR   = ../../libaio/src
 
-CFLAGS   += -fPIC
-CFLAGS   += -Wall
 CFLAGS   += -Werror
 CFLAGS   += -Wno-unused
-CFLAGS   += -g3
 CFLAGS   += -fno-strict-aliasing
 CFLAGS   += -I $(XEN_LIBXC) -I $(LIBAIO_DIR)
 CFLAGS   += $(INCLUDES) -I. -I../../xenstore 
diff -r 5176c3ea3293 -r b725c9e51a7c tools/blktap/drivers/blktapctrl.c
--- a/tools/blktap/drivers/blktapctrl.c Sun Oct 08 18:55:12 2006 -0600
+++ b/tools/blktap/drivers/blktapctrl.c Sat Oct 14 13:28:45 2006 -0600
@@ -73,11 +73,6 @@ static int write_msg(int fd, int msgtype
 static int write_msg(int fd, int msgtype, void *ptr, void *ptr2);
 static int read_msg(int fd, int msgtype, void *ptr);
 static driver_list_entry_t *active_disks[MAX_DISK_TYPES];
-
-void sig_handler(int sig)
-{
-       run = 0;        
-}
 
 static void init_driver_list(void)
 {
@@ -669,6 +664,7 @@ int main(int argc, char *argv[])
                goto open_failed;
        }
 
+
  retry:
        /* Set up store connection and watch. */
        h = xs_daemon_open();
@@ -682,15 +678,11 @@ int main(int argc, char *argv[])
                 } else goto open_failed;
        }
        
-       ret = add_blockdevice_probe_watch(h, "Domain-0");
+       ret = setup_probe_watch(h);
        if (ret != 0) {
                DPRINTF("Failed adding device probewatch\n");
-                if (count < MAX_ATTEMPTS) {
-                        count++;
-                        sleep(2);
-                        xs_daemon_close(h);
-                        goto retry;
-                } else goto open_failed;
+               xs_daemon_close(h);
+               goto open_failed;
        }
 
        ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE );
diff -r 5176c3ea3293 -r b725c9e51a7c tools/blktap/lib/blktaplib.h
--- a/tools/blktap/lib/blktaplib.h      Sun Oct 08 18:55:12 2006 -0600
+++ b/tools/blktap/lib/blktaplib.h      Sat Oct 14 13:28:45 2006 -0600
@@ -193,8 +193,8 @@ typedef struct msg_pid {
 #define CTLMSG_PID_RSP     10
 
 /* xenstore/xenbus: */
-extern int add_blockdevice_probe_watch(struct xs_handle *h, 
-                                       const char *domname);
+#define DOMNAME "Domain-0"
+int setup_probe_watch(struct xs_handle *h);
 int xs_fire_next_watch(struct xs_handle *h);
 
 
diff -r 5176c3ea3293 -r b725c9e51a7c tools/blktap/lib/xenbus.c
--- a/tools/blktap/lib/xenbus.c Sun Oct 08 18:55:12 2006 -0600
+++ b/tools/blktap/lib/xenbus.c Sat Oct 14 13:28:45 2006 -0600
@@ -166,60 +166,58 @@ static void ueblktap_setup(struct xs_han
                goto fail;
        }
 
-        deverr = xs_gather(h, bepath, "physical-device", "%li", &pdev, NULL);
-        if (!deverr) {
-                DPRINTF("pdev set to %ld\n",pdev);
-                if (be->pdev && be->pdev != pdev) {
-                        DPRINTF("changing physical-device not supported");
-                        goto fail;
-                }
-                be->pdev = pdev;
-        }
-
-        /*Check to see if device is to be opened read-only*/
-        asprintf(&path, "%s/%s", bepath, "read-only");
-        if (xs_exists(h, path))
-                be->readonly = 1;
-
-        if (be->blkif == NULL) {
-
-                /* Front end dir is a number, which is used as the handle. */
-                p = strrchr(be->frontpath, '/') + 1;
-                handle = strtoul(p, NULL, 0);
-
-                be->blkif = alloc_blkif(be->frontend_id);
-       
-                if (be->blkif == NULL)
-                        goto fail;
+       deverr = xs_gather(h, bepath, "physical-device", "%li", &pdev, NULL);
+       if (!deverr) {
+               DPRINTF("pdev set to %ld\n",pdev);
+               if (be->pdev && be->pdev != pdev) {
+                       DPRINTF("changing physical-device not supported");
+                       goto fail;
+               }
+               be->pdev = pdev;
+       }
+
+       /* Check to see if device is to be opened read-only. */
+       asprintf(&path, "%s/%s", bepath, "read-only");
+       if (xs_exists(h, path))
+               be->readonly = 1;
+
+       if (be->blkif == NULL) {
+               /* Front end dir is a number, which is used as the handle. */
+               p = strrchr(be->frontpath, '/') + 1;
+               handle = strtoul(p, NULL, 0);
+
+               be->blkif = alloc_blkif(be->frontend_id);
+               if (be->blkif == NULL)
+                       goto fail;
 
                be->blkif->be_id = get_be_id(bepath);
                
-                /*Insert device specific info*/
-                blk = malloc(sizeof(blkif_info_t));
+               /* Insert device specific info, */
+               blk = malloc(sizeof(blkif_info_t));
                if (!blk) {
                        DPRINTF("Out of memory - blkif_info_t\n");
                        goto fail;
                }
-                er = xs_gather(h, bepath, "params", NULL, &blk->params, NULL);
-                if (er)
-                        goto fail;
-                be->blkif->info = blk;
+               er = xs_gather(h, bepath, "params", NULL, &blk->params, NULL);
+               if (er)
+                       goto fail;
+               be->blkif->info = blk;
                
-                if (deverr) {
-                        /*Dev number was not available, try to set manually*/
-                        pdev = convert_dev_name_to_num(blk->params);
-                        be->pdev = pdev;
-                }
-
-                er = blkif_init(be->blkif, handle, be->pdev, be->readonly);
-
-                if (er != 0) {
-                        DPRINTF("Unable to open device %s\n",blk->params);
-                       goto fail;
-               }
-
-                DPRINTF("[BECHG]: ADDED A NEW BLKIF (%s)\n", bepath);
-        }      
+               if (deverr) {
+                       /*Dev number was not available, try to set manually*/
+                       pdev = convert_dev_name_to_num(blk->params);
+                       be->pdev = pdev;
+               }
+
+               er = blkif_init(be->blkif, handle, be->pdev, be->readonly);
+               if (er != 0) {
+                       DPRINTF("Unable to open device %s\n",blk->params);
+                       goto fail;
+               }
+
+               DPRINTF("[BECHG]: ADDED A NEW BLKIF (%s)\n", bepath);
+       }
+
        /* Supply the information about the device to xenstore */
        er = xs_printf(h, be->backpath, "sectors", "%lu",
                        be->blkif->ops->get_size(be->blkif));
@@ -283,10 +281,10 @@ static void ueblktap_probe(struct xs_han
         *asserts that xenstore structure is always 7 levels deep
         *e.g. /local/domain/0/backend/vbd/1/2049
         */
-        len = strsep_len(bepath, '/', 7);
-        if (len < 0) 
-               goto free_be;     
-        bepath[len] = '\0';
+       len = strsep_len(bepath, '/', 7);
+       if (len < 0) 
+               goto free_be;
+       bepath[len] = '\0';
        
        be = malloc(sizeof(*be));
        if (!be) {
@@ -318,22 +316,21 @@ static void ueblktap_probe(struct xs_han
                if ( (be != NULL) && (be->blkif != NULL) ) 
                        backend_remove(h, be);
                else goto free_be;
-               if (bepath)
+               if (bepath)
                        free(bepath);
                return;
        }
        
-        /* Are we already tracking this device? */
-        if (be_exists_be(bepath)) {
+       /* Are we already tracking this device? */
+       if (be_exists_be(bepath))
                goto free_be;
-       }
        
        be->backpath = bepath;
-               be->frontpath = frontend;
-       
-        list_add(&be->list, &belist);
-       
-        DPRINTF("[PROBE]\tADDED NEW DEVICE (%s)\n", bepath);
+       be->frontpath = frontend;
+       
+       list_add(&be->list, &belist);
+       
+       DPRINTF("[PROBE]\tADDED NEW DEVICE (%s)\n", bepath);
        DPRINTF("\tFRONTEND (%s),(%ld)\n", frontend,be->frontend_id);
        
        ueblktap_setup(h, bepath);      
@@ -342,11 +339,10 @@ static void ueblktap_probe(struct xs_han
  free_be:
        if (frontend)
                free(frontend);
-        if (bepath)
+       if (bepath)
                free(bepath);
        if (be) 
                free(be);
-       return;
 }
 
 /**
@@ -356,16 +352,10 @@ static void ueblktap_probe(struct xs_han
  *are created, we initalise the state and attach a disk.
  */
 
-int add_blockdevice_probe_watch(struct xs_handle *h, const char *domname)
-{
-       char *domid, *path;
+int add_blockdevice_probe_watch(struct xs_handle *h, const char *domid)
+{
+       char *path;
        struct xenbus_watch *vbd_watch;
-       int er;
-       
-       domid = get_dom_domid(h, domname);
-
-       DPRINTF("%s: %s\n", 
-               domname, (domid != NULL) ? domid : "[ not found! ]");
        
        asprintf(&path, "/local/domain/%s/backend/tap", domid);
        if (path == NULL) 
@@ -378,10 +368,67 @@ int add_blockdevice_probe_watch(struct x
        }       
        vbd_watch->node     = path;
        vbd_watch->callback = ueblktap_probe;
-       er = register_xenbus_watch(h, vbd_watch);
-       if (er == 0) {
+       if (register_xenbus_watch(h, vbd_watch) != 0) {
                DPRINTF("ERROR: adding vbd probe watch %s\n", path);
                return -EINVAL;
        }
        return 0;
 }
+
+/* Asynch callback to check for /local/domain/<DOMID>/name */
+void check_dom(struct xs_handle *h, struct xenbus_watch *w, 
+              const char *bepath_im)
+{
+       char *domid;
+
+       domid = get_dom_domid(h);
+       if (domid == NULL)
+               return;
+
+       add_blockdevice_probe_watch(h, domid);
+       free(domid);
+       unregister_xenbus_watch(h, w);
+}
+
+/* We must wait for xend to register /local/domain/<DOMID> */
+int watch_for_domid(struct xs_handle *h)
+{
+       struct xenbus_watch *domid_watch;
+       char *path = NULL;
+
+       asprintf(&path, "/local/domain");
+       if (path == NULL) 
+               return -ENOMEM;
+
+       domid_watch = malloc(sizeof(struct xenbus_watch));
+       if (domid_watch == NULL) {
+               DPRINTF("ERROR: unable to malloc domid_watch [%s]\n", path);
+               return -EINVAL;
+       }       
+
+       domid_watch->node     = path;
+       domid_watch->callback = check_dom;
+
+       if (register_xenbus_watch(h, domid_watch) != 0) {
+               DPRINTF("ERROR: adding vbd probe watch %s\n", path);
+               return -EINVAL;
+       }
+
+       DPRINTF("Set async watch for /local/domain\n");
+
+       return 0;
+}
+
+int setup_probe_watch(struct xs_handle *h)
+{
+       char *domid;
+       int ret;
+       
+       domid = get_dom_domid(h);
+       if (domid == NULL)
+               return watch_for_domid(h);
+
+       ret = add_blockdevice_probe_watch(h, domid);
+       free(domid);
+       return ret;
+}
diff -r 5176c3ea3293 -r b725c9e51a7c tools/blktap/lib/xs_api.c
--- a/tools/blktap/lib/xs_api.c Sun Oct 08 18:55:12 2006 -0600
+++ b/tools/blktap/lib/xs_api.c Sat Oct 14 13:28:45 2006 -0600
@@ -106,7 +106,7 @@ again:
        if (!xs_transaction_end(xs, xth, ret)) {
                if (ret == 0 && errno == EAGAIN)
                        goto again;
-                else
+               else
                        ret = errno;
        }
 
@@ -118,25 +118,25 @@ int xs_printf(struct xs_handle *h, const
 int xs_printf(struct xs_handle *h, const char *dir, const char *node, 
              const char *fmt, ...)
 {
-        char *buf, *path;
-        va_list ap;
-        int ret;
-       
-        va_start(ap, fmt);
-        ret = vasprintf(&buf, fmt, ap);
-        va_end(ap);
-       
-        asprintf(&path, "%s/%s", dir, node);
-       
-        if ( (path == NULL) || (buf == NULL) )
+       char *buf, *path;
+       va_list ap;
+       int ret;
+       
+       va_start(ap, fmt);
+       ret = vasprintf(&buf, fmt, ap);
+       va_end(ap);
+       
+       asprintf(&path, "%s/%s", dir, node);
+       
+       if ((path == NULL) || (buf == NULL))
                return 0;
 
-        ret = xs_write(h, XBT_NULL, path, buf, strlen(buf)+1);
-       
-        free(buf);
-        free(path);
-       
-        return ret;
+       ret = xs_write(h, XBT_NULL, path, buf, strlen(buf)+1);
+       
+       free(buf);
+       free(path);
+       
+       return ret;
 }
 
 
@@ -165,7 +165,7 @@ int xs_exists(struct xs_handle *h, const
  * This assumes that the domain name we are looking for is unique. 
  * Name parameter Domain-0 
  */
-char *get_dom_domid(struct xs_handle *h, const char *name)
+char *get_dom_domid(struct xs_handle *h)
 {
        char **e, *val, *domid = NULL;
        unsigned int num, len;
@@ -179,7 +179,9 @@ char *get_dom_domid(struct xs_handle *h,
        }
        
        e = xs_directory(h, xth, "/local/domain", &num);
-       
+       if (e == NULL)
+               return NULL;
+
        for (i = 0; (i < num) && (domid == NULL); i++) {
                asprintf(&path, "/local/domain/%s/name", e[i]);
                val = xs_read(h, xth, path, &len);
@@ -187,7 +189,7 @@ char *get_dom_domid(struct xs_handle *h,
                if (val == NULL)
                        continue;
                
-               if (strcmp(val, name) == 0) {
+               if (strcmp(val, DOMNAME) == 0) {
                        /* match! */
                        asprintf(&path, "/local/domain/%s/domid", e[i]);
                        domid = xs_read(h, xth, path, &len);
@@ -249,12 +251,12 @@ int convert_dev_name_to_num(char *name) 
                ret = BASE_DEV_VAL;
        }
 
-        free(p_sd);
-        free(p_hd);
-        free(p_xvd);
-        free(p_plx);
-        free(alpha);
-        
+       free(p_sd);
+       free(p_hd);
+       free(p_xvd);
+       free(p_plx);
+       free(alpha);
+
        return ret;
 }
 
@@ -281,42 +283,39 @@ int register_xenbus_watch(struct xs_hand
 {
        /* Pointer in ascii is the token. */
        char token[sizeof(watch) * 2 + 1];
-       int er;
-       
+
        sprintf(token, "%lX", (long)watch);
-       if (find_watch(token)) 
-       {
+       if (find_watch(token)) {
                DPRINTF("watch collision!\n");
                return -EINVAL;
        }
        
-       er = xs_watch(h, watch->node, token);
-       if (er != 0) {
-               list_add(&watch->list, &watches);
-       } 
-        
-       return er;
+       if (!xs_watch(h, watch->node, token)) {
+               DPRINTF("unable to set watch!\n");
+               return -EINVAL;
+       }
+
+       list_add(&watch->list, &watches);
+
+       return 0;
 }
 
 int unregister_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch)
 {
        char token[sizeof(watch) * 2 + 1];
-       int er;
        
        sprintf(token, "%lX", (long)watch);
-       if (!find_watch(token))
-       {
+       if (!find_watch(token)) {
                DPRINTF("no such watch!\n");
                return -EINVAL;
        }
-       
-       
-       er = xs_unwatch(h, watch->node, token);
+
+       if (!xs_unwatch(h, watch->node, token))
+               DPRINTF("XENBUS Failed to release watch %s: %i\n",
+                       watch->node, er);
+
        list_del(&watch->list);
        
-       if (er == 0)
-               DPRINTF("XENBUS Failed to release watch %s: %i\n",
-                    watch->node, er);
        return 0;
 }
 
@@ -354,14 +353,10 @@ int xs_fire_next_watch(struct xs_handle 
        token = res[XS_WATCH_TOKEN];
        
        w = find_watch(token);
-       if (!w)
-       {
-               DPRINTF("unregistered watch fired\n");
-               goto done;
-       }
-       w->callback(h, w, node);
-       
- done:
+       if (w)
+               w->callback(h, w, node);
+
        free(res);
+
        return 1;
 }
diff -r 5176c3ea3293 -r b725c9e51a7c tools/blktap/lib/xs_api.h
--- a/tools/blktap/lib/xs_api.h Sun Oct 08 18:55:12 2006 -0600
+++ b/tools/blktap/lib/xs_api.h Sat Oct 14 13:28:45 2006 -0600
@@ -42,7 +42,7 @@ int xs_printf(struct xs_handle *h, const
 int xs_printf(struct xs_handle *h, const char *dir, const char *node, 
              const char *fmt, ...);
 int xs_exists(struct xs_handle *h, const char *path);
-char *get_dom_domid(struct xs_handle *h, const char *name);
+char *get_dom_domid(struct xs_handle *h);
 int convert_dev_name_to_num(char *name);
 int register_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch);
 int unregister_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch);
diff -r 5176c3ea3293 -r b725c9e51a7c tools/examples/block
--- a/tools/examples/block      Sun Oct 08 18:55:12 2006 -0600
+++ b/tools/examples/block      Sat Oct 14 13:28:45 2006 -0600
@@ -377,7 +377,6 @@ mount it read-write in a guest domain."
       "")
         claim_lock "block"
         success
-        echo happy gun \"$t\" >>/tmp/block.$$
         release_lock "block"
        ;;
     esac
diff -r 5176c3ea3293 -r b725c9e51a7c tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp    Sun Oct 08 18:55:12 2006 -0600
+++ b/tools/examples/xend-config.sxp    Sat Oct 14 13:28:45 2006 -0600
@@ -130,3 +130,8 @@
 
 # The tool used for initiating virtual TPM migration
 #(external-migration-tool '')
+
+# The interface for VNC servers to listen on. Defaults
+# to 127.0.0.1  To restore old 'listen everywhere' behaviour
+# set this to 0.0.0.0
+#(vnc-listen '127.0.0.1')
diff -r 5176c3ea3293 -r b725c9e51a7c tools/examples/xmexample.hvm
--- a/tools/examples/xmexample.hvm      Sun Oct 08 18:55:12 2006 -0600
+++ b/tools/examples/xmexample.hvm      Sat Oct 14 13:28:45 2006 -0600
@@ -132,6 +132,11 @@ vnc=1
 vnc=1
 
 #----------------------------------------------------------------------------
+# address that should be listened on for the VNC server if vnc is set.
+# default is to use 'vnc-listen' setting from /etc/xen/xend-config.sxp
+#vnclisten="127.0.0.1"
+
+#----------------------------------------------------------------------------
 # set VNC display number, default = domid
 #vncdisplay=1
 
diff -r 5176c3ea3293 -r b725c9e51a7c tools/firmware/acpi/acpi_dsdt.asl
--- a/tools/firmware/acpi/acpi_dsdt.asl Sun Oct 08 18:55:12 2006 -0600
+++ b/tools/firmware/acpi/acpi_dsdt.asl Sat Oct 14 13:28:45 2006 -0600
@@ -115,20 +115,15 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 
                         0x0000,
                         0xF300)
 
-                /* reserve what device model consumed for PCI VGA device       
 */
+                /* reserve memory for pci devices */
 
                     DWordMemory (ResourceConsumer, PosDecode, MinFixed, 
MaxFixed, Cacheable, ReadWrite,
                         0x00000000,
                         0xF0000000,
-                        0xF1FFFFFF,
+                        0xF4FFFFFF,
                         0x00000000,
-                        0x02000000)
-                    DWordMemory (ResourceConsumer, PosDecode, MinFixed, 
MaxFixed, Cacheable, ReadWrite,
-                        0x00000000,
-                        0xF2000000,
-                        0xF2000FFF,
-                        0x00000000,
-                        0x00001000)
+                        0x05000000)
+
                 })
                 Return (PRT0)
             }
@@ -299,38 +294,43 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 
                Return (PRTP)  
                } // end _PRT
 
-        Name(PRTP, Package(){
-                        Package(){0x0000ffff, 0, \_SB.PCI0.LNKA, 0}, // Slot 
1, INTA
-                        Package(){0x0000ffff, 1, \_SB.PCI0.LNKB, 0}, // Slot 
1, INTB
-                        Package(){0x0000ffff, 2, \_SB.PCI0.LNKC, 0}, // Slot 
1, INTC
-                        Package(){0x0000ffff, 3, \_SB.PCI0.LNKD, 0}, // Slot 
1, INTD
-
-                        Package(){0x0001ffff, 0, \_SB.PCI0.LNKB, 0}, // Slot 
2, INTB
-                        Package(){0x0001ffff, 1, \_SB.PCI0.LNKC, 0}, // Slot 
2, INTC
-                        Package(){0x0001ffff, 2, \_SB.PCI0.LNKD, 0}, // Slot 
2, INTD
-                        Package(){0x0001ffff, 3, \_SB.PCI0.LNKA, 0}, // Slot 
2, INTA
+        Name(PRTP, Package() {
+                        // Slot 1, INTA - INTD
+                        Package(){0x0000ffff, 0, \_SB.PCI0.LNKA, 0},
+                        Package(){0x0000ffff, 1, \_SB.PCI0.LNKB, 0},
+                        Package(){0x0000ffff, 2, \_SB.PCI0.LNKC, 0},
+                        Package(){0x0000ffff, 3, \_SB.PCI0.LNKD, 0},
+
+                        // Slot 2, INTA - INTD
+                        Package(){0x0001ffff, 0, \_SB.PCI0.LNKB, 0},
+                        Package(){0x0001ffff, 1, \_SB.PCI0.LNKC, 0},
+                        Package(){0x0001ffff, 2, \_SB.PCI0.LNKD, 0},
+                        Package(){0x0001ffff, 3, \_SB.PCI0.LNKA, 0},
                         
-                        Package(){0x0002ffff, 0, \_SB.PCI0.LNKC, 0}, // Slot 
3, INTC
-                        Package(){0x0002ffff, 1, \_SB.PCI0.LNKD, 0}, // Slot 
3, INTD
-                        Package(){0x0002ffff, 2, \_SB.PCI0.LNKA, 0}, // Slot 
3, INTA
-                        Package(){0x0002ffff, 3, \_SB.PCI0.LNKB, 0}, // Slot 
3, INTB
+                        // Slot 3, INTA - INTD
+                        Package(){0x0002ffff, 0, \_SB.PCI0.LNKC, 0},
+                        Package(){0x0002ffff, 1, \_SB.PCI0.LNKD, 0},
+                        Package(){0x0002ffff, 2, \_SB.PCI0.LNKA, 0},
+                        Package(){0x0002ffff, 3, \_SB.PCI0.LNKB, 0},
                         
-                        Package(){0x0003ffff, 0, \_SB.PCI0.LNKD, 0}, // Slot 
2, INTD
-                        Package(){0x0003ffff, 1, \_SB.PCI0.LNKA, 0}, // Slot 
2, INTA
-                        Package(){0x0003ffff, 2, \_SB.PCI0.LNKB, 0}, // Slot 
2, INTB
-                        Package(){0x0003ffff, 3, \_SB.PCI0.LNKC, 0}, // Slot 
2, INTC
+                        // Slot 4, INTA - INTD
+                        Package(){0x0003ffff, 0, \_SB.PCI0.LNKD, 0},
+                        Package(){0x0003ffff, 1, \_SB.PCI0.LNKA, 0},
+                        Package(){0x0003ffff, 2, \_SB.PCI0.LNKB, 0},
+                        Package(){0x0003ffff, 3, \_SB.PCI0.LNKC, 0},
                         
+                        // Slot 5, INTA - INTD
+                        Package(){0x0004ffff, 0, \_SB.PCI0.LNKA, 0},
+                        Package(){0x0004ffff, 1, \_SB.PCI0.LNKB, 0},
+                        Package(){0x0004ffff, 2, \_SB.PCI0.LNKC, 0},
+                        Package(){0x0004ffff, 3, \_SB.PCI0.LNKD, 0},
                         }
             )
         Name(PRTA, Package(){
-                        Package(){0x0001ffff, 0, 0, 5}, // Device 1, INTA
-
+                        Package(){0x0001ffff, 0, 0, 5},  // Device 1, INTA
                         Package(){0x0002ffff, 0, 0, 7},  // Device 2, INTA
-                       
                         Package(){0x0003ffff, 0, 0, 10}, // Device 3, INTA
-
-                        Package(){0x0004ffff, 0, 0, 11},  // Device 4, INTA    
                            
-                        
+                        Package(){0x0004ffff, 0, 0, 11}, // Device 4, INTA
                         }
             )
             
diff -r 5176c3ea3293 -r b725c9e51a7c tools/firmware/acpi/acpi_dsdt.c
--- a/tools/firmware/acpi/acpi_dsdt.c   Sun Oct 08 18:55:12 2006 -0600
+++ b/tools/firmware/acpi/acpi_dsdt.c   Sat Oct 14 13:28:45 2006 -0600
@@ -1,19 +1,19 @@
 /*
  * 
  * Intel ACPI Component Architecture
- * ASL Optimizing Compiler / AML Disassembler version 20050513 [Jun  8 2005]
+ * ASL Optimizing Compiler / AML Disassembler version 20050513 [Oct 12 2006]
  * Copyright (C) 2000 - 2005 Intel Corporation
  * Supports ACPI Specification Revision 3.0
  * 
- * Compilation of "acpi_dsdt.asl" - Mon Aug 14 18:15:09 2006
+ * Compilation of "acpi_dsdt.asl" - Thu Oct 12 14:08:49 2006
  * 
  * C source code output
  *
  */
 unsigned char AmlCode[] = 
 {
-    0x44,0x53,0x44,0x54,0xBA,0x08,0x00,0x00,  /* 00000000    "DSDT...." */
-    0x01,0x1D,0x49,0x4E,0x54,0x45,0x4C,0x00,  /* 00000008    "..INTEL." */
+    0x44,0x53,0x44,0x54,0xDA,0x08,0x00,0x00,  /* 00000000    "DSDT...." */
+    0x01,0x26,0x49,0x4E,0x54,0x45,0x4C,0x00,  /* 00000008    ".&INTEL." */
     0x69,0x6E,0x74,0x2D,0x78,0x65,0x6E,0x00,  /* 00000010    "int-xen." */
     0xD6,0x07,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
     0x13,0x05,0x05,0x20,0x08,0x50,0x4D,0x42,  /* 00000020    "... .PMB" */
@@ -34,7 +34,7 @@ unsigned char AmlCode[] =
     0x12,0x08,0x04,0x0A,0x07,0x0A,0x07,0x00,  /* 00000098    "........" */
     0x00,0x08,0x50,0x49,0x43,0x44,0x00,0x14,  /* 000000A0    "..PICD.." */
     0x0C,0x5F,0x50,0x49,0x43,0x01,0x70,0x68,  /* 000000A8    "._PIC.ph" */
-    0x50,0x49,0x43,0x44,0x10,0x45,0x80,0x5F,  /* 000000B0    "PICD.E._" */
+    0x50,0x49,0x43,0x44,0x10,0x45,0x82,0x5F,  /* 000000B0    "PICD.E._" */
     0x53,0x42,0x5F,0x5B,0x82,0x49,0x04,0x4D,  /* 000000B8    "SB_[.I.M" */
     0x45,0x4D,0x30,0x08,0x5F,0x48,0x49,0x44,  /* 000000C0    "EM0._HID" */
     0x0C,0x41,0xD0,0x0C,0x02,0x08,0x5F,0x43,  /* 000000C8    ".A...._C" */
@@ -45,7 +45,7 @@ unsigned char AmlCode[] =
     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000F0    "........" */
     0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,  /* 000000F8    "........" */
     0x00,0x00,0x00,0x00,0x79,0x00,0x5B,0x82,  /* 00000100    "....y.[." */
-    0x42,0x7B,0x50,0x43,0x49,0x30,0x08,0x5F,  /* 00000108    "B{PCI0._" */
+    0x42,0x7D,0x50,0x43,0x49,0x30,0x08,0x5F,  /* 00000108    "B}PCI0._" */
     0x48,0x49,0x44,0x0C,0x41,0xD0,0x0A,0x03,  /* 00000110    "HID.A..." */
     0x08,0x5F,0x55,0x49,0x44,0x00,0x08,0x5F,  /* 00000118    "._UID.._" */
     0x41,0x44,0x52,0x00,0x08,0x5F,0x42,0x42,  /* 00000120    "ADR.._BB" */
@@ -55,9 +55,9 @@ unsigned char AmlCode[] =
     0x33,0x03,0x49,0x52,0x51,0x35,0x05,0x49,  /* 00000140    "3.IRQ5.I" */
     0x52,0x51,0x37,0x07,0x49,0x52,0x51,0x39,  /* 00000148    "RQ7.IRQ9" */
     0x09,0x49,0x52,0x51,0x41,0x0A,0x49,0x52,  /* 00000150    ".IRQA.IR" */
-    0x51,0x42,0x0B,0x14,0x44,0x08,0x5F,0x43,  /* 00000158    "QB..D._C" */
+    0x51,0x42,0x0B,0x14,0x4A,0x06,0x5F,0x43,  /* 00000158    "QB..J._C" */
     0x52,0x53,0x00,0x08,0x50,0x52,0x54,0x30,  /* 00000160    "RS..PRT0" */
-    0x11,0x42,0x07,0x0A,0x6E,0x88,0x0D,0x00,  /* 00000168    ".B..n..." */
+    0x11,0x48,0x05,0x0A,0x54,0x88,0x0D,0x00,  /* 00000168    ".H..T..." */
     0x02,0x0F,0x00,0x00,0x00,0x00,0x00,0xFF,  /* 00000170    "........" */
     0x00,0x00,0x00,0x00,0x01,0x47,0x01,0xF8,  /* 00000178    ".....G.." */
     0x0C,0xF8,0x0C,0x01,0x08,0x88,0x0D,0x00,  /* 00000180    "........" */
@@ -66,231 +66,235 @@ unsigned char AmlCode[] =
     0x01,0x0C,0x03,0x00,0x00,0x00,0x0D,0xFF,  /* 00000198    "........" */
     0xFF,0x00,0x00,0x00,0xF3,0x87,0x17,0x00,  /* 000001A0    "........" */
     0x00,0x0D,0x03,0x00,0x00,0x00,0x00,0x00,  /* 000001A8    "........" */
-    0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xF1,0x00,  /* 000001B0    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x87,  /* 000001B8    "........" */
-    0x17,0x00,0x00,0x0D,0x03,0x00,0x00,0x00,  /* 000001C0    "........" */
-    0x00,0x00,0x00,0x00,0xF2,0xFF,0x0F,0x00,  /* 000001C8    "........" */
-    0xF2,0x00,0x00,0x00,0x00,0x00,0x10,0x00,  /* 000001D0    "........" */
-    0x00,0x79,0x00,0xA4,0x50,0x52,0x54,0x30,  /* 000001D8    ".y..PRT0" */
-    0x08,0x42,0x55,0x46,0x41,0x11,0x09,0x0A,  /* 000001E0    ".BUFA..." */
-    0x06,0x23,0xF8,0xDC,0x18,0x79,0x00,0x08,  /* 000001E8    ".#...y.." */
-    0x42,0x55,0x46,0x42,0x11,0x09,0x0A,0x06,  /* 000001F0    "BUFB...." */
-    0x23,0x00,0x00,0x18,0x79,0x00,0x8B,0x42,  /* 000001F8    "#...y..B" */
-    0x55,0x46,0x42,0x01,0x49,0x52,0x51,0x56,  /* 00000200    "UFB.IRQV" */
-    0x08,0x42,0x55,0x46,0x43,0x11,0x07,0x0A,  /* 00000208    ".BUFC..." */
-    0x04,0x05,0x07,0x0A,0x0B,0x8C,0x42,0x55,  /* 00000210    "......BU" */
-    0x46,0x43,0x01,0x50,0x49,0x51,0x41,0x8C,  /* 00000218    "FC.PIQA." */
-    0x42,0x55,0x46,0x43,0x01,0x50,0x49,0x51,  /* 00000220    "BUFC.PIQ" */
-    0x42,0x8C,0x42,0x55,0x46,0x43,0x01,0x50,  /* 00000228    "B.BUFC.P" */
-    0x49,0x51,0x43,0x8C,0x42,0x55,0x46,0x43,  /* 00000230    "IQC.BUFC" */
-    0x01,0x50,0x49,0x51,0x44,0x5B,0x82,0x48,  /* 00000238    ".PIQD[.H" */
-    0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F,0x48,  /* 00000240    ".LNKA._H" */
-    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,  /* 00000248    "ID.A...." */
-    0x5F,0x55,0x49,0x44,0x01,0x14,0x1C,0x5F,  /* 00000250    "_UID..._" */
-    0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52,  /* 00000258    "STA.{PIR" */
-    0x41,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,  /* 00000260    "A..`...`" */
-    0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,  /* 00000268    "........" */
-    0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,  /* 00000270    "...._PRS" */
-    0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11,  /* 00000278    "..BUFA.." */
-    0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49,  /* 00000280    "_DIS.}PI" */
-    0x52,0x41,0x0A,0x80,0x50,0x49,0x52,0x41,  /* 00000288    "RA..PIRA" */
-    0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,  /* 00000290    ".._CRS.{" */
-    0x50,0x49,0x52,0x42,0x0A,0x0F,0x60,0x79,  /* 00000298    "PIRB..`y" */
-    0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42,  /* 000002A0    ".`IRQV.B" */
-    0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,  /* 000002A8    "UFB.._SR" */
-    0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51,  /* 000002B0    "S..h.IRQ" */
-    0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76,  /* 000002B8    "1.IRQ1`v" */
-    0x60,0x70,0x60,0x50,0x49,0x52,0x41,0x5B,  /* 000002C0    "`p`PIRA[" */
-    0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42,0x08,  /* 000002C8    ".I.LNKB." */
-    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 000002D0    "_HID.A.." */
-    0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,  /* 000002D8    ".._UID.." */
-    0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,  /* 000002E0    ".._STA.{" */
-    0x50,0x49,0x52,0x42,0x0A,0x80,0x60,0xA0,  /* 000002E8    "PIRB..`." */
-    0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,  /* 000002F0    "..`....." */
-    0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,  /* 000002F8    "......._" */
-    0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46,  /* 00000300    "PRS..BUF" */
-    0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00,  /* 00000308    "A.._DIS." */
-    0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,0x50,  /* 00000310    "}PIRB..P" */
-    0x49,0x52,0x42,0x14,0x1A,0x5F,0x43,0x52,  /* 00000318    "IRB.._CR" */
-    0x53,0x00,0x7B,0x50,0x49,0x52,0x42,0x0A,  /* 00000320    "S.{PIRB." */
-    0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51,  /* 00000328    ".`y.`IRQ" */
-    0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,  /* 00000330    "V.BUFB.." */
-    0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01,  /* 00000338    "_SRS..h." */
-    0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51,  /* 00000340    "IRQ1.IRQ" */
-    0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49,  /* 00000348    "1`v`p`PI" */
-    0x52,0x42,0x5B,0x82,0x49,0x08,0x4C,0x4E,  /* 00000350    "RB[.I.LN" */
-    0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000358    "KC._HID." */
-    0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49,  /* 00000360    "A...._UI" */
-    0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53,0x54,  /* 00000368    "D...._ST" */
-    0x41,0x00,0x7B,0x50,0x49,0x52,0x43,0x0A,  /* 00000370    "A.{PIRC." */
-    0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80,  /* 00000378    ".`...`.." */
-    0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B,  /* 00000380    "........" */
-    0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4,  /* 00000388    ".._PRS.." */
-    0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44,  /* 00000390    "BUFA.._D" */
-    0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x43,  /* 00000398    "IS.}PIRC" */
-    0x0A,0x80,0x50,0x49,0x52,0x43,0x14,0x1A,  /* 000003A0    "..PIRC.." */
-    0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49,  /* 000003A8    "_CRS.{PI" */
-    0x52,0x43,0x0A,0x0F,0x60,0x79,0x01,0x60,  /* 000003B0    "RC..`y.`" */
-    0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46,  /* 000003B8    "IRQV.BUF" */
-    0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,  /* 000003C0    "B.._SRS." */
-    0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82,  /* 000003C8    ".h.IRQ1." */
-    0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70,  /* 000003D0    "IRQ1`v`p" */
-    0x60,0x50,0x49,0x52,0x43,0x5B,0x82,0x49,  /* 000003D8    "`PIRC[.I" */
-    0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48,  /* 000003E0    ".LNKD._H" */
-    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,  /* 000003E8    "ID.A...." */
-    0x5F,0x55,0x49,0x44,0x0A,0x04,0x14,0x1C,  /* 000003F0    "_UID...." */
-    0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49,  /* 000003F8    "_STA.{PI" */
-    0x52,0x44,0x0A,0x80,0x60,0xA0,0x08,0x93,  /* 00000400    "RD..`..." */
-    0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,  /* 00000408    "`......." */
-    0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,  /* 00000410    "....._PR" */
-    0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14,  /* 00000418    "S..BUFA." */
-    0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,  /* 00000420    "._DIS.}P" */
-    0x49,0x52,0x44,0x0A,0x80,0x50,0x49,0x52,  /* 00000428    "IRD..PIR" */
-    0x44,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,  /* 00000430    "D.._CRS." */
-    0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F,0x60,  /* 00000438    "{PIRD..`" */
-    0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4,  /* 00000440    "y.`IRQV." */
-    0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,  /* 00000448    "BUFB.._S" */
-    0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52,  /* 00000450    "RS..h.IR" */
-    0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60,  /* 00000458    "Q1.IRQ1`" */
-    0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x44,  /* 00000460    "v`p`PIRD" */
-    0x14,0x16,0x5F,0x50,0x52,0x54,0x00,0xA0,  /* 00000468    ".._PRT.." */
-    0x0A,0x50,0x49,0x43,0x44,0xA4,0x50,0x52,  /* 00000470    ".PICD.PR" */
-    0x54,0x41,0xA4,0x50,0x52,0x54,0x50,0x08,  /* 00000478    "TA.PRTP." */
-    0x50,0x52,0x54,0x50,0x12,0x43,0x0E,0x10,  /* 00000480    "PRTP.C.." */
-    0x12,0x0B,0x04,0x0B,0xFF,0xFF,0x00,0x4C,  /* 00000488    ".......L" */
-    0x4E,0x4B,0x41,0x00,0x12,0x0B,0x04,0x0B,  /* 00000490    "NKA....." */
-    0xFF,0xFF,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000498    "...LNKB." */
-    0x12,0x0C,0x04,0x0B,0xFF,0xFF,0x0A,0x02,  /* 000004A0    "........" */
-    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0C,0x04,  /* 000004A8    "LNKC...." */
-    0x0B,0xFF,0xFF,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000004B0    ".....LNK" */
-    0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000004B8    "D......." */
-    0x01,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00,  /* 000004C0    "...LNKB." */
-    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00,  /* 000004C8    "........" */
-    0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,  /* 000004D0    ".LNKC..." */
-    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02,  /* 000004D8    "........" */
-    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 000004E0    "LNKD...." */
-    0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x03,0x4C,  /* 000004E8    ".......L" */
-    0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,  /* 000004F0    "NKA....." */
-    0xFF,0xFF,0x02,0x00,0x00,0x4C,0x4E,0x4B,  /* 000004F8    ".....LNK" */
-    0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000500    "C......." */
-    0x02,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00,  /* 00000508    "...LNKD." */
-    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00,  /* 00000510    "........" */
-    0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12,  /* 00000518    "..LNKA.." */
-    0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A,  /* 00000520    "........" */
-    0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,  /* 00000528    ".LNKB..." */
-    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x00,0x4C,  /* 00000530    ".......L" */
-    0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,  /* 00000538    "NKD....." */
-    0xFF,0xFF,0x03,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000540    ".....LNK" */
-    0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000548    "A......." */
-    0x03,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42,  /* 00000550    "....LNKB" */
-    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03,  /* 00000558    "........" */
-    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000560    "...LNKC." */
-    0x08,0x50,0x52,0x54,0x41,0x12,0x32,0x04,  /* 00000568    ".PRTA.2." */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x01,0x00,  /* 00000570    "........" */
-    0x00,0x00,0x0A,0x05,0x12,0x0B,0x04,0x0C,  /* 00000578    "........" */
-    0xFF,0xFF,0x02,0x00,0x00,0x00,0x0A,0x07,  /* 00000580    "........&