[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Merge.



# HG changeset patch
# User adsharma@xxxxxxxxxxxxxxxxxxxx
# Node ID 112d44270733c583e9c2506732299baceff7753a
# Parent  e2025593f702880de0cd6cb1958a72b5b6250d31
# Parent  b4b3f6be5226adfb127bc32fd5cca27f2ed473f7
Merge.

diff -r e2025593f702 -r 112d44270733 extras/mini-os/include/hypervisor.h
--- a/extras/mini-os/include/hypervisor.h       Wed Aug 24 23:16:52 2005
+++ b/extras/mini-os/include/hypervisor.h       Thu Aug 25 18:18:47 2005
@@ -80,16 +80,42 @@
 
 static __inline__ int HYPERVISOR_mmu_update(mmu_update_t *req, 
                                             int count, 
-                                            int *success_count)
-{
-    int ret;
-    __asm__ __volatile__ (
-        TRAP_INSTR
-        : "=a" (ret) : "0" (__HYPERVISOR_mmu_update), 
-        _a1 (req), _a2 (count), _a3 (success_count)  : "memory" );
-
-    return ret;
-}
+                                            int *success_count, 
+                                            domid_t domid)
+{
+    int ret;
+    unsigned long ign1, ign2, ign3, ign4;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
+        : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
+          "3" (success_count), "4" (domid)
+        : "memory" );
+
+    return ret;
+}
+
+
+static __inline__ int HYPERVISOR_mmuext_op(struct mmuext_op *op, 
+                                           int count, 
+                                           int *success_count, 
+                                           domid_t domid)
+{
+    int ret;
+    unsigned long ign1, ign2, ign3, ign4;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
+        : "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count),
+          "3" (success_count), "4" (domid)
+        : "memory" );
+
+    return ret;
+}
+
+
 
 static __inline__ int HYPERVISOR_set_gdt(unsigned long *frame_list, int 
entries)
 {
diff -r e2025593f702 -r 112d44270733 extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h       Wed Aug 24 23:16:52 2005
+++ b/extras/mini-os/include/mm.h       Thu Aug 25 18:18:47 2005
@@ -43,13 +43,27 @@
 #define PADDR_MASK              ((1UL << PADDR_BITS)-1)
 #define VADDR_MASK              ((1UL << VADDR_BITS)-1)
 
-#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> PAGE_SHIFT)
+#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> 
L1_PAGETABLE_SHIFT)
+
+#endif
+
+
+
+#ifdef __i386__
+
+#define L1_PAGETABLE_SHIFT      12
+#define L2_PAGETABLE_SHIFT      22
+
+#define L1_PAGETABLE_ENTRIES    1024
+#define L2_PAGETABLE_ENTRIES    1024
+#endif
 
 /* Given a virtual address, get an entry offset into a page table. */
 #define l1_table_offset(_a) \
   (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
 #define l2_table_offset(_a) \
   (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
+#ifdef __x86_64__
 #define l3_table_offset(_a) \
   (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
 #define l4_table_offset(_a) \
@@ -67,13 +81,16 @@
 #define _PAGE_PSE      0x080UL
 #define _PAGE_GLOBAL   0x100UL
 
-#define PAGE_SHIFT      12
-#define PAGE_SIZE       (1UL << PAGE_SHIFT)
+#define L1_PROT (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
+#define L2_PROT (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | 
_PAGE_USER)
+
+#define PAGE_SIZE       (1UL << L1_PAGETABLE_SHIFT)
+#define PAGE_SHIFT      L1_PAGETABLE_SHIFT
 #define PAGE_MASK       (~(PAGE_SIZE-1))
 
-#define PFN_UP(x)      (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)    ((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)    ((x) << PAGE_SHIFT)
+#define PFN_UP(x)      (((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
+#define PFN_DOWN(x)    ((x) >> L1_PAGETABLE_SHIFT)
+#define PFN_PHYS(x)    ((x) << L1_PAGETABLE_SHIFT)
 
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)        (((addr)+PAGE_SIZE-1)&PAGE_MASK)
@@ -83,14 +100,14 @@
 #define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
 static __inline__ unsigned long phys_to_machine(unsigned long phys)
 {
-    unsigned long machine = pfn_to_mfn(phys >> PAGE_SHIFT);
-    machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
+    unsigned long machine = pfn_to_mfn(phys >> L1_PAGETABLE_SHIFT);
+    machine = (machine << L1_PAGETABLE_SHIFT) | (phys & ~PAGE_MASK);
     return machine;
 }
 static __inline__ unsigned long machine_to_phys(unsigned long machine)
 {
-    unsigned long phys = mfn_to_pfn(machine >> PAGE_SHIFT);
-    phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
+    unsigned long phys = mfn_to_pfn(machine >> L1_PAGETABLE_SHIFT);
+    phys = (phys << L1_PAGETABLE_SHIFT) | (machine & ~PAGE_MASK);
     return phys;
 }
 
@@ -105,7 +122,10 @@
 #define __va to_virt
 #define __pa to_phys
 
+#define virt_to_pfn(_virt)         (PFN_DOWN(to_phys(_virt)))
+
 void init_mm(void);
 unsigned long alloc_pages(int order);
+int is_mfn_mapped(unsigned long mfn);
 
 #endif /* _MM_H_ */
diff -r e2025593f702 -r 112d44270733 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c   Wed Aug 24 23:16:52 2005
+++ b/extras/mini-os/kernel.c   Thu Aug 25 18:18:47 2005
@@ -133,7 +133,7 @@
     for ( ; ; ) 
     {      
 //        HYPERVISOR_yield();
-        block(1);
+        block(100);
         i++;
     }
 }
diff -r e2025593f702 -r 112d44270733 extras/mini-os/mm.c
--- a/extras/mini-os/mm.c       Wed Aug 24 23:16:52 2005
+++ b/extras/mini-os/mm.c       Thu Aug 25 18:18:47 2005
@@ -5,9 +5,9 @@
  *
  *        File: mm.c
  *      Author: Rolf Neugebauer (neugebar@xxxxxxxxxxxxx)
- *     Changes: 
+ *     Changes: Grzegorz Milos
  *              
- *        Date: Aug 2003
+ *        Date: Aug 2003, chages Aug 2005
  * 
  * Environment: Xen Minimal OS
  * Description: memory management related functions
@@ -41,86 +41,18 @@
 #include <types.h>
 #include <lib.h>
 
+
+#ifdef MM_DEBUG
+#define DEBUG(_f, _a...) \
+    printk("MINI_OS(file=mm.c, line=%d) " _f "\n", __LINE__, ## _a)
+#else
+#define DEBUG(_f, _a...)    ((void)0)
+#endif
+
 unsigned long *phys_to_machine_mapping;
 extern char *stack;
 extern char _text, _etext, _edata, _end;
 
-static void init_page_allocator(unsigned long min, unsigned long max);
-
-void init_mm(void)
-{
-
-    unsigned long start_pfn, max_pfn, max_free_pfn;
-
-    unsigned long *pgd = (unsigned long *)start_info.pt_base;
-
-    printk("MM: Init\n");
-
-    printk("  _text:        %p\n", &_text);
-    printk("  _etext:       %p\n", &_etext);
-    printk("  _edata:       %p\n", &_edata);
-    printk("  stack start:  %p\n", &stack);
-    printk("  _end:         %p\n", &_end);
-
-    /* set up minimal memory infos */
-    start_pfn = PFN_UP(to_phys(&_end));
-    max_pfn = start_info.nr_pages;
-
-    printk("  start_pfn:    %lx\n", start_pfn);
-    printk("  max_pfn:      %lx\n", max_pfn);
-
-    /*
-     * we know where free tables start (start_pfn) and how many we 
-     * have (max_pfn). 
-     * 
-     * Currently the hypervisor stores page tables it providesin the
-     * high region of the this memory range.
-     * 
-     * next we work out how far down this goes (max_free_pfn)
-     * 
-     * XXX this assumes the hypervisor provided page tables to be in
-     * the upper region of our initial memory. I don't know if this 
-     * is always true.
-     */
-
-    max_free_pfn = PFN_DOWN(to_phys(pgd));
-#ifdef __i386__
-    {
-        unsigned long *pgd = (unsigned long *)start_info.pt_base;
-        unsigned long  pte;
-        int i;
-        printk("  pgd(pa(pgd)): %lx(%lx)", (u_long)pgd, to_phys(pgd));
-
-        for ( i = 0; i < (HYPERVISOR_VIRT_START>>22); i++ )
-        {
-            unsigned long pgde = *pgd++;
-            if ( !(pgde & 1) ) continue;
-            pte = machine_to_phys(pgde & PAGE_MASK);
-            printk("  PT(%x): %lx(%lx)", i, (u_long)to_virt(pte), pte);
-            if (PFN_DOWN(pte) <= max_free_pfn) 
-                max_free_pfn = PFN_DOWN(pte);
-        }
-    }
-    max_free_pfn--;
-    printk("  max_free_pfn: %lx\n", max_free_pfn);
-
-    /*
-     * now we can initialise the page allocator
-     */
-    printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n",
-           (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), 
-           (u_long)to_virt(PFN_PHYS(max_free_pfn)), PFN_PHYS(max_free_pfn));
-    init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_free_pfn));   
-#endif
-
-
-    /* Now initialise the physical->machine mapping table. */
-
-
-    printk("MM: done\n");
-
-    
-}
 
 /*********************
  * ALLOCATION BITMAP
@@ -213,6 +145,59 @@
 
 #define round_pgdown(_p)  ((_p)&PAGE_MASK)
 #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
+
+#ifdef MM_DEBUG
+/*
+ * Prints allocation[0/1] for @nr_pages, starting at @start
+ * address (virtual).
+ */
+static void print_allocation(void *start, int nr_pages)
+{
+    unsigned long pfn_start = virt_to_pfn(start);
+    int count;
+    for(count = 0; count < nr_pages; count++)
+        if(allocated_in_map(pfn_start + count)) printk("1");
+        else printk("0");
+        
+    printk("\n");        
+}
+
+/*
+ * Prints chunks (making them with letters) for @nr_pages starting
+ * at @start (virtual).
+ */
+static void print_chunks(void *start, int nr_pages)
+{
+    char chunks[1001], current='A';
+    int order, count;
+    chunk_head_t *head;
+    unsigned long pfn_start = virt_to_pfn(start);
+   
+    memset(chunks, (int)'_', 1000);
+    if(nr_pages > 1000) 
+    {
+        DEBUG("Can only pring 1000 pages. Increase buffer size.");
+    }
+    
+    for(order=0; order < FREELIST_SIZE; order++)
+    {
+        head = free_head[order];
+        while(!FREELIST_EMPTY(head))
+        {
+            for(count = 0; count < 1<< head->level; count++)
+            {
+                if(count + virt_to_pfn(head) - pfn_start < 1000)
+                    chunks[count + virt_to_pfn(head) - pfn_start] = current;
+            }
+            head = head->next;
+            current++;
+        }
+    }
+    chunks[nr_pages] = '\0';
+    printk("%s\n", chunks);
+}
+#endif
+
 
 
 /*
@@ -328,3 +313,198 @@
     return 0;
 }
 
+void free_pages(void *pointer, int order)
+{
+    chunk_head_t *freed_ch, *to_merge_ch;
+    chunk_tail_t *freed_ct;
+    unsigned long mask;
+    
+    /* First free the chunk */
+    map_free(virt_to_pfn(pointer), 1 << order);
+    
+    /* Create free chunk */
+    freed_ch = (chunk_head_t *)pointer;
+    freed_ct = (chunk_tail_t *)((char *)pointer + (1<<(order + PAGE_SHIFT)))-1;
+    
+    /* Now, possibly we can conseal chunks together */
+    while(order < FREELIST_SIZE)
+    {
+        mask = 1 << (order + PAGE_SHIFT);
+        if((unsigned long)freed_ch & mask) 
+        {
+            to_merge_ch = (chunk_head_t *)((char *)freed_ch - mask);
+            if(allocated_in_map(virt_to_pfn(to_merge_ch)) ||
+                    to_merge_ch->level != order)
+                break;
+            
+            /* Merge with predecessor */
+            freed_ch = to_merge_ch;   
+        }
+        else 
+        {
+            to_merge_ch = (chunk_head_t *)((char *)freed_ch + mask);
+            if(allocated_in_map(virt_to_pfn(to_merge_ch)) ||
+                    to_merge_ch->level != order)
+                break;
+            
+            /* Merge with successor */
+            freed_ct = (chunk_tail_t *)((char *)to_merge_ch + mask);
+        }
+        
+        /* We are commited to merging, unlink the chunk */
+        *(to_merge_ch->pprev) = to_merge_ch->next;
+        to_merge_ch->next->pprev = to_merge_ch->pprev;
+        
+        order++;
+    }
+
+    /* Link the new chunk */
+    freed_ch->level = order;
+    freed_ch->next  = free_head[order];
+    freed_ch->pprev = &free_head[order];
+    freed_ct->level = order;
+    
+    freed_ch->next->pprev = &freed_ch->next;
+    free_head[order] = freed_ch;   
+   
+}
+void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
+{
+    unsigned long pfn_to_map, pt_frame;
+    unsigned long mach_ptd, max_mach_ptd;
+    int count;
+    unsigned long mach_pte, virt_pte;
+    unsigned long *ptd = (unsigned long *)start_info.pt_base;
+    mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
+    struct mmuext_op pin_request;
+    
+    /* Firstly work out what is the first pfn that is not yet in page tables
+       NB. Assuming that builder fills whole pt_frames (which it does at the
+       moment)
+     */  
+    pfn_to_map = (start_info.nr_pt_frames - 1) * L1_PAGETABLE_ENTRIES;
+    DEBUG("start_pfn=%ld, first pfn_to_map %ld, max_pfn=%ld", 
+            *start_pfn, pfn_to_map, *max_pfn);
+
+    /* Machine address of page table directory */
+    mach_ptd = phys_to_machine(to_phys(start_info.pt_base));
+    mach_ptd += sizeof(void *) * 
+        l2_table_offset((unsigned long)to_virt(PFN_PHYS(pfn_to_map)));
+  
+    max_mach_ptd = sizeof(void *) * 
+        l2_table_offset((unsigned long)to_virt(PFN_PHYS(*max_pfn)));
+    
+    /* Check that we are not trying to access Xen region */
+    if(max_mach_ptd > sizeof(void *) * l2_table_offset(HYPERVISOR_VIRT_START))
+    {
+        printk("WARNING: mini-os will not use all the memory supplied\n");
+        max_mach_ptd = sizeof(void *) * l2_table_offset(HYPERVISOR_VIRT_START);
+        *max_pfn = virt_to_pfn(HYPERVISOR_VIRT_START - PAGE_SIZE);
+    }
+    max_mach_ptd += phys_to_machine(to_phys(start_info.pt_base));
+    DEBUG("Max_mach_ptd 0x%lx", max_mach_ptd); 
+   
+    pt_frame = *start_pfn;
+    /* Should not happen - no empty, mapped pages */
+    if(pt_frame >= pfn_to_map)
+    {
+        printk("ERROR: Not even a single empty, mapped page\n");
+        *(int*)0=0;
+    }
+    
+    while(mach_ptd < max_mach_ptd)
+    {
+        /* Correct protection needs to be set for the new page table frame */
+        virt_pte = (unsigned long)to_virt(PFN_PHYS(pt_frame));
+        mach_pte = ptd[l2_table_offset(virt_pte)] & ~(PAGE_SIZE-1);
+        mach_pte += sizeof(void *) * l1_table_offset(virt_pte);
+        DEBUG("New page table page: pfn=0x%lx, mfn=0x%lx, virt_pte=0x%lx, "
+                "mach_pte=0x%lx", pt_frame, pfn_to_mfn(pt_frame), 
+                virt_pte, mach_pte);
+        
+        /* Update the entry */
+        mmu_updates[0].ptr = mach_pte;
+        mmu_updates[0].val = pfn_to_mfn(pt_frame) << PAGE_SHIFT | 
+                                                    (L1_PROT & ~_PAGE_RW);
+        if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
+        {
+            printk("PTE for new page table page could not be updated\n");
+            *(int*)0=0;
+        }
+        
+        /* Pin the page to provide correct protection */
+        pin_request.cmd = MMUEXT_PIN_L1_TABLE;
+        pin_request.mfn = pfn_to_mfn(pt_frame);
+        if(HYPERVISOR_mmuext_op(&pin_request, 1, NULL, DOMID_SELF) < 0)
+        {
+            printk("ERROR: pinning failed\n");
+            *(int*)0=0;
+        }
+        
+        /* Now fill the new page table page with entries.
+           Update the page directory as well. */
+        count = 0;
+        mmu_updates[count].ptr = mach_ptd;
+        mmu_updates[count].val = pfn_to_mfn(pt_frame) << PAGE_SHIFT |
+                                                         L2_PROT;
+        count++;
+        mach_ptd += sizeof(void *);
+        mach_pte = phys_to_machine(PFN_PHYS(pt_frame++));
+        
+        for(;count <= L1_PAGETABLE_ENTRIES && pfn_to_map <= *max_pfn; count++)
+        {
+            mmu_updates[count].ptr = mach_pte;
+            mmu_updates[count].val = 
+                pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
+            if(count == 1) DEBUG("mach_pte 0x%lx", mach_pte);
+            mach_pte += sizeof(void *);
+        }
+        if(HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF) < 0) 
+        {            
+            printk("ERROR: mmu_update failed\n");
+            *(int*)0=0;
+        }
+        (*start_pfn)++;
+    }
+
+    *start_pfn = pt_frame;
+}
+
+void init_mm(void)
+{
+
+    unsigned long start_pfn, max_pfn;
+
+    printk("MM: Init\n");
+
+    printk("  _text:        %p\n", &_text);
+    printk("  _etext:       %p\n", &_etext);
+    printk("  _edata:       %p\n", &_edata);
+    printk("  stack start:  %p\n", &stack);
+    printk("  _end:         %p\n", &_end);
+
+    /* set up minimal memory infos */
+    phys_to_machine_mapping = (unsigned long *)start_info.mfn_list;
+   
+    /* First page follows page table pages and 3 more pages (store page etc) */
+    start_pfn = PFN_UP(__pa(start_info.pt_base)) + start_info.nr_pt_frames + 3;
+    max_pfn = start_info.nr_pages;
+
+    printk("  start_pfn:    %lx\n", start_pfn);
+    printk("  max_pfn:      %lx\n", max_pfn);
+
+
+    build_pagetable(&start_pfn, &max_pfn);
+    
+#ifdef __i386__
+    /*
+     * now we can initialise the page allocator
+     */
+    printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n",
+           (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), 
+           (u_long)to_virt(PFN_PHYS(max_pfn)), PFN_PHYS(max_pfn));
+    init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));   
+#endif
+
+    printk("MM: done\n");
+}
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c    Wed Aug 24 
23:16:52 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c    Thu Aug 25 
18:18:47 2005
@@ -19,11 +19,13 @@
 
 #include "cpu.h"
 
+#ifndef CONFIG_XEN
 DEFINE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
 EXPORT_PER_CPU_SYMBOL(cpu_gdt_table);
 
 DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
 EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
+#endif
 
 static int cachesize_override __initdata = -1;
 static int disable_x86_fxsr __initdata = 0;
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Wed Aug 24 
23:16:52 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Thu Aug 25 
18:18:47 2005
@@ -131,15 +131,7 @@
  */
 void __init smp_alloc_memory(void)
 {
-#if 1
-       int cpu;
-
-       for (cpu = 1; cpu < NR_CPUS; cpu++) {
-               cpu_gdt_descr[cpu].address = (unsigned long)
-                       alloc_bootmem_low_pages(PAGE_SIZE);
-               /* XXX free unused pages later */
-       }
-#else
+#if 0
        trampoline_base = (void *) alloc_bootmem_low_pages(PAGE_SIZE);
        /*
         * Has to be in very low memory so we can execute
@@ -861,8 +853,8 @@
        atomic_set(&init_deasserted, 0);
 
 #if 1
-       if (cpu_gdt_descr[0].size > PAGE_SIZE)
-               BUG();
+       cpu_gdt_descr[cpu].address = __get_free_page(GFP_KERNEL);
+       BUG_ON(cpu_gdt_descr[0].size > PAGE_SIZE);
        cpu_gdt_descr[cpu].size = cpu_gdt_descr[0].size;
        printk("GDT: copying %d bytes from %lx to %lx\n",
                cpu_gdt_descr[0].size, cpu_gdt_descr[0].address,
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Wed Aug 24 23:16:52 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Thu Aug 25 18:18:47 2005
@@ -871,6 +871,7 @@
        }
 }
 
+#ifndef CONFIG_XEN
 fastcall void setup_x86_bogus_stack(unsigned char * stk)
 {
        unsigned long *switch16_ptr, *switch32_ptr;
@@ -915,6 +916,7 @@
        memcpy(stack32, stack16, len);
        return stack32;
 }
+#endif
 
 /*
  *  'math_state_restore()' saves the current math information in the
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c     Wed Aug 24 23:16:52 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c     Thu Aug 25 18:18:47 2005
@@ -34,9 +34,11 @@
 
 
 EXPORT_SYMBOL(gnttab_grant_foreign_access);
+EXPORT_SYMBOL(gnttab_end_foreign_access_ref);
 EXPORT_SYMBOL(gnttab_end_foreign_access);
 EXPORT_SYMBOL(gnttab_query_foreign_access);
 EXPORT_SYMBOL(gnttab_grant_foreign_transfer);
+EXPORT_SYMBOL(gnttab_end_foreign_transfer_ref);
 EXPORT_SYMBOL(gnttab_end_foreign_transfer);
 EXPORT_SYMBOL(gnttab_alloc_grant_references);
 EXPORT_SYMBOL(gnttab_free_grant_references);
@@ -160,7 +162,7 @@
 }
 
 void
-gnttab_end_foreign_access(grant_ref_t ref, int readonly)
+gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
 {
     u16 flags, nflags;
 
@@ -170,7 +172,12 @@
             printk(KERN_ALERT "WARNING: g.e. still in use!\n");
     }
     while ( (nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) != flags );
-
+}
+
+void
+gnttab_end_foreign_access(grant_ref_t ref, int readonly)
+{
+    gnttab_end_foreign_access_ref(ref, readonly);
     put_free_entry(ref);
 }
 
@@ -201,20 +208,13 @@
 }
 
 unsigned long
-gnttab_end_foreign_transfer(grant_ref_t ref)
+gnttab_end_foreign_transfer_ref(grant_ref_t ref)
 {
     unsigned long frame = 0;
     u16           flags;
 
     flags = shared[ref].flags;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
-    /*
-     * But can't flags == (GTF_accept_transfer | GTF_transfer_completed)
-     * if gnttab_donate executes without interruption???
-     */
-#else
-    ASSERT(flags == (GTF_accept_transfer | GTF_transfer_committed));
-#endif
+
     /*
      * If a transfer is committed then wait for the frame address to appear.
      * Otherwise invalidate the grant entry against future use.
@@ -224,8 +224,14 @@
         while ( unlikely((frame = shared[ref].frame) == 0) )
             cpu_relax();
 
+    return frame;
+}
+
+unsigned long
+gnttab_end_foreign_transfer(grant_ref_t ref)
+{
+    unsigned long frame = gnttab_end_foreign_transfer_ref(ref);
     put_free_entry(ref);
-
     return frame;
 }
 
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Wed Aug 24 23:16:52 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Thu Aug 25 18:18:47 2005
@@ -128,14 +128,6 @@
 
     /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
        /* XXX SMH: yes it would :-( */ 
-
-#ifdef CONFIG_XEN_NETDEV_FRONTEND
-    extern void netif_suspend(void);
-    extern void netif_resume(void);  
-#else
-#define netif_suspend() do{}while(0)
-#define netif_resume()  do{}while(0)
-#endif
 
 #ifdef CONFIG_XEN_USB_FRONTEND
     extern void usbif_resume();
@@ -218,8 +210,6 @@
     kmem_cache_shrink(pgd_cache);
 #endif
 
-    netif_suspend();
-
     time_suspend();
 
 #ifdef CONFIG_SMP
@@ -276,8 +266,6 @@
 #endif
 
     time_resume();
-
-    netif_resume();
 
     usbif_resume();
 
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/early_printk.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/early_printk.c        Wed Aug 
24 23:16:52 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/early_printk.c        Thu Aug 
25 18:18:47 2005
@@ -5,6 +5,8 @@
 #include <linux/string.h>
 #include <asm/io.h>
 #include <asm/processor.h>
+
+#ifndef CONFIG_XEN
 
 /* Simple VGA output */
 
@@ -59,7 +61,6 @@
        .index =        -1,
 };
 
-#ifndef CONFIG_XEN
 /* Serial functions loosely based on a similar package from Klaus P. Gerlicher 
*/ 
 
 static int early_serial_base = 0x3f8;  /* ttyS0 */
@@ -148,7 +149,8 @@
        outb((divisor >> 8) & 0xff, early_serial_base + DLH); 
        outb(c & ~DLAB, early_serial_base + LCR);
 }
-#else
+
+#else /* CONFIG_XEN */
 
 static void
 early_serial_write(struct console *con, const char *s, unsigned count)
@@ -167,6 +169,13 @@
 static __init void early_serial_init(char *s)
 {
 }
+
+/*
+ * No early VGA console on Xen, as we do not have convenient ISA-space
+ * mappings. Someone should fix this for domain 0. For now, use fake serial.
+ */
+#define early_vga_console early_serial_console
+
 #endif
 
 static struct console early_serial_console = {
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S        Wed Aug 24 
23:16:52 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S        Thu Aug 25 
18:18:47 2005
@@ -206,11 +206,13 @@
        .quad   0,0,0                   /* three TLS descriptors */ 
        .quad   0                       /* unused now?   __KERNEL16_CS - 16bit 
PM for S3 wakeup. */
 
-gdt_end:       
+gdt_end:
+#if 0
        /* asm/segment.h:GDT_ENTRIES must match this */ 
        /* This should be a multiple of the cache line size */
        /* GDTs of other CPUs: */       
        .fill (GDT_SIZE * NR_CPUS) - (gdt_end - cpu_gdt_table)
+#endif
 
 .org 0x8000
 ENTRY(empty_zero_page)
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c       Wed Aug 24 
23:16:52 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c       Thu Aug 25 
18:18:47 2005
@@ -536,48 +536,7 @@
 }
 #endif
 
-#ifdef CONFIG_XEN
-#define reserve_ebda_region() void(0)
-
-static void __init print_memory_map(char *who)
-{
-        int i;
-
-        for (i = 0; i < e820.nr_map; i++) {
-                early_printk(" %s: %016Lx - %016Lx ", who,
-                        e820.map[i].addr,
-                        e820.map[i].addr + e820.map[i].size);
-                switch (e820.map[i].type) {
-                case E820_RAM:  early_printk("(usable)\n");
-                                break;
-                case E820_RESERVED:
-                                early_printk("(reserved)\n");
-                                break;
-                case E820_ACPI:
-                                early_printk("(ACPI data)\n");
-                                break;
-                case E820_NVS:
-                                early_printk("(ACPI NVS)\n");
-                                break;
-                default:        early_printk("type %u\n", e820.map[i].type);
-                                break;
-                }
-        }
-}
-
-void __init smp_alloc_memory(void)
-{
-       int cpu;
-
-       for (cpu = 1; cpu < NR_CPUS; cpu++) {
-               cpu_gdt_descr[cpu].address = (unsigned long)
-                       alloc_bootmem_low_pages(PAGE_SIZE);
-               /* XXX free unused pages later */
-       }
-}
-
-
-#else
+#ifndef CONFIG_XEN
 #define EBDA_ADDR_POINTER 0x40E
 static void __init reserve_ebda_region(void)
 {
@@ -628,7 +587,6 @@
                             VMASST_TYPE_writable_pagetables);
 
         ARCH_SETUP
-        print_memory_map(machine_specific_memory_setup());
 #else
        ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
        drive_info = DRIVE_INFO;
@@ -743,9 +701,6 @@
                        initrd_start = 0;
                }
        }
-#endif
-#ifdef CONFIG_SMP
-       smp_alloc_memory();
 #endif
 #else  /* CONFIG_XEN */
 #ifdef CONFIG_BLK_DEV_INITRD
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c     Wed Aug 24 
23:16:52 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c     Thu Aug 25 
18:18:47 2005
@@ -286,10 +286,10 @@
 
        memcpy(me->thread.tls_array, cpu_gdt_table[cpu], GDT_ENTRY_TLS_ENTRIES 
* 8);
 #else
-       memcpy(me->thread.tls_array, &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN],
+       memcpy(me->thread.tls_array, &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN],
            GDT_ENTRY_TLS_ENTRIES * 8);
 
-    cpu_gdt_init(&cpu_gdt_descr[cpu]);
+       cpu_gdt_init(&cpu_gdt_descr[cpu]);
 #endif
        
        /*
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c     Wed Aug 24 
23:16:52 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c     Thu Aug 25 
18:18:47 2005
@@ -739,8 +739,8 @@
        atomic_set(&init_deasserted, 0);
 
 #ifdef CONFIG_XEN
-       if (cpu_gdt_descr[0].size > PAGE_SIZE)
-               BUG();
+       cpu_gdt_descr[cpu].address = __get_free_page(GFP_KERNEL);
+       BUG_ON(cpu_gdt_descr[0].size > PAGE_SIZE);
        cpu_gdt_descr[cpu].size = cpu_gdt_descr[0].size;
        memcpy((void *)cpu_gdt_descr[cpu].address,
                (void *)cpu_gdt_descr[0].address, cpu_gdt_descr[0].size);
@@ -798,6 +798,8 @@
        ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT;
 
        boot_error = HYPERVISOR_boot_vcpu(cpu, &ctxt);
+       if (boot_error)
+               printk("boot error: %ld\n", boot_error);
 
        if (!boot_error) {
                /*
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c    Wed Aug 24 23:16:52 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c    Thu Aug 25 18:18:47 2005
@@ -536,70 +536,38 @@
                          round_up(ptes * 8, PAGE_SIZE); 
 }
 
-static void xen_copy_pt(void)
-{
-       unsigned long va = __START_KERNEL_map;
-       unsigned long addr, *pte_page;
+void __init xen_init_pt(void)
+{
+       unsigned long addr, *page;
        int i;
-       pud_t *pud; pmd_t *pmd; pte_t *pte;
-       unsigned long *page = (unsigned long *) init_level4_pgt;
-
-       addr = (unsigned long) page[pgd_index(va)];
+
+       for (i = 0; i < NR_CPUS; i++)
+               per_cpu(cur_pgd, i) = init_mm.pgd;
+
+       memset((void *)init_level4_pgt,   0, PAGE_SIZE);
+       memset((void *)level3_kernel_pgt, 0, PAGE_SIZE);
+       memset((void *)level2_kernel_pgt, 0, PAGE_SIZE);
+
+       /* Find the initial pte page that was built for us. */
+       page = (unsigned long *)xen_start_info.pt_base;
+       addr = page[pgd_index(__START_KERNEL_map)];
        addr_to_page(addr, page);
-
-       pud = (pud_t *) &page[pud_index(va)];
-       addr = page[pud_index(va)];
+       addr = page[pud_index(__START_KERNEL_map)];
        addr_to_page(addr, page);
 
-       level3_kernel_pgt[pud_index(va)] = 
-               __pud(__pa_symbol(level2_kernel_pgt) | _KERNPG_TABLE | 
_PAGE_USER);
-
-       for (;;) {
-               pmd = (pmd_t *) &page[pmd_index(va)];
-               if (pmd_present(*pmd)) {
-                       level2_kernel_pgt[pmd_index(va)] = *pmd;
-                       /*
-                        * if pmd is valid, check pte.
-                        */
-                       addr = page[pmd_index(va)];
-                       addr_to_page(addr, pte_page);
-                       
-                       for (i = 0; i < PTRS_PER_PTE; i++) {
-                               pte = (pte_t *) &pte_page[pte_index(va)];
-                               if (pte_present(*pte))
-                                       va += PAGE_SIZE;
-                               else
-                                   break;
-                       }
-
-               } else
-                   break;
-       }
-
+       /* Construct mapping of initial pte page in our own directories. */
        init_level4_pgt[pgd_index(__START_KERNEL_map)] = 
                mk_kernel_pgd(__pa_symbol(level3_kernel_pgt));
-}
-
-void __init xen_init_pt(void)
-{
-       int i;
-
-       for (i = 0; i < NR_CPUS; i++)
-               per_cpu(cur_pgd, i) = init_mm.pgd;
-
-       memcpy((void *)init_level4_pgt, 
-              (void *)xen_start_info.pt_base, PAGE_SIZE);
-
-       memset((void *)level3_kernel_pgt, 0, PAGE_SIZE);
-       memset((void *)level2_kernel_pgt, 0, PAGE_SIZE);
-
-       xen_copy_pt();
+       level3_kernel_pgt[pud_index(__START_KERNEL_map)] = 
+               __pud(__pa_symbol(level2_kernel_pgt) |
+                     _KERNPG_TABLE | _PAGE_USER);
+        memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE);
 
        make_page_readonly(init_level4_pgt);
+       make_page_readonly(init_level4_user_pgt);
        make_page_readonly(level3_kernel_pgt);
+       make_page_readonly(level3_user_pgt);
        make_page_readonly(level2_kernel_pgt);
-       make_page_readonly(init_level4_user_pgt);
-       make_page_readonly(level3_user_pgt); /* for vsyscall stuff */
 
        xen_pgd_pin(__pa_symbol(init_level4_pgt));
        xen_pgd_pin(__pa_symbol(init_level4_user_pgt));
@@ -609,7 +577,6 @@
 
        set_pgd((pgd_t *)(init_level4_user_pgt + 511), 
                mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
-
 }
 
 /*
@@ -617,69 +584,58 @@
  * mapping done by Xen is minimal (e.g. 8MB) and we need to extend the
  * mapping for early initialization.
  */
-
-#define MIN_INIT_SIZE  0x800000
 static unsigned long current_size, extended_size;
 
 void __init extend_init_mapping(void) 
 {
        unsigned long va = __START_KERNEL_map;
-       unsigned long addr, *pte_page;
-
-       unsigned long phys;
+       unsigned long phys, addr, *pte_page;
         pmd_t *pmd;
        pte_t *pte, new_pte;
        unsigned long *page = (unsigned long *) init_level4_pgt;
        int i;
 
-       addr = (unsigned long) page[pgd_index(va)];
+       addr = page[pgd_index(va)];
        addr_to_page(addr, page);
-
        addr = page[pud_index(va)];
        addr_to_page(addr, page);
 
        for (;;) {
+               pmd = (pmd_t *)&page[pmd_index(va)];
+               if (!pmd_present(*pmd))
+                       break;
+               addr = page[pmd_index(va)];
+               addr_to_page(addr, pte_page);
+               for (i = 0; i < PTRS_PER_PTE; i++) {
+                       pte = (pte_t *) &pte_page[pte_index(va)];
+                       if (!pte_present(*pte))
+                               break;
+                       va += PAGE_SIZE;
+                       current_size += PAGE_SIZE;
+               }
+       }
+
+       while (va < __START_KERNEL_map + current_size + tables_space) {
                pmd = (pmd_t *) &page[pmd_index(va)];
-               if (pmd_present(*pmd)) {
-                       /*
-                        * if pmd is valid, check pte.
-                        */
-                       addr = page[pmd_index(va)];
-                       addr_to_page(addr, pte_page);
-                       
-                       for (i = 0; i < PTRS_PER_PTE; i++) {
-                               pte = (pte_t *) &pte_page[pte_index(va)];
-                               
-                               if (pte_present(*pte)) {
-                                       va += PAGE_SIZE;
-                                       current_size += PAGE_SIZE;
-                               } else
-                                   break;
-                       }
-
-               } else
-                   break;
-       }
-
-       for (; va < __START_KERNEL_map + current_size + tables_space; ) {
-               pmd = (pmd_t *) &page[pmd_index(va)];
-
-               if (pmd_none(*pmd)) {
-                       pte_page = (unsigned long *) alloc_static_page(&phys);
-                       make_page_readonly(pte_page);
-                       xen_pte_pin(phys);
-                       set_pmd(pmd, __pmd(phys | _KERNPG_TABLE | _PAGE_USER));
-
-                       for (i = 0; i < PTRS_PER_PTE; i++, va += PAGE_SIZE) {
-                               new_pte = pfn_pte((va -  __START_KERNEL_map) >> 
PAGE_SHIFT, 
-                                                 __pgprot(_KERNPG_TABLE | 
_PAGE_USER));
-
-                               pte = (pte_t *) &pte_page[pte_index(va)];
-                               xen_l1_entry_update(pte, new_pte);
-                               extended_size += PAGE_SIZE;
-                       }
-               } 
-       }
+               if (!pmd_none(*pmd))
+                       continue;
+               pte_page = (unsigned long *) alloc_static_page(&phys);
+               make_page_readonly(pte_page);
+               xen_pte_pin(phys);
+               set_pmd(pmd, __pmd(phys | _KERNPG_TABLE | _PAGE_USER));
+               for (i = 0; i < PTRS_PER_PTE; i++, va += PAGE_SIZE) {
+                       new_pte = pfn_pte(
+                               (va - __START_KERNEL_map) >> PAGE_SHIFT, 
+                               __pgprot(_KERNPG_TABLE | _PAGE_USER));
+                       pte = (pte_t *)&pte_page[pte_index(va)];
+                       xen_l1_entry_update(pte, new_pte);
+                       extended_size += PAGE_SIZE;
+               }
+       }
+
+       /* Kill mapping of low 1MB. */
+       for (va = __START_KERNEL_map; va < (unsigned long)&_text; va += 
PAGE_SIZE)
+               HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0);
 }
 
 
@@ -719,10 +675,6 @@
               table_end<<PAGE_SHIFT);
 
         start_pfn = ((current_size + extended_size) >> PAGE_SHIFT);
-
-        /*
-         * TBD: Need to calculate at runtime
-         */
 
        __flush_tlb_all();
         init_mapping_done = 1;
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Wed Aug 24 23:16:52 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Aug 25 18:18:47 2005
@@ -57,26 +57,26 @@
 /* Front end tells us frame. */
 static void frontend_changed(struct xenbus_watch *watch, const char *node)
 {
-       unsigned long sharedmfn;
+       unsigned long ring_ref;
        unsigned int evtchn;
        int err;
        struct backend_info *be
                = container_of(watch, struct backend_info, watch);
 
        /* If other end is gone, delete ourself. */
-       if (!xenbus_exists(be->frontpath, "")) {
+       if (node && !xenbus_exists(be->frontpath, "")) {
                xenbus_rm(be->dev->nodename, "");
                device_unregister(&be->dev->dev);
                return;
        }
-       if (be->blkif->status == CONNECTED)
-               return;
-
-       err = xenbus_gather(be->frontpath, "grant-id", "%lu", &sharedmfn,
+       if (be->blkif == NULL || be->blkif->status == CONNECTED)
+               return;
+
+       err = xenbus_gather(be->frontpath, "ring-ref", "%lu", &ring_ref,
                            "event-channel", "%u", &evtchn, NULL);
        if (err) {
                xenbus_dev_error(be->dev, err,
-                                "reading %s/grant-id and event-channel",
+                                "reading %s/ring-ref and event-channel",
                                 be->frontpath);
                return;
        }
@@ -113,11 +113,10 @@
        }
 
        /* Map the shared frame, irq etc. */
-       err = blkif_map(be->blkif, sharedmfn, evtchn);
-       if (err) {
-               xenbus_dev_error(be->dev, err,
-                                "mapping shared-frame %lu port %u",
-                                sharedmfn, evtchn);
+       err = blkif_map(be->blkif, ring_ref, evtchn);
+       if (err) {
+               xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u",
+                                ring_ref, evtchn);
                goto abort;
        }
 
@@ -139,133 +138,125 @@
 {
        int err;
        char *p;
-       char *frontend;
        long int handle, pdev;
        struct backend_info *be
                = container_of(watch, struct backend_info, backend_watch);
        struct xenbus_device *dev = be->dev;
+
+       err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev);
+       if (XENBUS_EXIST_ERR(err))
+               return;
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "reading physical-device");
+               return;
+       }
+       if (be->pdev && be->pdev != pdev) {
+               printk(KERN_WARNING
+                      "changing physical-device not supported\n");
+               return;
+       }
+       be->pdev = pdev;
+
+       /* If there's a read-only node, we're read only. */
+       p = xenbus_read(dev->nodename, "read-only", NULL);
+       if (!IS_ERR(p)) {
+               be->readonly = 1;
+               kfree(p);
+       }
+
+       if (be->blkif == NULL) {
+               /* Front end dir is a number, which is used as the handle. */
+               p = strrchr(be->frontpath, '/') + 1;
+               handle = simple_strtoul(p, NULL, 0);
+
+               be->blkif = alloc_blkif(be->frontend_id);
+               if (IS_ERR(be->blkif)) {
+                       err = PTR_ERR(be->blkif);
+                       be->blkif = NULL;
+                       xenbus_dev_error(dev, err, "creating block interface");
+                       return;
+               }
+
+               err = vbd_create(be->blkif, handle, be->pdev, be->readonly);
+               if (err) {
+                       xenbus_dev_error(dev, err, "creating vbd structure");
+                       return;
+               }
+
+               /* Pass in NULL node to skip exist test. */
+               frontend_changed(&be->watch, NULL);
+       }
+}
+
+static int blkback_probe(struct xenbus_device *dev,
+                        const struct xenbus_device_id *id)
+{
+       struct backend_info *be;
+       char *frontend;
+       int err;
+
+       be = kmalloc(sizeof(*be), GFP_KERNEL);
+       if (!be) {
+               xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
+               return -ENOMEM;
+       }
+       memset(be, 0, sizeof(*be));
 
        frontend = NULL;
        err = xenbus_gather(dev->nodename,
                            "frontend-id", "%li", &be->frontend_id,
                            "frontend", NULL, &frontend,
                            NULL);
-       if (XENBUS_EXIST_ERR(err) ||
-           strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
+       if (XENBUS_EXIST_ERR(err))
+               goto free_be;
+       if (err < 0) {
+               xenbus_dev_error(dev, err,
+                                "reading %s/frontend or frontend-id",
+                                dev->nodename);
+               goto free_be;
+       }
+       if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
                /* If we can't get a frontend path and a frontend-id,
                 * then our bus-id is no longer valid and we need to
                 * destroy the backend device.
                 */
-               goto device_fail;
-       }
-       if (err < 0) {
-               xenbus_dev_error(dev, err,
-                                "reading %s/frontend or frontend-id",
-                                dev->nodename);
-               goto device_fail;
-       }
-
-       if (!be->frontpath || strcmp(frontend, be->frontpath)) {
-               if (be->watch.node)
-                       unregister_xenbus_watch(&be->watch);
-               if (be->frontpath)
-                       kfree(be->frontpath);
-               be->frontpath = frontend;
-               frontend = NULL;
-               be->watch.node = be->frontpath;
-               be->watch.callback = frontend_changed;
-               err = register_xenbus_watch(&be->watch);
-               if (err) {
-                       be->watch.node = NULL;
-                       xenbus_dev_error(dev, err,
-                                        "adding frontend watch on %s",
-                                        be->frontpath);
-                       goto device_fail;
-               }
-       }
-
-       err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev);
-       if (XENBUS_EXIST_ERR(err))
-               goto out;
-       if (err < 0) {
-               xenbus_dev_error(dev, err, "reading physical-device");
-               goto device_fail;
-       }
-       if (be->pdev && be->pdev != pdev) {
-               printk(KERN_WARNING
-                      "changing physical-device not supported\n");
-               goto device_fail;
-       }
-       be->pdev = pdev;
-
-       /* If there's a read-only node, we're read only. */
-       p = xenbus_read(dev->nodename, "read-only", NULL);
-       if (!IS_ERR(p)) {
-               be->readonly = 1;
-               kfree(p);
-       }
-
-       if (be->blkif == NULL) {
-               /* Front end dir is a number, which is used as the handle. */
-               p = strrchr(be->frontpath, '/') + 1;
-               handle = simple_strtoul(p, NULL, 0);
-
-               be->blkif = alloc_blkif(be->frontend_id);
-               if (IS_ERR(be->blkif)) {
-                       err = PTR_ERR(be->blkif);
-                       be->blkif = NULL;
-                       xenbus_dev_error(dev, err, "creating block interface");
-                       goto device_fail;
-               }
-
-               err = vbd_create(be->blkif, handle, be->pdev, be->readonly);
-               if (err) {
-                       xenbus_dev_error(dev, err, "creating vbd structure");
-                       goto device_fail;
-               }
-
-               frontend_changed(&be->watch, be->frontpath);
-       }
-
- out:
-       if (frontend)
-               kfree(frontend);
-       return;
-
- device_fail:
-       device_unregister(&be->dev->dev);
-       goto out;
-}
-
-static int blkback_probe(struct xenbus_device *dev,
-                        const struct xenbus_device_id *id)
-{
-       struct backend_info *be;
-       int err;
-
-       be = kmalloc(sizeof(*be), GFP_KERNEL);
-       if (!be) {
-               xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
-               return -ENOMEM;
-       }
-
-       memset(be, 0, sizeof(*be));
+               err = -ENOENT;
+               goto free_be;
+       }
 
        be->dev = dev;
        be->backend_watch.node = dev->nodename;
        be->backend_watch.callback = backend_changed;
        err = register_xenbus_watch(&be->backend_watch);
        if (err) {
+               be->backend_watch.node = NULL;
                xenbus_dev_error(dev, err, "adding backend watch on %s",
                                 dev->nodename);
                goto free_be;
        }
 
+       be->frontpath = frontend;
+       be->watch.node = be->frontpath;
+       be->watch.callback = frontend_changed;
+       err = register_xenbus_watch(&be->watch);
+       if (err) {
+               be->watch.node = NULL;
+               xenbus_dev_error(dev, err,
+                                "adding frontend watch on %s",
+                                be->frontpath);
+               goto free_be;
+       }
+
        dev->data = be;
 
        backend_changed(&be->backend_watch, dev->nodename);
-       return err;
+       return 0;
+
  free_be:
+       if (be->backend_watch.node)
+               unregister_xenbus_watch(&be->backend_watch);
+       if (frontend)
+               kfree(frontend);
        kfree(be);
        return err;
 }
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Wed Aug 24 
23:16:52 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Thu Aug 25 
18:18:47 2005
@@ -1084,7 +1084,8 @@
                            "sector-size", "%lu", &sector_size,
                            NULL);
        if (err) {
-               xenbus_dev_error(info->xbdev, err, "reading backend fields");
+               xenbus_dev_error(info->xbdev, err,
+                                "reading backend fields at %s", watch->node);
                return;
        }
 
@@ -1123,12 +1124,12 @@
                xenbus_dev_error(dev, err, "granting access to ring page");
                return err;
        }
-       info->grant_id = err;
+       info->ring_ref = err;
 
        op.u.alloc_unbound.dom = info->backend_id;
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
-               gnttab_end_foreign_access(info->grant_id, 0);
+               gnttab_end_foreign_access(info->ring_ref, 0);
                free_page((unsigned long)info->ring.sring);
                info->ring.sring = 0;
                xenbus_dev_error(dev, err, "allocating event channel");
@@ -1176,9 +1177,9 @@
                goto destroy_blkring;
        }
 
-       err = xenbus_printf(dev->nodename, "grant-id","%u", info->grant_id);
+       err = xenbus_printf(dev->nodename, "ring-ref","%u", info->ring_ref);
        if (err) {
-               message = "writing grant-id";
+               message = "writing ring-ref";
                goto abort_transaction;
        }
        err = xenbus_printf(dev->nodename,
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Wed Aug 24 23:16:52 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Thu Aug 25 18:18:47 2005
@@ -112,7 +112,7 @@
        int connected;
        char *backend;
        int backend_id;
-       int grant_id;
+       int ring_ref;
        blkif_front_ring_t ring;
        unsigned int evtchn;
        struct xlbd_major_info *mi;
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/drivers/xen/console/console.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/console.c        Wed Aug 24 
23:16:52 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c        Thu Aug 25 
18:18:47 2005
@@ -240,7 +240,11 @@
 #endif
 
 /*** Useful function for console debugging -- goes straight to Xen. ***/
+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
 asmlinkage int xprintk(const char *fmt, ...)
+#else
+asmlinkage int xprintk(const char *fmt, ...)
+#endif
 {
     va_list args;
     int printk_len;
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/drivers/xen/netback/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/netback/Makefile Wed Aug 24 23:16:52 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/Makefile Thu Aug 25 18:18:47 2005
@@ -1,2 +1,2 @@
 
-obj-y  := netback.o control.o interface.o loopback.o
+obj-y  := netback.o xenbus.o interface.o loopback.o
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Wed Aug 24 23:16:52 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Thu Aug 25 18:18:47 2005
@@ -59,6 +59,7 @@
     grant_ref_t      rx_shmem_ref; 
 #endif
     unsigned int     evtchn;
+    unsigned int     remote_evtchn;
 
     /* The shared rings and indexes. */
     netif_tx_interface_t *tx;
@@ -82,36 +83,30 @@
     /* Miscellaneous private stuff. */
     enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
     int active;
-    /*
-     * DISCONNECT response is deferred until pending requests are ack'ed.
-     * We therefore need to store the id from the original request.
-     */
-    u8               disconnect_rspid;
-    struct netif_st *hash_next;
     struct list_head list;  /* scheduling list */
     atomic_t         refcnt;
     struct net_device *dev;
     struct net_device_stats stats;
 
-    struct work_struct work;
+    struct work_struct free_work;
 } netif_t;
 
-void netif_create(netif_be_create_t *create);
-void netif_destroy(netif_be_destroy_t *destroy);
-void netif_creditlimit(netif_be_creditlimit_t *creditlimit);
-void netif_connect(netif_be_connect_t *connect);
-int  netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id);
-void netif_disconnect_complete(netif_t *netif);
-netif_t *netif_find_by_handle(domid_t domid, unsigned int handle);
+void netif_creditlimit(netif_t *netif);
+int  netif_disconnect(netif_t *netif);
+
+netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
+void free_netif_callback(netif_t *netif);
+int netif_map(netif_t *netif, unsigned long tx_ring_ref,
+             unsigned long rx_ring_ref, unsigned int evtchn);
+
 #define netif_get(_b) (atomic_inc(&(_b)->refcnt))
 #define netif_put(_b)                             \
     do {                                          \
         if ( atomic_dec_and_test(&(_b)->refcnt) ) \
-            netif_disconnect_complete(_b);        \
+            free_netif_callback(_b);              \
     } while (0)
 
-void netif_interface_init(void);
-void netif_ctrlif_init(void);
+void netif_xenbus_init(void);
 
 void netif_schedule_work(netif_t *netif);
 void netif_deschedule_work(netif_t *netif);
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Wed Aug 24 
23:16:52 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Thu Aug 25 
18:18:47 2005
@@ -9,24 +9,6 @@
 #include "common.h"
 #include <linux/rtnetlink.h>
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#endif
-
-#define NETIF_HASHSZ 1024
-#define NETIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(NETIF_HASHSZ-1))
-
-static netif_t *netif_hash[NETIF_HASHSZ];
-
-netif_t *netif_find_by_handle(domid_t domid, unsigned int handle)
-{
-    netif_t *netif = netif_hash[NETIF_HASH(domid, handle)];
-    while ( (netif != NULL) && 
-            ((netif->domid != domid) || (netif->handle != handle)) )
-        netif = netif->hash_next;
-    return netif;
-}
-
 static void __netif_up(netif_t *netif)
 {
     struct net_device *dev = netif->dev;
@@ -51,7 +33,7 @@
 static int net_open(struct net_device *dev)
 {
     netif_t *netif = netdev_priv(dev);
-    if ( netif->status == CONNECTED )
+    if (netif->status == CONNECTED)
         __netif_up(netif);
     netif_start_queue(dev);
     return 0;
@@ -61,92 +43,23 @@
 {
     netif_t *netif = netdev_priv(dev);
     netif_stop_queue(dev);
-    if ( netif->status == CONNECTED )
+    if (netif->status == CONNECTED)
         __netif_down(netif);
     return 0;
 }
 
-static void __netif_disconnect_complete(void *arg)
-{
-    netif_t              *netif = (netif_t *)arg;
-    ctrl_msg_t            cmsg;
-    netif_be_disconnect_t disc;
-#if defined(CONFIG_XEN_NETDEV_GRANT_RX) || defined(CONFIG_XEN_NETDEV_GRANT_TX)
-    struct gnttab_unmap_grant_ref op;
-#endif
-
-    /*
-     * These can't be done in netif_disconnect() because at that point there
-     * may be outstanding requests in the network stack whose asynchronous
-     * responses must still be notified to the remote driver.
-     */
-
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
-    op.host_addr    = netif->tx_shmem_vaddr;
-    op.handle       = netif->tx_shmem_handle;
-    op.dev_bus_addr = 0;
-    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
-#endif
-
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
-    op.host_addr    = netif->rx_shmem_vaddr;
-    op.handle       = netif->rx_shmem_handle;
-    op.dev_bus_addr = 0;
-    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
-#endif
-
-
-    vfree(netif->tx); /* Frees netif->rx as well. */
-
-    /* Construct the deferred response message. */
-    cmsg.type         = CMSG_NETIF_BE;
-    cmsg.subtype      = CMSG_NETIF_BE_DISCONNECT;
-    cmsg.id           = netif->disconnect_rspid;
-    cmsg.length       = sizeof(netif_be_disconnect_t);
-    disc.domid        = netif->domid;
-    disc.netif_handle = netif->handle;
-    disc.status       = NETIF_BE_STATUS_OKAY;
-    memcpy(cmsg.msg, &disc, sizeof(disc));
-
-    /*
-     * Make sure message is constructed /before/ status change, because
-     * after the status change the 'netif' structure could be deallocated at
-     * any time. Also make sure we send the response /after/ status change,
-     * as otherwise a subsequent CONNECT request could spuriously fail if
-     * another CPU doesn't see the status change yet.
-     */
-    mb();
-    if ( netif->status != DISCONNECTING )
-        BUG();
-    netif->status = DISCONNECTED;
-    mb();
-
-    /* Send the successful response. */
-    ctrl_if_send_response(&cmsg);
-}
-
-void netif_disconnect_complete(netif_t *netif)
-{
-    INIT_WORK(&netif->work, __netif_disconnect_complete, (void *)netif);
-    schedule_work(&netif->work);
-}
-
-void netif_create(netif_be_create_t *create)
-{
-    int                err = 0;
-    domid_t            domid  = create->domid;
-    unsigned int       handle = create->netif_handle;
+netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN])
+{
+    int err = 0, i;
     struct net_device *dev;
-    netif_t          **pnetif, *netif;
-    char               name[IFNAMSIZ] = {};
+    netif_t *netif;
+    char name[IFNAMSIZ] = {};
 
     snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle);
     dev = alloc_netdev(sizeof(netif_t), name, ether_setup);
-    if ( dev == NULL )
-    {
+    if (dev == NULL) {
         DPRINTK("Could not create netif: out of memory\n");
-        create->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
-        return;
+        return NULL;
     }
 
     netif = netdev_priv(dev);
@@ -161,19 +74,6 @@
     netif->credit_usec  = 0UL;
     init_timer(&netif->credit_timeout);
 
-    pnetif = &netif_hash[NETIF_HASH(domid, handle)];
-    while ( *pnetif != NULL )
-    {
-        if ( ((*pnetif)->domid == domid) && ((*pnetif)->handle == handle) )
-        {
-            DPRINTK("Could not create netif: already exists\n");
-            create->status = NETIF_BE_STATUS_INTERFACE_EXISTS;
-            free_netdev(dev);
-            return;
-        }
-        pnetif = &(*pnetif)->hash_next;
-    }
-
     dev->hard_start_xmit = netif_be_start_xmit;
     dev->get_stats       = netif_be_get_stats;
     dev->open            = net_open;
@@ -183,10 +83,10 @@
     /* Disable queuing. */
     dev->tx_queue_len = 0;
 
-    if ( (create->be_mac[0] == 0) && (create->be_mac[1] == 0) &&
-         (create->be_mac[2] == 0) && (create->be_mac[3] == 0) &&
-         (create->be_mac[4] == 0) && (create->be_mac[5] == 0) )
-    {
+    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
@@ -194,87 +94,200 @@
          */ 
         memset(dev->dev_addr, 0xFF, ETH_ALEN);
         dev->dev_addr[0] &= ~0x01;
-    }
-    else
-    {
-        memcpy(dev->dev_addr, create->be_mac, ETH_ALEN);
-    }
-
-    memcpy(netif->fe_dev_addr, create->mac, ETH_ALEN);
+    } else
+        memcpy(dev->dev_addr, be_mac, ETH_ALEN);
 
     rtnl_lock();
     err = register_netdevice(dev);
     rtnl_unlock();
-
-    if ( err != 0 )
-    {
+    if (err) {
         DPRINTK("Could not register new net device %s: err=%d\n",
                 dev->name, err);
-        create->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
         free_netdev(dev);
-        return;
-    }
-
-    netif->hash_next = *pnetif;
-    *pnetif = netif;
+        return NULL;
+    }
 
     DPRINTK("Successfully created netif\n");
-    create->status = NETIF_BE_STATUS_OKAY;
-}
-
-void netif_destroy(netif_be_destroy_t *destroy)
-{
-    domid_t       domid  = destroy->domid;
-    unsigned int  handle = destroy->netif_handle;
-    netif_t     **pnetif, *netif;
-
-    pnetif = &netif_hash[NETIF_HASH(domid, handle)];
-    while ( (netif = *pnetif) != NULL )
+    return netif;
+}
+
+static int map_frontend_page(netif_t *netif, unsigned long localaddr,
+                            unsigned long tx_ring_ref, unsigned long 
rx_ring_ref)
+{
+#if !defined(CONFIG_XEN_NETDEV_GRANT_TX)||!defined(CONFIG_XEN_NETDEV_GRANT_RX)
+    pgprot_t      prot = __pgprot(_KERNPG_TABLE);
+    int           err;
+#endif
+#if defined(CONFIG_XEN_NETDEV_GRANT_TX)
     {
-        if ( (netif->domid == domid) && (netif->handle == handle) )
-        {
-            if ( netif->status != DISCONNECTED )
-                goto still_connected;
-            goto destroy;
+        struct gnttab_map_grant_ref op;
+
+        /* Map: Use the Grant table reference */
+        op.host_addr = localaddr;
+        op.flags     = GNTMAP_host_map;
+        op.ref       = tx_ring_ref;
+        op.dom       = netif->domid;
+       
+       BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+        if (op.handle < 0) { 
+            DPRINTK(" Grant table operation failure !\n");
+            return op.handle;
         }
-        pnetif = &netif->hash_next;
-    }
-
-    destroy->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND;
-    return;
-
- still_connected:
-    destroy->status = NETIF_BE_STATUS_INTERFACE_CONNECTED;
-    return;
-
- destroy:
-    *pnetif = netif->hash_next;
+
+        netif->tx_shmem_ref    = tx_ring_ref;
+        netif->tx_shmem_handle = op.handle;
+        netif->tx_shmem_vaddr  = localaddr;
+    }
+#else 
+    err = direct_remap_area_pages(&init_mm, localaddr,
+                                 tx_ring_ref<<PAGE_SHIFT, PAGE_SIZE,
+                                 prot, netif->domid); 
+    if (err)
+       return err;
+#endif
+
+#if defined(CONFIG_XEN_NETDEV_GRANT_RX)
+    {
+        struct gnttab_map_grant_ref op;
+
+        /* Map: Use the Grant table reference */
+        op.host_addr = localaddr + PAGE_SIZE;
+        op.flags     = GNTMAP_host_map;
+        op.ref       = rx_ring_ref;
+        op.dom       = netif->domid;
+
+       BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+        if (op.handle < 0) { 
+            DPRINTK(" Grant table operation failure !\n");
+            return op.handle;
+        }
+
+        netif->rx_shmem_ref    = rx_ring_ref;
+        netif->rx_shmem_handle = op.handle;
+        netif->rx_shmem_vaddr  = localaddr + PAGE_SIZE;
+    }
+#else 
+    err = direct_remap_area_pages(&init_mm, localaddr + PAGE_SIZE,
+                                 rx_ring_ref<<PAGE_SHIFT, PAGE_SIZE,
+                                 prot, netif->domid);
+    if (err)
+       return err;
+#endif
+
+    return 0;
+}
+
+static void unmap_frontend_page(netif_t *netif)
+{
+#if defined(CONFIG_XEN_NETDEV_GRANT_RX) || defined(CONFIG_XEN_NETDEV_GRANT_TX)
+    struct gnttab_unmap_grant_ref op;
+#endif
+
+#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+    op.host_addr    = netif->tx_shmem_vaddr;
+    op.handle       = netif->tx_shmem_handle;
+    op.dev_bus_addr = 0;
+    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
+#endif
+
+#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+    op.host_addr    = netif->rx_shmem_vaddr;
+    op.handle       = netif->rx_shmem_handle;
+    op.dev_bus_addr = 0;
+    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
+#endif
+}
+
+int netif_map(netif_t *netif, unsigned long tx_ring_ref,
+             unsigned long rx_ring_ref, unsigned int evtchn)
+{
+    struct vm_struct *vma;
+    evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
+    int err;
+
+    vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP);
+    if (vma == NULL)
+        return -ENOMEM;
+
+    err = map_frontend_page(netif, (unsigned long)vma->addr, tx_ring_ref,
+                           rx_ring_ref);
+    if (err) {
+        vfree(vma->addr);
+       return err;
+    }
+
+    op.u.bind_interdomain.dom1 = DOMID_SELF;
+    op.u.bind_interdomain.dom2 = netif->domid;
+    op.u.bind_interdomain.port1 = 0;
+    op.u.bind_interdomain.port2 = evtchn;
+    err = HYPERVISOR_event_channel_op(&op);
+    if (err) {
+       unmap_frontend_page(netif);
+       vfree(vma->addr);
+       return err;
+    }
+
+    netif->evtchn = op.u.bind_interdomain.port1;
+    netif->remote_evtchn = evtchn;
+
+    netif->tx = (netif_tx_interface_t *)vma->addr;
+    netif->rx = (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE);
+    netif->tx->resp_prod = netif->rx->resp_prod = 0;
+    netif_get(netif);
+    wmb(); /* Other CPUs see new state before interface is started. */
+
+    rtnl_lock();
+    netif->status = CONNECTED;
+    wmb();
+    if (netif_running(netif->dev))
+        __netif_up(netif);
+    rtnl_unlock();
+
+    return 0;
+}
+
+static void free_netif(void *arg)
+{
+    evtchn_op_t op = { .cmd = EVTCHNOP_close };
+    netif_t *netif = (netif_t *)arg;
+
+    /*
+     * These can't be done in netif_disconnect() because at that point there
+     * may be outstanding requests in the network stack whose asynchronous
+     * responses must still be notified to the remote driver.
+     */
+
+    op.u.close.port = netif->evtchn;
+    op.u.close.dom = DOMID_SELF;
+    HYPERVISOR_event_channel_op(&op);
+    op.u.close.port = netif->remote_evtchn;
+    op.u.close.dom = netif->domid;
+    HYPERVISOR_event_channel_op(&op);
+
     unregister_netdev(netif->dev);
+
+    if (netif->tx) {
+       unmap_frontend_page(netif);
+       vfree(netif->tx); /* Frees netif->rx as well. */
+    }
+
     free_netdev(netif->dev);
-    destroy->status = NETIF_BE_STATUS_OKAY;
-}
-
-void netif_creditlimit(netif_be_creditlimit_t *creditlimit)
-{
-    domid_t       domid  = creditlimit->domid;
-    unsigned int  handle = creditlimit->netif_handle;
-    netif_t      *netif;
-
-    netif = netif_find_by_handle(domid, handle);
-    if ( unlikely(netif == NULL) )
-    {
-        DPRINTK("netif_creditlimit attempted for non-existent netif"
-                " (%u,%u)\n", creditlimit->domid, creditlimit->netif_handle); 
-        creditlimit->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND;
-        return; 
-    }
-
+}
+
+void free_netif_callback(netif_t *netif)
+{
+    INIT_WORK(&netif->free_work, free_netif, (void *)netif);
+    schedule_work(&netif->free_work);
+}
+
+void netif_creditlimit(netif_t *netif)
+{
+#if 0
     /* Set the credit limit (reset remaining credit to new limit). */
     netif->credit_bytes = netif->remaining_credit = creditlimit->credit_bytes;
     netif->credit_usec = creditlimit->period_usec;
 
-    if ( netif->status == CONNECTED )
-    {
+    if (netif->status == CONNECTED) {
         /*
          * Schedule work so that any packets waiting under previous credit 
          * limit are dealt with (acts like a replenishment point).
@@ -282,184 +295,22 @@
         netif->credit_timeout.expires = jiffies;
         netif_schedule_work(netif);
     }
-    
-    creditlimit->status = NETIF_BE_STATUS_OKAY;
-}
-
-void netif_connect(netif_be_connect_t *connect)
-{
-    domid_t       domid  = connect->domid;
-    unsigned int  handle = connect->netif_handle;
-    unsigned int  evtchn = connect->evtchn;
-    unsigned long tx_shmem_frame = connect->tx_shmem_frame;
-    unsigned long rx_shmem_frame = connect->rx_shmem_frame;
-    struct vm_struct *vma;
-#if !defined(CONFIG_XEN_NETDEV_GRANT_TX)||!defined(CONFIG_XEN_NETDEV_GRANT_RX)
-    pgprot_t      prot = __pgprot(_KERNPG_TABLE);
-    int           error;
-#endif
-    netif_t      *netif;
-
-    netif = netif_find_by_handle(domid, handle);
-    if ( unlikely(netif == NULL) ) {
-        DPRINTK("netif_connect attempted for non-existent netif (%u,%u)\n", 
-                connect->domid, connect->netif_handle); 
-        connect->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND;
-        return;
-    }
-
-    if ( netif->status != DISCONNECTED ) {
-        connect->status = NETIF_BE_STATUS_INTERFACE_CONNECTED;
-        return;
-    }
-
-    if ( (vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP)) == NULL ) {
-        connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
-        return;
-    }
-
-
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX)
-    {
-        struct gnttab_map_grant_ref op;
-        int tx_ref = connect->tx_shmem_ref; 
-
-        /* Map: Use the Grant table reference */
-        op.host_addr = VMALLOC_VMADDR(vma->addr);
-        op.flags     = GNTMAP_host_map;
-        op.ref       = tx_ref;
-        op.dom       = domid;
-       
-        if ((HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) < 0) || 
-            (op.handle < 0)) { 
-            DPRINTK(" Grant table operation failure !\n");
-            connect->status = NETIF_BE_STATUS_MAPPING_ERROR;
-            vfree(vma->addr);
-            return;
-        }
-
-        netif->tx_shmem_ref    = tx_ref;
-        netif->tx_shmem_handle = op.handle;
-        netif->tx_shmem_vaddr  = VMALLOC_VMADDR(vma->addr);
-    }
-        
-
-#else 
-    error = direct_remap_area_pages(&init_mm, 
-                                    VMALLOC_VMADDR(vma->addr),
-                                    tx_shmem_frame<<PAGE_SHIFT, PAGE_SIZE,
-                                    prot, domid); 
-    if ( error != 0 )
-    {
-        if ( error == -ENOMEM )
-            connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
-        else if ( error == -EFAULT )
-            connect->status = NETIF_BE_STATUS_MAPPING_ERROR;
-        else
-            connect->status = NETIF_BE_STATUS_ERROR;
-        vfree(vma->addr);
-        return;
-    }
-#endif
-
-
-#if defined(CONFIG_XEN_NETDEV_GRANT_RX)
-    {
-        struct gnttab_map_grant_ref op;
-        int rx_ref = connect->rx_shmem_ref; 
-
-
-        /* Map: Use the Grant table reference */
-        op.host_addr = VMALLOC_VMADDR(vma->addr) + PAGE_SIZE;
-        op.flags     = GNTMAP_host_map;
-        op.ref       = rx_ref;
-        op.dom       = domid;
-
-        if ((HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) < 0) || 
-            (op.handle < 0)) { 
-            DPRINTK(" Grant table operation failure !\n");
-            connect->status = NETIF_BE_STATUS_MAPPING_ERROR;
-            vfree(vma->addr);
-            return;
-        }
-
-        netif->rx_shmem_ref    = rx_ref;
-        netif->rx_shmem_handle = handle;
-        netif->rx_shmem_vaddr  = VMALLOC_VMADDR(vma->addr) + PAGE_SIZE;
-    }
-#else 
-    error = direct_remap_area_pages(&init_mm, 
-                                     VMALLOC_VMADDR(vma->addr) + PAGE_SIZE,
-                                     rx_shmem_frame<<PAGE_SHIFT, PAGE_SIZE,
-                                     prot, domid);
-    if ( error != 0 )
-    {
-        if ( error == -ENOMEM )
-            connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
-        else if ( error == -EFAULT )
-            connect->status = NETIF_BE_STATUS_MAPPING_ERROR;
-        else
-            connect->status = NETIF_BE_STATUS_ERROR;
-        vfree(vma->addr);
-        return;
-    }
-
-#endif
-
-    netif->evtchn         = evtchn;
-    netif->tx_shmem_frame = tx_shmem_frame;
-    netif->rx_shmem_frame = rx_shmem_frame;
-    netif->tx             = 
-        (netif_tx_interface_t *)vma->addr;
-    netif->rx             = 
-        (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE);
-    netif->tx->resp_prod = netif->rx->resp_prod = 0;
-    netif_get(netif);
-    wmb(); /* Other CPUs see new state before interface is started. */
-
-    rtnl_lock();
-    netif->status = CONNECTED;
-    wmb();
-    if ( netif_running(netif->dev) )
-        __netif_up(netif);
-    rtnl_unlock();
-
-    connect->status = NETIF_BE_STATUS_OKAY;
-}
-
-int netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id)
-{
-    domid_t       domid  = disconnect->domid;
-    unsigned int  handle = disconnect->netif_handle;
-    netif_t      *netif;
-
-    netif = netif_find_by_handle(domid, handle);
-    if ( unlikely(netif == NULL) )
-    {
-        DPRINTK("netif_disconnect attempted for non-existent netif"
-                " (%u,%u)\n", disconnect->domid, disconnect->netif_handle); 
-        disconnect->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND;
-        return 1; /* Caller will send response error message. */
-    }
-
-    if ( netif->status == CONNECTED )
-    {
+#endif
+}
+
+int netif_disconnect(netif_t *netif)
+{
+
+    if (netif->status == CONNECTED) {
         rtnl_lock();
         netif->status = DISCONNECTING;
-        netif->disconnect_rspid = rsp_id;
         wmb();
-        if ( netif_running(netif->dev) )
+        if (netif_running(netif->dev))
             __netif_down(netif);
         rtnl_unlock();
         netif_put(netif);
         return 0; /* Caller should not send response message. */
     }
 
-    disconnect->status = NETIF_BE_STATUS_OKAY;
     return 1;
 }
-
-void netif_interface_init(void)
-{
-    memset(netif_hash, 0, sizeof(netif_hash));
-}
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Wed Aug 24 
23:16:52 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Thu Aug 25 
18:18:47 2005
@@ -13,10 +13,6 @@
 #include "common.h"
 #include <asm-xen/balloon.h>
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-#include <linux/delay.h>
-#endif
-
 #if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
 #include <asm-xen/xen-public/grant_table.h>
 #include <asm-xen/gnttab.h>
@@ -153,11 +149,7 @@
 static inline int is_xen_skb(struct sk_buff *skb)
 {
     extern kmem_cache_t *skbuff_cachep;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->lru.next;
-#else
-    kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->list.next;
-#endif
     return (cp == skbuff_cachep);
 }
 
@@ -642,11 +634,7 @@
                 netif->credit_timeout.expires  = next_credit;
                 netif->credit_timeout.data     = (unsigned long)netif;
                 netif->credit_timeout.function = tx_credit_callback;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
                 add_timer_on(&netif->credit_timeout, smp_processor_id());
-#else
-                add_timer(&netif->credit_timeout); 
-#endif
                 break;
             }
         }
@@ -966,8 +954,6 @@
     net_timer.data = 0;
     net_timer.function = net_alarm;
     
-    netif_interface_init();
-
     page = balloon_alloc_empty_page_range(MAX_PENDING_REQS);
     BUG_ON(page == NULL);
     mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
@@ -987,7 +973,7 @@
     spin_lock_init(&net_schedule_list_lock);
     INIT_LIST_HEAD(&net_schedule_list);
 
-    netif_ctrlif_init();
+    netif_xenbus_init();
 
     (void)request_irq(bind_virq_to_irq(VIRQ_DEBUG),
                       netif_be_dbg, SA_SHIRQ, 
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Aug 24 
23:16:52 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Thu Aug 25 
18:18:47 2005
@@ -48,7 +48,7 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm-xen/evtchn.h>
-#include <asm-xen/ctrl_if.h>
+#include <asm-xen/xenbus.h>
 #include <asm-xen/xen-public/io/netif.h>
 #include <asm-xen/balloon.h>
 #include <asm/page.h>
@@ -112,9 +112,13 @@
 #endif
 
 #if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
-static domid_t rdomid = 0;
 #define GRANT_INVALID_REF      (0xFFFF)
 #endif
+
+#define NETIF_STATE_DISCONNECTED 0
+#define NETIF_STATE_CONNECTED    1
+
+static unsigned int netif_state = NETIF_STATE_DISCONNECTED;
 
 static void network_tx_buf_gc(struct net_device *dev);
 static void network_alloc_rx_buffers(struct net_device *dev);
@@ -133,12 +137,11 @@
 #define xennet_proc_delif(d) ((void)0)
 #endif
 
-static struct list_head dev_list;
-
+#define netfront_info net_private
 struct net_private
 {
     struct list_head list;
-    struct net_device *dev;
+    struct net_device *netdev;
 
     struct net_device_stats stats;
     NETIF_RING_IDX rx_resp_cons, tx_resp_cons;
@@ -176,6 +179,14 @@
      */
     struct sk_buff *tx_skbs[NETIF_TX_RING_SIZE+1];
     struct sk_buff *rx_skbs[NETIF_RX_RING_SIZE+1];
+
+       struct xenbus_device *xbdev;
+       char *backend;
+       int backend_id;
+       struct xenbus_watch watch;
+       int tx_ring_ref;
+       int rx_ring_ref;
+       u8 mac[ETH_ALEN];
 };
 
 /* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */
@@ -187,20 +198,14 @@
     (_list)[0]  = (_list)[_id];                    \
     (unsigned short)_id; })
 
-static char *status_name[] = {
-    [NETIF_INTERFACE_STATUS_CLOSED]       = "closed",
-    [NETIF_INTERFACE_STATUS_DISCONNECTED] = "disconnected",
-    [NETIF_INTERFACE_STATUS_CONNECTED]    = "connected",
-    [NETIF_INTERFACE_STATUS_CHANGED]      = "changed",
-};
-
+#ifdef DEBUG
 static char *be_state_name[] = {
     [BEST_CLOSED]       = "closed",
     [BEST_DISCONNECTED] = "disconnected",
     [BEST_CONNECTED]    = "connected",
 };
-
-#define DEBUG
+#endif
+
 #ifdef DEBUG
 #define DPRINTK(fmt, args...) \
     printk(KERN_ALERT "xen_net (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
@@ -211,89 +216,6 @@
     printk(KERN_INFO "xen_net: " fmt, ##args)
 #define WPRINTK(fmt, args...) \
     printk(KERN_WARNING "xen_net: " fmt, ##args)
-
-static struct net_device *find_dev_by_handle(unsigned int handle)
-{
-    struct list_head *ent;
-    struct net_private *np;
-    list_for_each (ent, &dev_list) {
-        np = list_entry(ent, struct net_private, list);
-        if (np->handle == handle)
-            return np->dev;
-    }
-    return NULL;
-}
-
-/** Network interface info. */
-struct netif_ctrl {
-    /** Number of interfaces. */
-    int interface_n;
-    /** Number of connected interfaces. */
-    int connected_n;
-    /** Error code. */
-    int err;
-    int up;
-};
-
-static struct netif_ctrl netctrl;
-
-static void netctrl_init(void)
-{
-    memset(&netctrl, 0, sizeof(netctrl));
-    netctrl.up = NETIF_DRIVER_STATUS_DOWN;
-}
-
-/** Get or set a network interface error.
- */
-static int netctrl_err(int err)
-{
-    if ((err < 0) && !netctrl.err)
-        netctrl.err = err;
-    return netctrl.err;
-}
-
-/** Test if all network interfaces are connected.
- *
- * @return 1 if all connected, 0 if not, negative error code otherwise
- */
-static int netctrl_connected(void)
-{
-    int ok;
-
-    if (netctrl.err)
-        ok = netctrl.err;
-    else if (netctrl.up == NETIF_DRIVER_STATUS_UP)
-        ok = (netctrl.connected_n == netctrl.interface_n);
-    else
-        ok = 0;
-
-    return ok;
-}
-
-/** Count the connected network interfaces.
- *
- * @return connected count
- */
-static int netctrl_connected_count(void)
-{
-    
-    struct list_head *ent;
-    struct net_private *np;
-    unsigned int connected;
-
-    connected = 0;
-    
-    list_for_each(ent, &dev_list) {
-        np = list_entry(ent, struct net_private, list);
-        if (np->backend_state == BEST_CONNECTED)
-            connected++;
-    }
-
-    netctrl.connected_n = connected;
-    DPRINTK("> connected_n=%d interface_n=%d\n",
-            netctrl.connected_n, netctrl.interface_n);
-    return connected;
-}
 
 /** Send a packet on a net device to encourage switches to learn the
  * MAC. We send a fake ARP request.
@@ -364,7 +286,7 @@
                        "still in use by backend domain.\n");
                 goto out; 
             }
-            gnttab_end_foreign_access(grant_tx_ref[id], GNTMAP_readonly);
+            gnttab_end_foreign_access_ref(grant_tx_ref[id], GNTMAP_readonly);
             gnttab_release_grant_reference(&gref_tx_head, grant_tx_ref[id]);
             grant_tx_ref[id] = GRANT_INVALID_REF;
 #endif
@@ -448,7 +370,7 @@
             BUG();
         }
         grant_rx_ref[id] = ref;
-        gnttab_grant_foreign_transfer_ref(ref, rdomid,
+        gnttab_grant_foreign_transfer_ref(ref, np->backend_id,
                                           virt_to_mfn(skb->head));
         np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.gref = ref;
 #endif
@@ -544,7 +466,7 @@
         BUG();
     }
     mfn = virt_to_mfn(skb->data);
-    gnttab_grant_foreign_access_ref(ref, rdomid, mfn, GNTMAP_readonly);
+    gnttab_grant_foreign_access_ref(ref, np->backend_id, mfn, GNTMAP_readonly);
     tx->addr = ref << PAGE_SHIFT;
     grant_tx_ref[id] = ref;
 #else
@@ -650,7 +572,7 @@
 #ifdef CONFIG_XEN_NETDEV_GRANT_RX
         ref = grant_rx_ref[rx->id];
         grant_rx_ref[rx->id] = GRANT_INVALID_REF;
-        mfn = gnttab_end_foreign_transfer(ref);
+        mfn = gnttab_end_foreign_transfer_ref(ref);
         gnttab_release_grant_reference(&gref_rx_head, ref);
 #endif
 
@@ -809,7 +731,7 @@
 {
     struct net_private *np = netdev_priv(dev);
     np->user_state = UST_CLOSED;
-    netif_stop_queue(np->dev);
+    netif_stop_queue(np->netdev);
     return 0;
 }
 
@@ -821,8 +743,7 @@
 }
 
 
-static void network_connect(struct net_device *dev,
-                            netif_fe_interface_status_t *status)
+static void network_connect(struct net_device *dev)
 {
     struct net_private *np;
     int i, requeue_idx;
@@ -890,7 +811,7 @@
      */
     np->backend_state = BEST_CONNECTED;
     wmb();
-    notify_via_evtchn(status->evtchn);  
+    notify_via_evtchn(np->evtchn);  
     network_tx_buf_gc(dev);
 
     if (np->user_state == UST_OPEN)
@@ -900,148 +821,21 @@
     spin_unlock_irq(&np->tx_lock);
 }
 
-static void vif_show(struct net_private *np)
+static void show_device(struct net_private *np)
 {
 #ifdef DEBUG
-    if (np) {
-        IPRINTK("<vif handle=%u %s(%s) evtchn=%u tx=%p rx=%p>\n",
-               np->handle,
-               be_state_name[np->backend_state],
-               np->user_state ? "open" : "closed",
-               np->evtchn,
-               np->tx,
-               np->rx);
-    } else {
-        IPRINTK("<vif NULL>\n");
-    }
-#endif
-}
-
-/* Send a connect message to xend to tell it to bring up the interface. */
-static void send_interface_connect(struct net_private *np)
-{
-    int err;
-    ctrl_msg_t cmsg = {
-        .type    = CMSG_NETIF_FE,
-        .subtype = CMSG_NETIF_FE_INTERFACE_CONNECT,
-        .length  = sizeof(netif_fe_interface_connect_t),
-    };
-    netif_fe_interface_connect_t *msg = (void*)cmsg.msg;
-
-    msg->handle = np->handle;
-    msg->tx_shmem_frame = virt_to_mfn(np->tx);
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
-    err = gnttab_grant_foreign_access(rdomid, msg->tx_shmem_frame, 0);
-    if (err < 0) {
-        printk(KERN_ALERT "#### netfront can't grant access to tx_shmem\n");
-        BUG();
-    }
-    msg->tx_shmem_ref = err;
-#endif
-
-    msg->rx_shmem_frame = virt_to_mfn(np->rx);
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
-    err = gnttab_grant_foreign_access(rdomid, msg->rx_shmem_frame, 0);
-    if (err < 0) {
-        printk(KERN_ALERT "#### netfront can't grant access to rx_shmem\n");
-        BUG();
-    }
-    msg->rx_shmem_ref = err;
-#endif
-
-    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
-}
-
-/* Send a driver status notification to the domain controller. */
-static int send_driver_status(int ok)
-{
-    int err = 0;
-    ctrl_msg_t cmsg = {
-        .type    = CMSG_NETIF_FE,
-        .subtype = CMSG_NETIF_FE_DRIVER_STATUS,
-        .length  = sizeof(netif_fe_driver_status_t),
-    };
-    netif_fe_driver_status_t *msg = (void*)cmsg.msg;
-
-    msg->status = (ok ? NETIF_DRIVER_STATUS_UP : NETIF_DRIVER_STATUS_DOWN);
-    err = ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
-    return err;
-}
-
-/* Stop network device and free tx/rx queues and irq.
- */
-static void vif_release(struct net_private *np)
-{
-    /* Stop old i/f to prevent errors whilst we rebuild the state. */
-    spin_lock_irq(&np->tx_lock);
-    spin_lock(&np->rx_lock);
-    netif_stop_queue(np->dev);
-    /* np->backend_state = BEST_DISCONNECTED; */
-    spin_unlock(&np->rx_lock);
-    spin_unlock_irq(&np->tx_lock);
-    
-    /* Free resources. */
-    if ( np->tx != NULL )
-    {
-        unbind_evtchn_from_irqhandler(np->evtchn, np->dev);
-        free_page((unsigned long)np->tx);
-        free_page((unsigned long)np->rx);
-        np->evtchn = 0;
-        np->tx = NULL;
-        np->rx = NULL;
-    }
-}
-
-/* Release vif resources and close it down completely.
- */
-static void vif_close(struct net_private *np)
-{
-    WPRINTK("Unexpected netif-CLOSED message in state %s\n",
-            be_state_name[np->backend_state]);
-    vif_release(np);
-    np->backend_state = BEST_CLOSED;
-    /* todo: take dev down and free. */
-    vif_show(np);
-}
-
-/* Move the vif into disconnected state.
- * Allocates tx/rx pages.
- * Sends connect message to xend.
- */
-static void vif_disconnect(struct net_private *np)
-{
-    if(np->tx) free_page((unsigned long)np->tx);
-    if(np->rx) free_page((unsigned long)np->rx);
-    // Before this np->tx and np->rx had better be null.
-    np->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL);
-    np->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL);
-    memset(np->tx, 0, PAGE_SIZE);
-    memset(np->rx, 0, PAGE_SIZE);
-    np->backend_state = BEST_DISCONNECTED;
-    send_interface_connect(np);
-    vif_show(np);
-}
-
-/* Begin interface recovery.
- *
- * NB. Whilst we're recovering, we turn the carrier state off.  We
- * take measures to ensure that this device isn't used for
- * anything.  We also stop the queue for this device.  Various
- * different approaches (e.g. continuing to buffer packets) have
- * been tested but don't appear to improve the overall impact on
- * TCP connections.
- *
- * TODO: (MAW) Change the Xend<->Guest protocol so that a recovery
- * is initiated by a special "RESET" message - disconnect could
- * just mean we're not allowed to use this interface any more.
- */
-static void vif_reset(struct net_private *np)
-{
-    IPRINTK("Attempting to reconnect network interface: handle=%u\n",
-            np->handle);    
-    vif_release(np);
-    vif_disconnect(np);
-    vif_show(np);
+       if (np) {
+               IPRINTK("<vif handle=%u %s(%s) evtchn=%u tx=%p rx=%p>\n",
+                       np->handle,
+                       be_state_name[np->backend_state],
+                       np->user_state ? "open" : "closed",
+                       np->evtchn,
+                       np->tx,
+                       np->rx);
+       } else {
+               IPRINTK("<vif NULL>\n");
+       }
+#endif
 }
 
 /* Move the vif into connected state.
@@ -1049,26 +843,22 @@
  * Binds the irq to the event channel.
  */
 static void 
-vif_connect(struct net_private *np, netif_fe_interface_status_t *status)
-{
-    struct net_device *dev = np->dev;
-    memcpy(dev->dev_addr, status->mac, ETH_ALEN);
-    network_connect(dev, status);
-    np->evtchn = status->evtchn;
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
-    rdomid = status->domid;
-#endif
-    (void)bind_evtchn_to_irqhandler(
-        np->evtchn, netif_int, SA_SAMPLE_RANDOM, dev->name, dev);
-    netctrl_connected_count();
-    (void)send_fake_arp(dev);
-    vif_show(np);
+connect_device(struct net_private *np, unsigned int evtchn)
+{
+       struct net_device *dev = np->netdev;
+       memcpy(dev->dev_addr, np->mac, ETH_ALEN);
+       np->evtchn = evtchn;
+       network_connect(dev);
+       (void)bind_evtchn_to_irqhandler(
+               np->evtchn, netif_int, SA_SAMPLE_RANDOM, dev->name, dev);
+       (void)send_fake_arp(dev);
+       show_device(np);
 }
 
 static struct ethtool_ops network_ethtool_ops =
 {
-    .get_tx_csum = ethtool_op_get_tx_csum,
-    .set_tx_csum = ethtool_op_set_tx_csum,
+       .get_tx_csum = ethtool_op_get_tx_csum,
+       .set_tx_csum = ethtool_op_set_tx_csum,
 };
 
 /** Create a network device.
@@ -1076,22 +866,24 @@
  * @param val return parameter for created device
  * @return 0 on success, error code otherwise
  */
-static int create_netdev(int handle, struct net_device **val)
+static int create_netdev(int handle, struct xenbus_device *dev,
+                        struct net_device **val)
 {
     int i, err = 0;
-    struct net_device *dev = NULL;
+    struct net_device *netdev = NULL;
     struct net_private *np = NULL;
 
-    if ((dev = alloc_etherdev(sizeof(struct net_private))) == NULL) {
+    if ((netdev = alloc_etherdev(sizeof(struct net_private))) == NULL) {
         printk(KERN_WARNING "%s> alloc_etherdev failed.\n", __FUNCTION__);
         err = -ENOMEM;
         goto exit;
     }
 
-    np                = netdev_priv(dev);
+    np                = netdev_priv(netdev);
     np->backend_state = BEST_CLOSED;
     np->user_state    = UST_CLOSED;
     np->handle        = handle;
+    np->xbdev         = dev;
     
     spin_lock_init(&np->tx_lock);
     spin_lock_init(&np->rx_lock);
@@ -1115,268 +907,53 @@
 #endif
     }
 
-    dev->open            = network_open;
-    dev->hard_start_xmit = network_start_xmit;
-    dev->stop            = network_close;
-    dev->get_stats       = network_get_stats;
-    dev->poll            = netif_poll;
-    dev->weight          = 64;
-    dev->features        = NETIF_F_IP_CSUM;
-
-    SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
-
-    if ((err = register_netdev(dev)) != 0) {
+    netdev->open            = network_open;
+    netdev->hard_start_xmit = network_start_xmit;
+    netdev->stop            = network_close;
+    netdev->get_stats       = network_get_stats;
+    netdev->poll            = netif_poll;
+    netdev->weight          = 64;
+    netdev->features        = NETIF_F_IP_CSUM;
+
+    SET_ETHTOOL_OPS(netdev, &network_ethtool_ops);
+
+    if ((err = register_netdev(netdev)) != 0) {
         printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err);
         goto exit;
     }
 
-    if ((err = xennet_proc_addif(dev)) != 0) {
-        unregister_netdev(dev);
+    if ((err = xennet_proc_addif(netdev)) != 0) {
+        unregister_netdev(netdev);
         goto exit;
     }
 
-    np->dev = dev;
-    list_add(&np->list, &dev_list);
+    np->netdev = netdev;
 
   exit:
-    if ((err != 0) && (dev != NULL))
-        kfree(dev);
+    if ((err != 0) && (netdev != NULL))
+        kfree(netdev);
     else if (val != NULL)
-        *val = dev;
+        *val = netdev;
     return err;
 }
 
-/* Get the target interface for a status message.
- * Creates the interface when it makes sense.
- * The returned interface may be null when there is no error.
- *
- * @param status status message
- * @param np return parameter for interface state
- * @return 0 on success, error code otherwise
- */
-static int 
-target_vif(netif_fe_interface_status_t *status, struct net_private **np)
-{
-    int err = 0;
-    struct net_device *dev;
-
-    DPRINTK("> handle=%d\n", status->handle);
-    if (status->handle < 0) {
-        err = -EINVAL;
-        goto exit;
-    }
-
-    if ((dev = find_dev_by_handle(status->handle)) != NULL)
-        goto exit;
-
-    if (status->status == NETIF_INTERFACE_STATUS_CLOSED)
-        goto exit;
-    if (status->status == NETIF_INTERFACE_STATUS_CHANGED)
-        goto exit;
-
-    /* It's a new interface in a good state - create it. */
-    DPRINTK("> create device...\n");
-    if ((err = create_netdev(status->handle, &dev)) != 0)
-        goto exit;
-
-    netctrl.interface_n++;
-
-  exit:
-    if (np != NULL)
-        *np = ((dev && !err) ? netdev_priv(dev) : NULL);
-    DPRINTK("< err=%d\n", err);
-    return err;
-}
-
-/* Handle an interface status message. */
-static void netif_interface_status(netif_fe_interface_status_t *status)
-{
-    int err = 0;
-    struct net_private *np = NULL;
-    
-    DPRINTK("> status=%s handle=%d\n",
-            status_name[status->status], status->handle);
-
-    if ((err = target_vif(status, &np)) != 0) {
-        WPRINTK("Invalid netif: handle=%u\n", status->handle);
-        return;
-    }
-
-    if (np == NULL) {
-        DPRINTK("> no vif\n");
-        return;
-    }
-
-    switch (status->status) {
-    case NETIF_INTERFACE_STATUS_CLOSED:
-        switch (np->backend_state) {
-        case BEST_CLOSED:
-        case BEST_DISCONNECTED:
-        case BEST_CONNECTED:
-            vif_close(np);
-            break;
-        }
-        break;
-
-    case NETIF_INTERFACE_STATUS_DISCONNECTED:
-        switch (np->backend_state) {
-        case BEST_CLOSED:
-            vif_disconnect(np);
-            break;
-        case BEST_DISCONNECTED:
-        case BEST_CONNECTED:
-            vif_reset(np);
-            break;
-        }
-        break;
-
-    case NETIF_INTERFACE_STATUS_CONNECTED:
-        switch (np->backend_state) {
-        case BEST_CLOSED:
-            WPRINTK("Unexpected netif status %s in state %s\n",
-                    status_name[status->status],
-                    be_state_name[np->backend_state]);
-            vif_disconnect(np);
-            vif_connect(np, status);
-            break;
-        case BEST_DISCONNECTED:
-            vif_connect(np, status);
-            break;
-        }
-        break;
-
-    case NETIF_INTERFACE_STATUS_CHANGED:
-        /*
-         * The domain controller is notifying us that a device has been
-         * added or removed.
-         */
-        break;
-
-    default:
-        WPRINTK("Invalid netif status code %d\n", status->status);
-        break;
-    }
-
-    vif_show(np);
-}
-
-/*
- * Initialize the network control interface. 
- */
-static void netif_driver_status(netif_fe_driver_status_t *status)
-{
-    netctrl.up = status->status;
-    netctrl_connected_count();
-}
-
-/* Receive handler for control messages. */
-static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
-{
-
-    switch (msg->subtype) {
-    case CMSG_NETIF_FE_INTERFACE_STATUS:
-        netif_interface_status((netif_fe_interface_status_t *) &msg->msg[0]);
-        break;
-
-    case CMSG_NETIF_FE_DRIVER_STATUS:
-        netif_driver_status((netif_fe_driver_status_t *) &msg->msg[0]);
-        break;
-
-    default:
-        msg->length = 0;
-        break;
-    }
-
-    ctrl_if_send_response(msg);
-}
-
-
-#if 1
-/* Wait for all interfaces to be connected.
- *
- * This works OK, but we'd like to use the probing mode (see below).
- */
-static int probe_interfaces(void)
-{
-    int err = 0, conn = 0;
-    int wait_i, wait_n = 100;
-
-    DPRINTK(">\n");
-
-    for (wait_i = 0; wait_i < wait_n; wait_i++) { 
-        DPRINTK("> wait_i=%d\n", wait_i);
-        conn = netctrl_connected();
-        if(conn) break;
-        DPRINTK("> schedule_timeout...\n");
-        set_current_state(TASK_INTERRUPTIBLE);
-        schedule_timeout(10);
-    }
-
-    DPRINTK("> wait finished...\n");
-    if (conn <= 0) {
-        err = netctrl_err(-ENETDOWN);
-        WPRINTK("Failed to connect all virtual interfaces: err=%d\n", err);
-    }
-
-    DPRINTK("< err=%d\n", err);
-
-    return err;
-}
-#else
-/* Probe for interfaces until no more are found.
- *
- * This is the mode we'd like to use, but at the moment it panics the kernel.
-*/
-static int probe_interfaces(void)
-{
-    int err = 0;
-    int wait_i, wait_n = 100;
-    ctrl_msg_t cmsg = {
-        .type    = CMSG_NETIF_FE,
-        .subtype = CMSG_NETIF_FE_INTERFACE_STATUS,
-        .length  = sizeof(netif_fe_interface_status_t),
-    };
-    netif_fe_interface_status_t msg = {};
-    ctrl_msg_t rmsg = {};
-    netif_fe_interface_status_t *reply = (void*)rmsg.msg;
-    int state = TASK_UNINTERRUPTIBLE;
-    u32 query = -1;
-
-    DPRINTK(">\n");
-
-    netctrl.interface_n = 0;
-    for (wait_i = 0; wait_i < wait_n; wait_i++) { 
-        DPRINTK("> wait_i=%d query=%d\n", wait_i, query);
-        msg.handle = query;
-        memcpy(cmsg.msg, &msg, sizeof(msg));
-        DPRINTK("> set_current_state...\n");
-        set_current_state(state);
-        DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply);
-        DPRINTK("> sending...\n");
-        err = ctrl_if_send_message_and_get_response(&cmsg, &rmsg, state);
-        DPRINTK("> err=%d\n", err);
-        if(err) goto exit;
-        DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply);
-        if((int)reply->handle < 0) {
-            // No more interfaces.
-            break;
-        }
-        query = -reply->handle - 2;
-        DPRINTK(">netif_interface_status ...\n");
-        netif_interface_status(reply);
-    }
-
-  exit:
-    if (err) {
-        err = netctrl_err(-ENETDOWN);
-        WPRINTK("Connecting virtual network interfaces failed: err=%d\n", err);
-    }
-
-    DPRINTK("< err=%d\n", err);
-    return err;
-}
-
-#endif
+static int destroy_netdev(struct net_device *netdev)
+{
+       struct net_private *np = NULL;
+
+#ifdef CONFIG_PROC_FS
+       xennet_proc_delif(netdev);
+#endif
+
+        unregister_netdev(netdev);
+
+       np = netdev_priv(netdev);
+       list_del(&np->list);
+
+       kfree(netdev);
+
+       return 0;
+}
 
 /*
  * We use this notifier to send out a fake ARP reply to reset switches and
@@ -1387,19 +964,11 @@
 {
     struct in_ifaddr  *ifa = (struct in_ifaddr *)ptr; 
     struct net_device *dev = ifa->ifa_dev->dev;
-    struct list_head  *ent;
-    struct net_private *np;
-
-    if (event != NETDEV_UP)
-        goto out;
-
-    list_for_each (ent, &dev_list) {
-        np = list_entry(ent, struct net_private, list);
-        if (np->dev == dev)
-            (void)send_fake_arp(dev);
-    }
+
+    /* UP event and is it one of our devices? */
+    if (event == NETDEV_UP && dev->open == network_open)
+        (void)send_fake_arp(dev);
         
- out:
     return NOTIFY_DONE;
 }
 
@@ -1409,67 +978,310 @@
     .priority       = 0
 };
 
-static int __init netif_init(void)
-{
-    int err = 0;
-
-    if (xen_start_info.flags & SIF_INITDOMAIN)
-        return 0;
+static struct xenbus_device_id netfront_ids[] = {
+       { "vif" },
+       { "" }
+};
+
+static void watch_for_status(struct xenbus_watch *watch, const char *node)
+{
+}
+
+static int setup_device(struct xenbus_device *dev, struct netfront_info *info)
+{
+       evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
+       int err;
+
 #ifdef CONFIG_XEN_NETDEV_GRANT_TX
-    /* A grant for every ring slot */
-    if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE,
-                                      &gref_tx_head) < 0) {
-        printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
-        return 1;
-    }
-    printk(KERN_ALERT "Netdev frontend (TX) is using grant tables.\n"); 
+       info->tx_ring_ref = GRANT_INVALID_REF;
 #endif
 #ifdef CONFIG_XEN_NETDEV_GRANT_RX
-    /* A grant for every ring slot */
-    if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE,
-                                      &gref_rx_head) < 0) {
-        printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
-        return 1;
-    }
-    printk(KERN_ALERT "Netdev frontend (RX) is using grant tables.\n"); 
-#endif
-
-    if ((err = xennet_proc_init()) != 0)
-        return err;
-
-    IPRINTK("Initialising virtual ethernet driver.\n");
-    INIT_LIST_HEAD(&dev_list);
-    (void)register_inetaddr_notifier(&notifier_inetdev);
-    netctrl_init();
-    (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx,
-                                    CALLBACK_IN_BLOCKING_CONTEXT);
-    send_driver_status(1);
-    err = probe_interfaces();
-    if (err)
-        ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx);
-
-    DPRINTK("< err=%d\n", err);
-    return err;
-}
-
-static void netif_exit(void)
-{
+       info->rx_ring_ref = GRANT_INVALID_REF;
+#endif
+
+       info->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL);
+       if (info->tx == 0) {
+               err = -ENOMEM;
+               xenbus_dev_error(dev, err, "allocating tx ring page");
+               goto out;
+       }
+       info->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL);
+       if (info->rx == 0) {
+               err = -ENOMEM;
+               xenbus_dev_error(dev, err, "allocating rx ring page");
+               goto out;
+       }
+       memset(info->tx, 0, PAGE_SIZE);
+       memset(info->rx, 0, PAGE_SIZE);
+       info->backend_state = BEST_DISCONNECTED;
+
 #ifdef CONFIG_XEN_NETDEV_GRANT_TX
-    gnttab_free_grant_references(gref_tx_head);
-#endif
+       err = gnttab_grant_foreign_access(info->backend_id,
+                                         virt_to_mfn(info->tx), 0);
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "granting access to tx ring page");
+               goto out;
+       }
+       info->tx_ring_ref = err;
+#else
+       info->tx_ring_ref = virt_to_mfn(info->tx);
+#endif
+
 #ifdef CONFIG_XEN_NETDEV_GRANT_RX
-    gnttab_free_grant_references(gref_rx_head);
-#endif
-}
-
-static void vif_suspend(struct net_private *np)
-{
+       err = gnttab_grant_foreign_access(info->backend_id,
+                                         virt_to_mfn(info->rx), 0);
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "granting access to rx ring page");
+               goto out;
+       }
+       info->rx_ring_ref = err;
+#else
+       info->rx_ring_ref = virt_to_mfn(info->rx);
+#endif
+
+       op.u.alloc_unbound.dom = info->backend_id;
+       err = HYPERVISOR_event_channel_op(&op);
+       if (err) {
+               xenbus_dev_error(dev, err, "allocating event channel");
+               goto out;
+       }
+       connect_device(info, op.u.alloc_unbound.port);
+       return 0;
+
+ out:
+       if (info->tx)
+               free_page((unsigned long)info->tx);
+       info->tx = 0;
+       if (info->rx)
+               free_page((unsigned long)info->rx);
+       info->rx = 0;
+#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+       if (info->tx_ring_ref != GRANT_INVALID_REF)
+               gnttab_end_foreign_access(info->tx_ring_ref, 0);
+       info->tx_ring_ref = GRANT_INVALID_REF;
+#endif
+#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+       if (info->rx_ring_ref != GRANT_INVALID_REF)
+               gnttab_end_foreign_access(info->rx_ring_ref, 0);
+       info->rx_ring_ref = GRANT_INVALID_REF;
+#endif
+       return err;
+}
+
+static void netif_free(struct netfront_info *info)
+{
+       if (info->tx)
+               free_page((unsigned long)info->tx);
+       info->tx = 0;
+       if (info->rx)
+               free_page((unsigned long)info->rx);
+       info->rx = 0;
+#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+       if (info->tx_ring_ref != GRANT_INVALID_REF)
+               gnttab_end_foreign_access(info->tx_ring_ref, 0);
+       info->tx_ring_ref = GRANT_INVALID_REF;
+#endif
+#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+       if (info->rx_ring_ref != GRANT_INVALID_REF)
+               gnttab_end_foreign_access(info->rx_ring_ref, 0);
+       info->rx_ring_ref = GRANT_INVALID_REF;
+#endif
+       unbind_evtchn_from_irqhandler(info->evtchn, info->netdev);
+       info->evtchn = 0;
+}
+
+/* Stop network device and free tx/rx queues and irq.
+ */
+static void shutdown_device(struct net_private *np)
+{
+       /* Stop old i/f to prevent errors whilst we rebuild the state. */
+       spin_lock_irq(&np->tx_lock);
+       spin_lock(&np->rx_lock);
+       netif_stop_queue(np->netdev);
+       /* np->backend_state = BEST_DISCONNECTED; */
+       spin_unlock(&np->rx_lock);
+       spin_unlock_irq(&np->tx_lock);
+    
+       /* Free resources. */
+       netif_free(np);
+}
+
+/* Common code used when first setting up, and when resuming. */
+static int talk_to_backend(struct xenbus_device *dev,
+                          struct netfront_info *info)
+{
+       char *backend, *mac, *e, *s;
+       const char *message;
+       int err, i;
+
+       backend = NULL;
+       err = xenbus_gather(dev->nodename,
+                           "backend-id", "%i", &info->backend_id,
+                           "backend", NULL, &backend,
+                           NULL);
+       if (XENBUS_EXIST_ERR(err))
+               goto out;
+       if (backend && strlen(backend) == 0) {
+               err = -ENOENT;
+               goto out;
+       }
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "reading %s/backend or backend-id",
+                                dev->nodename);
+               goto out;
+       }
+
+       mac = xenbus_read(dev->nodename, "mac", NULL);
+       if (IS_ERR(mac)) {
+               err = PTR_ERR(mac);
+               xenbus_dev_error(dev, err, "reading %s/mac",
+                                dev->nodename);
+               goto out;
+       }
+       s = mac;
+       for (i = 0; i < ETH_ALEN; i++) {
+               info->mac[i] = simple_strtoul(s, &e, 16);
+               if (s == e || (e[0] != ':' && e[0] != 0)) {
+                       kfree(mac);
+                       err = -ENOENT;
+                       xenbus_dev_error(dev, err, "parsing %s/mac",
+                                        dev->nodename);
+                       goto out;
+               }
+               s = &e[1];
+       }
+       kfree(mac);
+
+       /* Create shared ring, alloc event channel. */
+       err = setup_device(dev, info);
+       if (err) {
+               xenbus_dev_error(dev, err, "setting up ring");
+               goto out;
+       }
+
+       err = xenbus_transaction_start(dev->nodename);
+       if (err) {
+               xenbus_dev_error(dev, err, "starting transaction");
+               goto destroy_ring;
+       }
+
+       err = xenbus_printf(dev->nodename, "tx-ring-ref","%u",
+                           info->tx_ring_ref);
+       if (err) {
+               message = "writing tx ring-ref";
+               goto abort_transaction;
+       }
+       err = xenbus_printf(dev->nodename, "rx-ring-ref","%u",
+                           info->rx_ring_ref);
+       if (err) {
+               message = "writing rx ring-ref";
+               goto abort_transaction;
+       }
+       err = xenbus_printf(dev->nodename,
+                           "event-channel", "%u", info->evtchn);
+       if (err) {
+               message = "writing event-channel";
+               goto abort_transaction;
+       }
+
+       info->backend = backend;
+       backend = NULL;
+
+       info->watch.node = info->backend;
+       info->watch.callback = watch_for_status;
+       err = register_xenbus_watch(&info->watch);
+       if (err) {
+               message = "registering watch on backend";
+               goto abort_transaction;
+       }
+
+       err = xenbus_transaction_end(0);
+       if (err) {
+               xenbus_dev_error(dev, err, "completing transaction");
+               goto destroy_ring;
+       }
+
+       netif_state = NETIF_STATE_CONNECTED;
+
+ out:
+       if (backend)
+               kfree(backend);
+       return err;
+
+ abort_transaction:
+       xenbus_transaction_end(1);
+       /* Have to do this *outside* transaction.  */
+       xenbus_dev_error(dev, err, "%s", message);
+ destroy_ring:
+       shutdown_device(info);
+       goto out;
+}
+
+/* Setup supplies the backend dir, virtual device.
+
+   We place an event channel and shared frame entries.
+   We watch backend to wait if it's ok. */
+static int netfront_probe(struct xenbus_device *dev,
+                         const struct xenbus_device_id *id)
+{
+       int err;
+       struct net_device *netdev;
+       struct netfront_info *info;
+       unsigned int handle;
+
+       err = xenbus_scanf(dev->nodename, "handle", "%u", &handle);
+       if (XENBUS_EXIST_ERR(err))
+               return err;
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "reading handle");
+               return err;
+       }
+
+       err = create_netdev(handle, dev, &netdev);
+       if (err) {
+               xenbus_dev_error(dev, err, "creating netdev");
+               return err;
+       }
+
+       info = netdev_priv(netdev);
+       err = talk_to_backend(dev, info);
+       if (err) {
+               destroy_netdev(netdev);
+               return err;
+       }
+
+       /* Call once in case entries already there. */
+       watch_for_status(&info->watch, info->watch.node);
+
+       return 0;
+}
+
+static int netfront_remove(struct xenbus_device *dev)
+{
+       struct netfront_info *info = dev->data;
+
+       if (info->backend)
+               unregister_xenbus_watch(&info->watch);
+
+       netif_free(info);
+
+       kfree(info->backend);
+       kfree(info);
+
+       return 0;
+}
+
+static int netfront_suspend(struct xenbus_device *dev)
+{
+    struct net_private *np = dev->data;
     /* Avoid having tx/rx stuff happen until we're ready. */
-    unbind_evtchn_from_irqhandler(np->evtchn, np->dev);
-}
-
-static void vif_resume(struct net_private *np)
-{
+    unbind_evtchn_from_irqhandler(np->evtchn, np->netdev);
+    return 0;
+}
+
+static int netfront_resume(struct xenbus_device *dev)
+{
+    struct net_private *np = dev->data;
     /*
      * Connect regardless of whether IFF_UP flag set.
      * Stop bad things from happening until we're back up.
@@ -1478,29 +1290,96 @@
     memset(np->tx, 0, PAGE_SIZE);
     memset(np->rx, 0, PAGE_SIZE);
     
-    send_interface_connect(np);
-}
-
-void netif_suspend(void)
-{
-    struct list_head *ent;
-    struct net_private *np;
-    
-    list_for_each (ent, &dev_list) {
-        np = list_entry(ent, struct net_private, list);
-        vif_suspend(np);
-    }
-}
-
-void netif_resume(void)
-{
-    struct list_head *ent;
-    struct net_private *np;
-
-    list_for_each (ent, &dev_list) {
-        np = list_entry(ent, struct net_private, list);
-        vif_resume(np);
-    }
+    // send_interface_connect(np);
+    return 0;
+}
+
+static struct xenbus_driver netfront = {
+       .name = "vif",
+       .owner = THIS_MODULE,
+       .ids = netfront_ids,
+       .probe = netfront_probe,
+       .remove = netfront_remove,
+       .resume = netfront_resume,
+       .suspend = netfront_suspend,
+};
+
+static void __init init_net_xenbus(void)
+{
+       xenbus_register_device(&netfront);
+}
+
+static int wait_for_netif(void)
+{
+    int err = 0;
+    int i;
+
+    /*
+     * We should figure out how many and which devices we need to
+     * proceed and only wait for those.  For now, continue once the
+     * first device is around.
+     */
+    for ( i=0; netif_state != NETIF_STATE_CONNECTED && (i < 10*HZ); i++ )
+    {
+        set_current_state(TASK_INTERRUPTIBLE);
+        schedule_timeout(1);
+    }
+
+    if (netif_state != NETIF_STATE_CONNECTED) {
+        WPRINTK("Timeout connecting to device!\n");
+        err = -ENOSYS;
+    }
+    return err;
+}
+
+static int __init netif_init(void)
+{
+    int err = 0;
+
+    if (xen_start_info.flags & SIF_INITDOMAIN)
+        return 0;
+
+#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+    /* A grant for every ring slot */
+    if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE,
+                                      &gref_tx_head) < 0) {
+        printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
+        return 1;
+    }
+    printk(KERN_ALERT "Netdev frontend (TX) is using grant tables.\n"); 
+#endif
+#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+    /* A grant for every ring slot */
+    if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE,
+                                      &gref_rx_head) < 0) {
+        printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
+        return 1;
+    }
+    printk(KERN_ALERT "Netdev frontend (RX) is using grant tables.\n"); 
+#endif
+
+    if ((err = xennet_proc_init()) != 0)
+        return err;
+
+    IPRINTK("Initialising virtual ethernet driver.\n");
+
+    (void)register_inetaddr_notifier(&notifier_inetdev);
+
+    init_net_xenbus();
+
+    wait_for_netif();
+
+    return err;
+}
+
+static void netif_exit(void)
+{
+#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+    gnttab_free_grant_references(gref_tx_head);
+#endif
+#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+    gnttab_free_grant_references(gref_rx_head);
+#endif
 }
 
 #ifdef CONFIG_PROC_FS
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h      Wed Aug 24 
23:16:52 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h      Thu Aug 25 
18:18:47 2005
@@ -65,8 +65,26 @@
 extern unsigned int *phys_to_machine_mapping;
 #define pfn_to_mfn(pfn)        \
 ((unsigned long)phys_to_machine_mapping[(unsigned int)(pfn)] & 0x7FFFFFFFUL)
-#define mfn_to_pfn(mfn)        \
-((unsigned long)machine_to_phys_mapping[(unsigned int)(mfn)])
+static inline unsigned long mfn_to_pfn(unsigned long mfn)
+{
+       unsigned int pfn;
+
+       /*
+        * The array access can fail (e.g., device space beyond end of RAM).
+        * In such cases it doesn't matter what we return (we return garbage),
+        * but we must handle the fault without crashing!
+        */
+       asm (
+               "1:     movl %1,%0\n"
+               "2:\n"
+               ".section __ex_table,\"a\"\n"
+               "       .align 4\n"
+               "       .long 1b,2b\n"
+               ".previous"
+               : "=r" (pfn) : "m" (machine_to_phys_mapping[mfn]) );
+
+       return (unsigned long)pfn;
+}
 
 /* Definitions for machine and pseudophysical addresses. */
 #ifdef CONFIG_X86_PAE
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h    Wed Aug 24 
23:16:52 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h    Thu Aug 25 
18:18:47 2005
@@ -67,8 +67,26 @@
 extern u32 *phys_to_machine_mapping;
 #define pfn_to_mfn(pfn)        \
 ((unsigned long)phys_to_machine_mapping[(unsigned int)(pfn)] & 0x7FFFFFFFUL)
-#define mfn_to_pfn(mfn)        \
-((unsigned long)machine_to_phys_mapping[(unsigned int)(mfn)])
+static inline unsigned long mfn_to_pfn(unsigned long mfn)
+{
+       unsigned int pfn;
+
+       /*
+        * The array access can fail (e.g., device space beyond end of RAM).
+        * In such cases it doesn't matter what we return (we return garbage),
+        * but we must handle the fault without crashing!
+        */
+       asm (
+               "1:     movl %1,%k0\n"
+               "2:\n"
+               ".section __ex_table,\"a\"\n"
+               "       .align 8\n"
+               "       .quad 1b,2b\n"
+               ".previous"
+               : "=r" (pfn) : "m" (machine_to_phys_mapping[mfn]) );
+
+       return (unsigned long)pfn;
+}
 
 /* Definitions for machine and pseudophysical addresses. */
 typedef unsigned long paddr_t;
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/include/asm-xen/gnttab.h
--- a/linux-2.6-xen-sparse/include/asm-xen/gnttab.h     Wed Aug 24 23:16:52 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/gnttab.h     Thu Aug 25 18:18:47 2005
@@ -30,10 +30,12 @@
 int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
                                int readonly);
 
+void gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly);
 void gnttab_end_foreign_access(grant_ref_t ref, int readonly);
 
 int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn);
 
+unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref);
 unsigned long gnttab_end_foreign_transfer(grant_ref_t ref);
 
 int gnttab_query_foreign_access(grant_ref_t ref);
diff -r e2025593f702 -r 112d44270733 tools/blktap/blktaplib.h
--- a/tools/blktap/blktaplib.h  Wed Aug 24 23:16:52 2005
+++ b/tools/blktap/blktaplib.h  Thu Aug 25 18:18:47 2005
@@ -7,7 +7,7 @@
 #ifndef __BLKTAPLIB_H__
 #define __BLKTAPLIB_H__
 
-#include <xc.h>
+#include <xenctrl.h>
 #include <sys/user.h>
 #include <xen/xen.h>
 #include <xen/io/blkif.h>
diff -r e2025593f702 -r 112d44270733 tools/blktap/parallax/block-async.h
--- a/tools/blktap/parallax/block-async.h       Wed Aug 24 23:16:52 2005
+++ b/tools/blktap/parallax/block-async.h       Thu Aug 25 18:18:47 2005
@@ -7,7 +7,7 @@
 #define _BLOCKASYNC_H_
 
 #include <assert.h>
-#include <xc.h>
+#include <xenctrl.h>
 #include "vdi.h"
 
 struct io_ret
diff -r e2025593f702 -r 112d44270733 tools/blktap/parallax/blockstore.h
--- a/tools/blktap/parallax/blockstore.h        Wed Aug 24 23:16:52 2005
+++ b/tools/blktap/parallax/blockstore.h        Thu Aug 25 18:18:47 2005
@@ -10,7 +10,7 @@
 #define __BLOCKSTORE_H__
 
 #include <netinet/in.h>
-#include <xc.h>
+#include <xenctrl.h>
 
 #define BLOCK_SIZE  4096
 #define BLOCK_SHIFT   12
diff -r e2025593f702 -r 112d44270733 tools/console/Makefile
--- a/tools/console/Makefile    Wed Aug 24 23:16:52 2005
+++ b/tools/console/Makefile    Thu Aug 25 18:18:47 2005
@@ -26,11 +26,11 @@
 
 xenconsoled: $(patsubst %.c,%.o,$(wildcard daemon/*.c))
        $(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -L$(XEN_XENSTORE) \
-              -lxc -lxenstore
+              -lxenctrl -lxenstore
 
 xenconsole: $(patsubst %.c,%.o,$(wildcard client/*.c))
        $(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -L$(XEN_XENSTORE) \
-             -lxc -lxenstore
+             -lxenctrl -lxenstore
 
 install: $(BIN)
        $(INSTALL_DIR) -p $(DESTDIR)/$(DAEMON_INSTALL_DIR)
diff -r e2025593f702 -r 112d44270733 tools/console/client/main.c
--- a/tools/console/client/main.c       Wed Aug 24 23:16:52 2005
+++ b/tools/console/client/main.c       Thu Aug 25 18:18:47 2005
@@ -36,7 +36,7 @@
 #include <errno.h>
 #include <pty.h>
 
-#include "xc.h"
+#include "xenctrl.h"
 #include "xs.h"
 
 #define ESCAPE_CHARACTER 0x1d
diff -r e2025593f702 -r 112d44270733 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Wed Aug 24 23:16:52 2005
+++ b/tools/console/daemon/io.c Thu Aug 25 18:18:47 2005
@@ -23,7 +23,7 @@
 #include "utils.h"
 #include "io.h"
 
-#include "xc.h"
+#include "xenctrl.h"
 #include "xs.h"
 #include "xen/io/domain_controller.h"
 #include "xcs_proto.h"
diff -r e2025593f702 -r 112d44270733 tools/console/daemon/main.c
--- a/tools/console/daemon/main.c       Wed Aug 24 23:16:52 2005
+++ b/tools/console/daemon/main.c       Thu Aug 25 18:18:47 2005
@@ -25,7 +25,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 
-#include "xc.h"
+#include "xenctrl.h"
 #include "xen/io/domain_controller.h"
 #include "xcs_proto.h"
 
diff -r e2025593f702 -r 112d44270733 tools/console/daemon/utils.c
--- a/tools/console/daemon/utils.c      Wed Aug 24 23:16:52 2005
+++ b/tools/console/daemon/utils.c      Thu Aug 25 18:18:47 2005
@@ -33,7 +33,7 @@
 #include <sys/un.h>
 #include <string.h>
 
-#include "xc.h"
+#include "xenctrl.h"
 #include "xen/io/domain_controller.h"
 #include "xcs_proto.h"
 
diff -r e2025593f702 -r 112d44270733 
tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
--- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c     
Wed Aug 24 23:16:52 2005
+++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c     
Thu Aug 25 18:18:47 2005
@@ -35,7 +35,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
-#include <xc.h>
+#include <xenctrl.h>
 #define TRACE_ENTER /* printf("enter %s\n", __FUNCTION__) */
 long (*myptrace)(enum __ptrace_request, pid_t, long, long);
 int (*myxcwait)(int domain, int *status, int options) ;
diff -r e2025593f702 -r 112d44270733 tools/debugger/libxendebug/Makefile
--- a/tools/debugger/libxendebug/Makefile       Wed Aug 24 23:16:52 2005
+++ b/tools/debugger/libxendebug/Makefile       Thu Aug 25 18:18:47 2005
@@ -20,7 +20,7 @@
 CFLAGS   += -Wp,-MD,.$(@F).d
 DEPS     = .*.d
 
-LDFLAGS  += -L$(XEN_ROOT)/tools/libxc -lxc
+LDFLAGS  += -L$(XEN_ROOT)/tools/libxc -lxenctrl
 
 LIB_OBJS := $(patsubst %.c,%.o,$(SRCS))
 PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS))
diff -r e2025593f702 -r 112d44270733 tools/debugger/libxendebug/xendebug.c
--- a/tools/debugger/libxendebug/xendebug.c     Wed Aug 24 23:16:52 2005
+++ b/tools/debugger/libxendebug/xendebug.c     Thu Aug 25 18:18:47 2005
@@ -12,7 +12,7 @@
 #include <string.h>
 #include <errno.h>
 #include <sys/mman.h>
-#include <xc.h>
+#include <xenctrl.h>
 #include "list.h"
 
 #if defined(__i386__)
diff -r e2025593f702 -r 112d44270733 tools/debugger/libxendebug/xendebug.h
--- a/tools/debugger/libxendebug/xendebug.h     Wed Aug 24 23:16:52 2005
+++ b/tools/debugger/libxendebug/xendebug.h     Thu Aug 25 18:18:47 2005
@@ -9,7 +9,7 @@
 #ifndef _XENDEBUG_H_DEFINED
 #define _XENDEBUG_H_DEFINED
 
-#include <xc.h>
+#include <xenctrl.h>
 
 int xendebug_attach(int xc_handle,
                    u32 domid,
diff -r e2025593f702 -r 112d44270733 tools/debugger/pdb/pdb_caml_domain.c
--- a/tools/debugger/pdb/pdb_caml_domain.c      Wed Aug 24 23:16:52 2005
+++ b/tools/debugger/pdb/pdb_caml_domain.c      Thu Aug 25 18:18:47 2005
@@ -6,7 +6,7 @@
  * PDB's OCaml interface library for debugging domains
  */
 
-#include <xc.h>
+#include <xenctrl.h>
 #include <xendebug.h>
 #include <errno.h>
 #include <stdio.h>
diff -r e2025593f702 -r 112d44270733 tools/debugger/pdb/pdb_caml_evtchn.c
--- a/tools/debugger/pdb/pdb_caml_evtchn.c      Wed Aug 24 23:16:52 2005
+++ b/tools/debugger/pdb/pdb_caml_evtchn.c      Thu Aug 25 18:18:47 2005
@@ -6,7 +6,7 @@
  * PDB's OCaml interface library for event channels
  */
 
-#include <xc.h>
+#include <xenctrl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
diff -r e2025593f702 -r 112d44270733 tools/debugger/pdb/pdb_caml_process.c
--- a/tools/debugger/pdb/pdb_caml_process.c     Wed Aug 24 23:16:52 2005
+++ b/tools/debugger/pdb/pdb_caml_process.c     Thu Aug 25 18:18:47 2005
@@ -15,7 +15,7 @@
 #include <caml/memory.h>
 #include <caml/mlvalues.h>
 
-#include <xc.h>
+#include <xenctrl.h>
 #include <xen/xen.h>
 #include <xen/io/domain_controller.h>
 #include <xen/linux/privcmd.h>
diff -r e2025593f702 -r 112d44270733 tools/debugger/pdb/pdb_caml_xc.c
--- a/tools/debugger/pdb/pdb_caml_xc.c  Wed Aug 24 23:16:52 2005
+++ b/tools/debugger/pdb/pdb_caml_xc.c  Thu Aug 25 18:18:47 2005
@@ -6,7 +6,7 @@
  * PDB's OCaml interface library for debugging domains
  */
 
-#include <xc.h>
+#include <xenctrl.h>
 #include <xendebug.h>
 #include <errno.h>
 #include <stdio.h>
diff -r e2025593f702 -r 112d44270733 tools/debugger/pdb/pdb_caml_xcs.c
--- a/tools/debugger/pdb/pdb_caml_xcs.c Wed Aug 24 23:16:52 2005
+++ b/tools/debugger/pdb/pdb_caml_xcs.c Thu Aug 25 18:18:47 2005
@@ -17,7 +17,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <errno.h>
-#include <xc.h>
+#include <xenctrl.h>
 
 #include <xen/xen.h>
 #include <xen/io/domain_controller.h>
diff -r e2025593f702 -r 112d44270733 tools/debugger/pdb/pdb_xen.c
--- a/tools/debugger/pdb/pdb_xen.c      Wed Aug 24 23:16:52 2005
+++ b/tools/debugger/pdb/pdb_xen.c      Thu Aug 25 18:18:47 2005
@@ -7,7 +7,7 @@
  * PDB interface library for accessing Xen
  */
 
-#include <xc.h>
+#include <xenctrl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
diff -r e2025593f702 -r 112d44270733 tools/examples/Makefile
--- a/tools/examples/Makefile   Wed Aug 24 23:16:52 2005
+++ b/tools/examples/Makefile   Thu Aug 25 18:18:47 2005
@@ -24,10 +24,14 @@
 XEN_BOOT_DIR = /usr/lib/xen/boot
 XEN_BOOT = mem-map.sxp
 
+XEN_HOTPLUG_DIR = /etc/hotplug.d/xen-backend
+XEN_HOTPLUG_SCRIPTS = backend.hotplug
+
 all: 
 build:
 
-install: all install-initd install-configs install-scripts install-boot
+install: all install-initd install-configs install-scripts install-boot \
+        install-hotplug
 
 install-initd:
        [ -d $(DESTDIR)/etc/init.d ] || $(INSTALL_DIR) $(DESTDIR)/etc/init.d
@@ -60,4 +64,12 @@
            $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_BOOT_DIR); \
        done
 
+install-hotplug:
+       [ -d $(DESTDIR)$(XEN_HOTPLUG_DIR) ] || \
+               $(INSTALL_DIR) $(DESTDIR)$(XEN_HOTPLUG_DIR)
+       for i in $(XEN_HOTPLUG_SCRIPTS); \
+           do [ -a $(DESTDIR)$(XEN_HOTPLUG_DIR)/$$i ] || \
+           $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_HOTPLUG_DIR); \
+       done
+
 clean:
diff -r e2025593f702 -r 112d44270733 tools/examples/README
--- a/tools/examples/README     Wed Aug 24 23:16:52 2005
+++ b/tools/examples/README     Thu Aug 25 18:18:47 2005
@@ -9,9 +9,20 @@
 send it (preferably with a little summary to go in this file) to
 <xen-devel@xxxxxxxxxxxxxxxxxxxxx> so we can add it to this directory.
 
+block-enbd          - binds/unbinds network block devices
+block-file          - binds/unbinds file to loopback device
+mem-map.sxp         - memory map xend configuration file.
 network             - default network setup script called by xend at startup.
+network-route       - default xen network start/stop script.
+network-nat         - default xen network start/stop script when using NAT.
 vif-bridge          - default virtual network interface setup script.
+vif-route           - default xen virtual network start/stop script
+vif-nat             - configures vif in routed-nat mode.
 xend-config.sxp     - default xend configuration file.
 xmexample1          - example configuration script for 'xm create'.
 xmexample2          - a more complex configuration script for 'xm create'.
+xmexample3          - an advanced configuration script for 'xm create' 
+                      that utilizes the vmid.
+xmexample.vmx       - a configuration script for creating a vmx domain with
+                      'xm create'.
 
diff -r e2025593f702 -r 112d44270733 tools/examples/vif-bridge
--- a/tools/examples/vif-bridge Wed Aug 24 23:16:52 2005
+++ b/tools/examples/vif-bridge Thu Aug 25 18:18:47 2005
@@ -74,8 +74,10 @@
     exit
 fi
 
-# Add/remove vif to/from bridge.
-brctl ${brcmd} ${bridge} ${vif}
+# Add vif to bridge. vifs are auto-removed from bridge.
+if [ "${brcmd}" == "addif" ] ; then
+    brctl ${brcmd} ${bridge} ${vif}
+fi
 ifconfig ${vif} $OP
 
 if [ ${ip} ] ; then
diff -r e2025593f702 -r 112d44270733 tools/firmware/acpi/acpi2_0.h
--- a/tools/firmware/acpi/acpi2_0.h     Wed Aug 24 23:16:52 2005
+++ b/tools/firmware/acpi/acpi2_0.h     Thu Aug 25 18:18:47 2005
@@ -18,7 +18,7 @@
 #ifndef _ACPI_2_0_H_
 #define _ACPI_2_0_H_
 
-#include "xc.h"  // for u8, u16, u32, u64 definition
+#include "xenctrl.h"  // for u8, u16, u32, u64 definition
 
 #pragma pack (1)
 
diff -r e2025593f702 -r 112d44270733 tools/ioemu/hw/i8254.c
--- a/tools/ioemu/hw/i8254.c    Wed Aug 24 23:16:52 2005
+++ b/tools/ioemu/hw/i8254.c    Thu Aug 25 18:18:47 2005
@@ -22,7 +22,7 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
-#include "xc.h"
+#include "xenctrl.h"
 #include <io/ioreq.h>
 
 //#define DEBUG_PIT
diff -r e2025593f702 -r 112d44270733 tools/ioemu/hw/i8259.c
--- a/tools/ioemu/hw/i8259.c    Wed Aug 24 23:16:52 2005
+++ b/tools/ioemu/hw/i8259.c    Thu Aug 25 18:18:47 2005
@@ -22,7 +22,7 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
-#include "xc.h"
+#include "xenctrl.h"
 #include <io/ioreq.h>
 
 /* debug PIC */
diff -r e2025593f702 -r 112d44270733 tools/ioemu/hw/ioapic.h
--- a/tools/ioemu/hw/ioapic.h   Wed Aug 24 23:16:52 2005
+++ b/tools/ioemu/hw/ioapic.h   Thu Aug 25 18:18:47 2005
@@ -26,7 +26,7 @@
 #ifndef __IOAPIC_H
 #define __IOAPIC_H
 
-#include "xc.h"
+#include "xenctrl.h"
 #include <io/ioreq.h>
 #include <io/vmx_vlapic.h>
 
diff -r e2025593f702 -r 112d44270733 tools/ioemu/target-i386-dm/Makefile
--- a/tools/ioemu/target-i386-dm/Makefile       Wed Aug 24 23:16:52 2005
+++ b/tools/ioemu/target-i386-dm/Makefile       Thu Aug 25 18:18:47 2005
@@ -188,7 +188,7 @@
 #########################################################
 
 DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE 
-DAPIC_SUPPORT
-LIBS+=-lm -L../../libxc -lxc
+LIBS+=-lm -L../../libxc -lxenctrl
 ifndef CONFIG_USER_ONLY
 LIBS+=-lz
 endif
diff -r e2025593f702 -r 112d44270733 tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c      Wed Aug 24 23:16:52 2005
+++ b/tools/ioemu/target-i386-dm/helper2.c      Thu Aug 25 18:18:47 2005
@@ -47,7 +47,7 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 
-#include "xc.h"
+#include "xenctrl.h"
 #include <io/ioreq.h>
 
 #include "cpu.h"
diff -r e2025593f702 -r 112d44270733 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Wed Aug 24 23:16:52 2005
+++ b/tools/ioemu/vl.c  Thu Aug 25 18:18:47 2005
@@ -72,7 +72,7 @@
 #endif
 #endif /* CONFIG_SDL */
 
-#include "xc.h"
+#include "xenctrl.h"
 #include "exec-all.h"
 
 //#define DO_TB_FLUSH
diff -r e2025593f702 -r 112d44270733 tools/libxc/Makefile
--- a/tools/libxc/Makefile      Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/Makefile      Thu Aug 25 18:18:47 2005
@@ -12,28 +12,32 @@
 XEN_ROOT = ../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-SRCS     :=
-SRCS     += xc_sedf.c
-SRCS     += xc_bvtsched.c
-SRCS     += xc_core.c
-SRCS     += xc_domain.c
-SRCS     += xc_evtchn.c
-SRCS     += xc_gnttab.c
-SRCS     += xc_load_bin.c
-SRCS     += xc_load_elf.c
-SRCS     += xc_linux_build.c
-SRCS     += xc_misc.c
-SRCS     += xc_physdev.c
-SRCS     += xc_private.c
+SRCS       :=
+BUILD_SRCS :=
+SRCS       += xc_bvtsched.c
+SRCS       += xc_core.c
+SRCS       += xc_domain.c
+SRCS       += xc_evtchn.c
+SRCS       += xc_gnttab.c
+SRCS       += xc_misc.c
+SRCS       += xc_physdev.c
+SRCS       += xc_private.c
+SRCS       += xc_sedf.c
+
 ifeq ($(XEN_TARGET_ARCH),ia64)
-SRCS     += xc_ia64_stubs.c
+BUILD_SRCS += xc_ia64_stubs.c
 else
-SRCS     += xc_load_aout9.c
-SRCS     += xc_linux_restore.c
-SRCS     += xc_linux_save.c
-SRCS     += xc_vmx_build.c
-SRCS     += xc_ptrace.c
-SRCS     += xc_ptrace_core.c
+SRCS       += xc_ptrace.c
+SRCS       += xc_ptrace_core.c
+
+BUILD_SRCS := xc_load_aout9.c
+BUILD_SRCS += xc_load_bin.c
+BUILD_SRCS += xc_load_elf.c
+BUILD_SRCS += xc_linux_build.c
+BUILD_SRCS += xc_linux_restore.c
+BUILD_SRCS += xc_linux_save.c
+BUILD_SRCS += xc_vmx_build.c
+BUILD_SRCS += xg_private.c
 endif
 
 CFLAGS   += -Wall
@@ -43,13 +47,20 @@
 CFLAGS   += $(INCLUDES) -I.
 # Get gcc to generate the dependencies for us.
 CFLAGS   += -Wp,-MD,.$(@F).d
+LDFLAGS  += -L.
 DEPS     = .*.d
 
 LIB_OBJS := $(patsubst %.c,%.o,$(SRCS))
 PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS))
 
-LIB      := libxc.a libxc-pic.a
-LIB      += libxc.so libxc.so.$(MAJOR) libxc.so.$(MAJOR).$(MINOR)
+LIB_BUILD_OBJS := $(patsubst %.c,%.o,$(BUILD_SRCS))
+PIC_BUILD_OBJS := $(patsubst %.c,%.opic,$(BUILD_SRCS))
+
+LIB := libxenctrl.a
+LIB += libxenctrl.so libxenctrl.so.$(MAJOR) libxenctrl.so.$(MAJOR).$(MINOR)
+
+LIB += libxenguest.a
+LIB += libxenguest.so libxenguest.so.$(MAJOR) libxenguest.so.$(MAJOR).$(MINOR)
 
 all: build
 build: check-for-zlib mk-symlinks
@@ -77,11 +88,16 @@
 install: build
        [ -d $(DESTDIR)/usr/$(LIBDIR) ] || $(INSTALL_DIR) 
$(DESTDIR)/usr/$(LIBDIR)
        [ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include
-       $(INSTALL_PROG) libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)
-       $(INSTALL_DATA) libxc.a $(DESTDIR)/usr/$(LIBDIR)
-       ln -sf libxc.so.$(MAJOR).$(MINOR) 
$(DESTDIR)/usr/$(LIBDIR)/libxc.so.$(MAJOR)
-       ln -sf libxc.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libxc.so
-       $(INSTALL_DATA) xc.h $(DESTDIR)/usr/include
+       $(INSTALL_PROG) libxenctrl.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)
+       $(INSTALL_DATA) libxenctrl.a $(DESTDIR)/usr/$(LIBDIR)
+       ln -sf libxenctrl.so.$(MAJOR).$(MINOR) 
$(DESTDIR)/usr/$(LIBDIR)/libxenctrl.so.$(MAJOR)
+       ln -sf libxenctrl.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libxenctrl.so
+       $(INSTALL_DATA) xenctrl.h $(DESTDIR)/usr/include
+
+       $(INSTALL_PROG) libxenguest.so.$(MAJOR).$(MINOR) 
$(DESTDIR)/usr/$(LIBDIR)
+       $(INSTALL_DATA) libxenguest.a $(DESTDIR)/usr/$(LIBDIR)
+       ln -sf libxenguest.so.$(MAJOR).$(MINOR) 
$(DESTDIR)/usr/$(LIBDIR)/libxenguest.so.$(MAJOR)
+       ln -sf libxenguest.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libxenguest.so
 
 .PHONY: TAGS clean rpm install all
 
@@ -100,18 +116,30 @@
        mv staging/i386/*.rpm .
        rm -rf staging
 
-libxc.a: $(LIB_OBJS)
+# libxenctrl
+
+libxenctrl.a: $(LIB_OBJS)
        $(AR) rc $@ $^
 
-libxc-pic.a: $(PIC_OBJS)
+libxenctrl.so: libxenctrl.so.$(MAJOR)
+       ln -sf $< $@
+libxenctrl.so.$(MAJOR): libxenctrl.so.$(MAJOR).$(MINOR)
+       ln -sf $< $@
+
+libxenctrl.so.$(MAJOR).$(MINOR): $(PIC_OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxenctrl.so.$(MAJOR) 
-shared -o $@ $^
+
+# libxenguest
+
+libxenguest.a: $(LIB_BUILD_OBJS)
        $(AR) rc $@ $^
 
-libxc.so: libxc.so.$(MAJOR)
+libxenguest.so: libxenguest.so.$(MAJOR)
        ln -sf $< $@
-libxc.so.$(MAJOR): libxc.so.$(MAJOR).$(MINOR)
+libxenguest.so.$(MAJOR): libxenguest.so.$(MAJOR).$(MINOR)
        ln -sf $< $@
 
-libxc.so.$(MAJOR).$(MINOR): $(PIC_OBJS)
-       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxc.so.$(MAJOR) -shared -o 
$@ $^ -lz
+libxenguest.so.$(MAJOR).$(MINOR): $(PIC_BUILD_OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxenguest.so.$(MAJOR) 
-shared -o $@ $^ -lz -lxenctrl
 
 -include $(DEPS)
diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_core.c
--- a/tools/libxc/xc_core.c     Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xc_core.c     Thu Aug 25 18:18:47 2005
@@ -1,4 +1,4 @@
-#include "xc_private.h"
+#include "xg_private.h"
 #define ELFSIZE 32
 #include "xc_elf.h"
 #include <stdlib.h>
diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xc_domain.c   Thu Aug 25 18:18:47 2005
@@ -266,7 +266,7 @@
     int err;
     unsigned int npages = mem_kb / (PAGE_SIZE/1024);
 
-    err = do_dom_mem_op(xc_handle, MEMOP_increase_reservation, NULL,
+    err = xc_dom_mem_op(xc_handle, MEMOP_increase_reservation, NULL,
                         npages, 0, domid);
     if (err == npages)
         return 0;
diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xc_linux_build.c      Thu Aug 25 18:18:47 2005
@@ -2,7 +2,8 @@
  * xc_linux_build.c
  */
 
-#include "xc_private.h"
+#include "xg_private.h"
+#include <xenctrl.h>
 
 #if defined(__i386__)
 #define ELFSIZE 32
@@ -340,7 +341,7 @@
     unsigned long count, i;
     start_info_t *start_info;
     shared_info_t *shared_info;
-    mmu_t *mmu = NULL;
+    xc_mmu_t *mmu = NULL;
     int rc;
 
     unsigned long nr_pt_pages;
@@ -490,7 +491,7 @@
         }
     }
 
-    if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL )
+    if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL )
         goto error_out;
 
     /* setup page tables */
@@ -520,9 +521,9 @@
         page_array[physmap_pfn++]);
     for ( count = 0; count < nr_pages; count++ )
     {
-        if ( add_mmu_update(xc_handle, mmu,
-                            (page_array[count] << PAGE_SHIFT) | 
-                            MMU_MACHPHYS_UPDATE, count) )
+        if ( xc_add_mmu_update(xc_handle, mmu,
+                              (page_array[count] << PAGE_SHIFT) | 
+                              MMU_MACHPHYS_UPDATE, count) )
         {
             munmap(physmap, PAGE_SIZE);
             goto error_out;
@@ -602,7 +603,7 @@
     munmap(shared_info, PAGE_SIZE);
 
     /* Send the page update requests down to the hypervisor. */
-    if ( finish_mmu_updates(xc_handle, mmu) )
+    if ( xc_finish_mmu_updates(xc_handle, mmu) )
         goto error_out;
 
     free(mmu);
@@ -676,7 +677,7 @@
 
     op.cmd = DOM0_GETDOMAININFO;
     op.u.getdomaininfo.domain = (domid_t)domid;
-    if ( (do_dom0_op(xc_handle, &op) < 0) || 
+    if ( (xc_dom0_op(xc_handle, &op) < 0) || 
          ((u16)op.u.getdomaininfo.domain != domid) )
     {
         PERROR("Could not get info on domain");
@@ -793,7 +794,7 @@
     launch_op.u.setdomaininfo.ctxt   = ctxt;
 
     launch_op.cmd = DOM0_SETDOMAININFO;
-    rc = do_dom0_op(xc_handle, &launch_op);
+    rc = xc_dom0_op(xc_handle, &launch_op);
     
     return rc;
 
diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c    Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xc_linux_restore.c    Thu Aug 25 18:18:47 2005
@@ -6,7 +6,12 @@
  * Copyright (c) 2003, K A Fraser.
  */
 
-#include "xc_private.h"
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "xg_private.h"
+#include <xenctrl.h>
+
 #include <xen/linux/suspend.h>
 
 #define MAX_BATCH_SIZE 1024
@@ -89,7 +94,7 @@
 
     char *region_base;
 
-    mmu_t *mmu = NULL;
+    xc_mmu_t *mmu = NULL;
 
     /* used by debug verify code */
     unsigned long buf[PAGE_SIZE/sizeof(unsigned long)];
@@ -132,7 +137,7 @@
     /* Get the domain's shared-info frame. */
     op.cmd = DOM0_GETDOMAININFO;
     op.u.getdomaininfo.domain = (domid_t)dom;
-    if (do_dom0_op(xc_handle, &op) < 0) {
+    if (xc_dom0_op(xc_handle, &op) < 0) {
         ERR("Could not get information on new domain");
         goto out;
     }
@@ -158,7 +163,7 @@
         goto out;
     }
 
-    mmu = init_mmu_updates(xc_handle, dom);
+    mmu = xc_init_mmu_updates(xc_handle, dom);
     if (mmu == NULL) {
         ERR("Could not initialise for MMU updates");
         goto out;
@@ -355,8 +360,9 @@
                 }
             }
 
-            if ( add_mmu_update(xc_handle, mmu,
-                                (mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, pfn) )
+            if ( xc_add_mmu_update(xc_handle, mmu,
+                                  (mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE,
+                                  pfn) )
             {
                 printf("machpys mfn=%ld pfn=%ld\n",mfn,pfn);
                 goto out;
@@ -370,7 +376,7 @@
 
     DPRINTF("Received all pages\n");
 
-    if ( finish_mmu_updates(xc_handle, mmu) )
+    if ( xc_finish_mmu_updates(xc_handle, mmu) )
         goto out;
 
     /*
@@ -388,14 +394,14 @@
         pin[nr_pins].mfn = pfn_to_mfn_table[i];
         if ( ++nr_pins == MAX_PIN_BATCH )
         {
-            if ( do_mmuext_op(xc_handle, pin, nr_pins, dom) < 0 )
+            if ( xc_mmuext_op(xc_handle, pin, nr_pins, dom) < 0 )
                 goto out;
             nr_pins = 0;
         }
     }
 
     if ( (nr_pins != 0) &&
-         (do_mmuext_op(xc_handle, pin, nr_pins, dom) < 0) )
+         (xc_mmuext_op(xc_handle, pin, nr_pins, dom) < 0) )
         goto out;
 
     DPRINTF("\b\b\b\b100%%\n");
@@ -435,7 +441,7 @@
 
        if ( count > 0 )
        {
-           if ( (rc = do_dom_mem_op( xc_handle,
+           if ( (rc = xc_dom_mem_op( xc_handle,
                                       MEMOP_decrease_reservation,
                                       pfntab, count, 0, dom )) <0 )
            {
@@ -586,7 +592,7 @@
     op.u.setdomaininfo.domain = (domid_t)dom;
     op.u.setdomaininfo.vcpu   = 0;
     op.u.setdomaininfo.ctxt   = &ctxt;
-    rc = do_dom0_op(xc_handle, &op);
+    rc = xc_dom0_op(xc_handle, &op);
 
     if ( rc != 0 )
     {
@@ -597,7 +603,7 @@
     DPRINTF("Domain ready to be unpaused\n");
     op.cmd = DOM0_UNPAUSEDOMAIN;
     op.u.unpausedomain.domain = (domid_t)dom;
-    rc = do_dom0_op(xc_handle, &op);
+    rc = xc_dom0_op(xc_handle, &op);
     if (rc == 0) {
         /* Success: print the domain id. */
         DPRINTF("DOM=%u\n", dom);
diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xc_linux_save.c       Thu Aug 25 18:18:47 2005
@@ -7,11 +7,15 @@
  */
 
 #include <inttypes.h>
+#include <time.h>
+#include <stdlib.h>
+#include <unistd.h>
 #include <sys/time.h>
-#include "xc_private.h"
+
+#include "xg_private.h"
+
 #include <xen/linux/suspend.h>
 #include <xen/io/domain_controller.h>
-#include <time.h>
 
 #define BATCH_SIZE 1024   /* 1024 pages (4MB) at a time */
 
@@ -772,7 +776,7 @@
                 goto out;
             }
      
-            if ( get_pfn_type_batch(xc_handle, dom, batch, pfn_type) ){
+            if ( xc_get_pfn_type_batch(xc_handle, dom, batch, pfn_type) ){
                 ERR("get_pfn_type_batch failed");
                 goto out;
             }
diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_load_aout9.c
--- a/tools/libxc/xc_load_aout9.c       Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xc_load_aout9.c       Thu Aug 25 18:18:47 2005
@@ -1,5 +1,5 @@
 
-#include "xc_private.h"
+#include "xg_private.h"
 #include "xc_aout9.h"
 
 #if defined(__i386__)
diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_load_bin.c
--- a/tools/libxc/xc_load_bin.c Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xc_load_bin.c Thu Aug 25 18:18:47 2005
@@ -66,7 +66,7 @@
  * Free Software Foundation, Inc.
  */
 
-#include "xc_private.h"
+#include "xg_private.h"
 #include <stdlib.h>
 
 #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xc_load_elf.c Thu Aug 25 18:18:47 2005
@@ -2,7 +2,7 @@
  * xc_elf_load.c
  */
 
-#include "xc_private.h"
+#include "xg_private.h"
 
 #if defined(__i386__)
 #define ELFSIZE 32
diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xc_private.c  Thu Aug 25 18:18:47 2005
@@ -64,8 +64,8 @@
 /*******************/
 
 /* NB: arr must be mlock'ed */
-int get_pfn_type_batch(int xc_handle, 
-                       u32 dom, int num, unsigned long *arr)
+int xc_get_pfn_type_batch(int xc_handle, 
+                         u32 dom, int num, unsigned long *arr)
 {
     dom0_op_t op;
     op.cmd = DOM0_GETPAGEFRAMEINFO2;
@@ -92,25 +92,40 @@
     return op.u.getpageframeinfo.type;
 }
 
-
-
-/*******************/
-
-int pin_table(
-    int xc_handle, unsigned int type, unsigned long mfn, domid_t dom)
-{
-    struct mmuext_op op;
-
-    op.cmd = type;
-    op.mfn = mfn;
-
-    if ( do_mmuext_op(xc_handle, &op, 1, dom) < 0 )
-        return 1;
-
-    return 0;
-}
-
-static int flush_mmu_updates(int xc_handle, mmu_t *mmu)
+int xc_mmuext_op(
+    int xc_handle,
+    struct mmuext_op *op,
+    unsigned int nr_ops,
+    domid_t dom)
+{
+    privcmd_hypercall_t hypercall;
+    long ret = -EINVAL;
+
+    hypercall.op     = __HYPERVISOR_mmuext_op;
+    hypercall.arg[0] = (unsigned long)op;
+    hypercall.arg[1] = (unsigned long)nr_ops;
+    hypercall.arg[2] = (unsigned long)0;
+    hypercall.arg[3] = (unsigned long)dom;
+
+    if ( mlock(op, nr_ops*sizeof(*op)) != 0 )
+    {
+        PERROR("Could not lock memory for Xen hypercall");
+        goto out1;
+    }
+
+    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
+    {
+       fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to"
+                    " rebuild the user-space tool set?\n",ret,errno);
+    }
+
+    safe_munlock(op, nr_ops*sizeof(*op));
+
+ out1:
+    return ret;
+}    
+
+static int flush_mmu_updates(int xc_handle, xc_mmu_t *mmu)
 {
     int err = 0;
     privcmd_hypercall_t hypercall;
@@ -145,9 +160,9 @@
     return err;
 }
 
-mmu_t *init_mmu_updates(int xc_handle, domid_t dom)
-{
-    mmu_t *mmu = malloc(sizeof(mmu_t));
+xc_mmu_t *xc_init_mmu_updates(int xc_handle, domid_t dom)
+{
+    xc_mmu_t *mmu = malloc(sizeof(xc_mmu_t));
     if ( mmu == NULL )
         return mmu;
     mmu->idx     = 0;
@@ -155,8 +170,8 @@
     return mmu;
 }
 
-int add_mmu_update(int xc_handle, mmu_t *mmu, 
-                   unsigned long ptr, unsigned long val)
+int xc_add_mmu_update(int xc_handle, xc_mmu_t *mmu, 
+                     unsigned long ptr, unsigned long val)
 {
     mmu->updates[mmu->idx].ptr = ptr;
     mmu->updates[mmu->idx].val = val;
@@ -167,10 +182,47 @@
     return 0;
 }
 
-int finish_mmu_updates(int xc_handle, mmu_t *mmu)
+int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu)
 {
     return flush_mmu_updates(xc_handle, mmu);
 }
+
+int xc_dom_mem_op(int xc_handle,
+                 unsigned int memop, 
+                 unsigned int *extent_list, 
+                 unsigned int nr_extents,
+                 unsigned int extent_order,
+                 domid_t domid)
+{
+    privcmd_hypercall_t hypercall;
+    long ret = -EINVAL;
+
+    hypercall.op     = __HYPERVISOR_dom_mem_op;
+    hypercall.arg[0] = (unsigned long)memop;
+    hypercall.arg[1] = (unsigned long)extent_list;
+    hypercall.arg[2] = (unsigned long)nr_extents;
+    hypercall.arg[3] = (unsigned long)extent_order;
+    hypercall.arg[4] = (unsigned long)domid;
+
+    if ( (extent_list != NULL) && 
+         (mlock(extent_list, nr_extents*sizeof(unsigned long)) != 0) )
+    {
+        PERROR("Could not lock memory for Xen hypercall");
+        goto out1;
+    }
+
+    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
+    {
+       fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to"
+                " rebuild the user-space tool set?\n",ret,errno);
+    }
+
+    if ( extent_list != NULL )
+        safe_munlock(extent_list, nr_extents*sizeof(unsigned long));
+
+ out1:
+    return ret;
+}    
 
 
 long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu )
@@ -189,19 +241,6 @@
     return op.u.getvcpucontext.cpu_time;
 }
 
-
-/* This is shared between save and restore, and may generally be useful. */
-unsigned long csum_page (void * page)
-{
-    int i;
-    unsigned long *p = page;
-    unsigned long long sum=0;
-
-    for ( i = 0; i < (PAGE_SIZE/sizeof(unsigned long)); i++ )
-        sum += p[i];
-
-    return sum ^ (sum>>32);
-}
 
 unsigned long xc_get_m2p_start_mfn ( int xc_handle )
 {
@@ -332,53 +371,6 @@
     return sz;
 }
 
-char *xc_read_kernel_image(const char *filename, unsigned long *size)
-{
-    int kernel_fd = -1;
-    gzFile kernel_gfd = NULL;
-    char *image = NULL;
-    unsigned int bytes;
-
-    if ( (kernel_fd = open(filename, O_RDONLY)) < 0 )
-    {
-        PERROR("Could not open kernel image");
-        goto out;
-    }
-
-    if ( (*size = xc_get_filesz(kernel_fd)) == 0 )
-    {
-        PERROR("Could not read kernel image");
-        goto out;
-    }
-
-    if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL )
-    {
-        PERROR("Could not allocate decompression state for state file");
-        goto out;
-    }
-
-    if ( (image = malloc(*size)) == NULL )
-    {
-        PERROR("Could not allocate memory for kernel image");
-        goto out;
-    }
-
-    if ( (bytes = gzread(kernel_gfd, image, *size)) != *size )
-    {
-        PERROR("Error reading kernel image, could not"
-               " read the whole image (%d != %ld).", bytes, *size);
-        free(image);
-        image = NULL;
-    }
-
- out:
-    if ( kernel_gfd != NULL )
-        gzclose(kernel_gfd);
-    else if ( kernel_fd >= 0 )
-        close(kernel_fd);
-    return image;
-}
-
 void xc_map_memcpy(unsigned long dst, char *src, unsigned long size,
                    int xch, u32 dom, unsigned long *parray,
                    unsigned long vstart)
diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_private.h
--- a/tools/libxc/xc_private.h  Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xc_private.h  Thu Aug 25 18:18:47 2005
@@ -1,123 +1,25 @@
 
-#ifndef __XC_PRIVATE_H__
-#define __XC_PRIVATE_H__
+#ifndef XC_PRIVATE_H
+#define XC_PRIVATE_H
 
 #include <unistd.h>
 #include <stdio.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <string.h>
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdlib.h>
 #include <sys/ioctl.h>
-#include <errno.h>
-#include <string.h>
 
-#include "xc.h"
+#include "xenctrl.h"
 
 #include <xen/linux/privcmd.h>
 
-#define _PAGE_PRESENT   0x001
-#define _PAGE_RW        0x002
-#define _PAGE_USER      0x004
-#define _PAGE_PWT       0x008
-#define _PAGE_PCD       0x010
-#define _PAGE_ACCESSED  0x020
-#define _PAGE_DIRTY     0x040
-#define _PAGE_PAT       0x080
-#define _PAGE_PSE       0x080
-#define _PAGE_GLOBAL    0x100
-
-#if defined(__i386__)
-#define L1_PAGETABLE_SHIFT       12
-#define L2_PAGETABLE_SHIFT       22
-#define L1_PAGETABLE_SHIFT_PAE   12
-#define L2_PAGETABLE_SHIFT_PAE   21
-#define L3_PAGETABLE_SHIFT_PAE   30
-#elif defined(__x86_64__)
-#define L1_PAGETABLE_SHIFT      12
-#define L2_PAGETABLE_SHIFT      21
-#define L3_PAGETABLE_SHIFT      30
-#define L4_PAGETABLE_SHIFT      39
-#endif
-
-#if defined(__i386__) 
-#define ENTRIES_PER_L1_PAGETABLE 1024
-#define ENTRIES_PER_L2_PAGETABLE 1024
-#define L1_PAGETABLE_ENTRIES_PAE  512
-#define L2_PAGETABLE_ENTRIES_PAE  512
-#define L3_PAGETABLE_ENTRIES_PAE    4
-#elif defined(__x86_64__)
-#define L1_PAGETABLE_ENTRIES    512
-#define L2_PAGETABLE_ENTRIES    512
-#define L3_PAGETABLE_ENTRIES    512
-#define L4_PAGETABLE_ENTRIES    512
-#endif
- 
 #define PAGE_SHIFT              XC_PAGE_SHIFT
 #define PAGE_SIZE               (1UL << PAGE_SHIFT)
 #define PAGE_MASK               (~(PAGE_SIZE-1))
-
-typedef u32 l1_pgentry_32_t;
-typedef u32 l2_pgentry_32_t;
-typedef u64 l1_pgentry_64_t;
-typedef u64 l2_pgentry_64_t;
-typedef u64 l3_pgentry_64_t;
-typedef unsigned long l1_pgentry_t;
-typedef unsigned long l2_pgentry_t;
-#if defined(__x86_64__)
-typedef unsigned long l3_pgentry_t;
-typedef unsigned long l4_pgentry_t;
-#endif
-
-#if defined(__i386__)
-#define l1_table_offset(_a) \
-          (((_a) >> L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE - 1))
-#define l2_table_offset(_a) \
-          ((_a) >> L2_PAGETABLE_SHIFT)
-#define l1_table_offset_pae(_a) \
-  (((_a) >> L1_PAGETABLE_SHIFT_PAE) & (L1_PAGETABLE_ENTRIES_PAE - 1))
-#define l2_table_offset_pae(_a) \
-  (((_a) >> L2_PAGETABLE_SHIFT_PAE) & (L2_PAGETABLE_ENTRIES_PAE - 1))
-#define l3_table_offset_pae(_a) \
-       (((_a) >> L3_PAGETABLE_SHIFT_PAE) & (L3_PAGETABLE_ENTRIES_PAE - 1))
-#elif defined(__x86_64__)
-#define l1_table_offset(_a) \
-  (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
-#define l2_table_offset(_a) \
-  (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
-#define l3_table_offset(_a) \
-       (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
-#define l4_table_offset(_a) \
-       (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
-#endif
-
-struct domain_setup_info
-{
-    unsigned long v_start;
-    unsigned long v_end;
-    unsigned long v_kernstart;
-    unsigned long v_kernend;
-    unsigned long v_kernentry;
-
-    unsigned int  load_symtab;
-    unsigned int  pae_kernel;
-    unsigned long symtab_addr;
-    unsigned long symtab_len;
-};
-
-typedef int (*parseimagefunc)(char *image, unsigned long image_size,
-                             struct domain_setup_info *dsi);
-typedef int (*loadimagefunc)(char *image, unsigned long image_size, int xch,
-                            u32 dom, unsigned long *parray,
-                            struct domain_setup_info *dsi);
-
-struct load_funcs
-{
-    parseimagefunc parseimage;
-    loadimagefunc loadimage;
-};
 
 #define ERROR(_m, _a...)                                \
 do {                                                    \
@@ -186,97 +88,6 @@
     return ret;
 }
 
-static inline int do_dom_mem_op(int            xc_handle,
-                               unsigned int   memop, 
-                               unsigned int *extent_list, 
-                               unsigned int  nr_extents,
-                               unsigned int   extent_order,
-                               domid_t        domid)
-{
-    privcmd_hypercall_t hypercall;
-    long ret = -EINVAL;
-
-    hypercall.op     = __HYPERVISOR_dom_mem_op;
-    hypercall.arg[0] = (unsigned long)memop;
-    hypercall.arg[1] = (unsigned long)extent_list;
-    hypercall.arg[2] = (unsigned long)nr_extents;
-    hypercall.arg[3] = (unsigned long)extent_order;
-    hypercall.arg[4] = (unsigned long)domid;
-
-    if ( (extent_list != NULL) && 
-         (mlock(extent_list, nr_extents*sizeof(unsigned long)) != 0) )
-    {
-        PERROR("Could not lock memory for Xen hypercall");
-        goto out1;
-    }
-
-    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
-    {
-       fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to"
-                " rebuild the user-space tool set?\n",ret,errno);
-    }
-
-    if ( extent_list != NULL )
-        safe_munlock(extent_list, nr_extents*sizeof(unsigned long));
-
- out1:
-    return ret;
-}    
-
-static inline int do_mmuext_op(
-    int xc_handle,
-    struct mmuext_op *op,
-    unsigned int nr_ops,
-    domid_t dom)
-{
-    privcmd_hypercall_t hypercall;
-    long ret = -EINVAL;
-
-    hypercall.op     = __HYPERVISOR_mmuext_op;
-    hypercall.arg[0] = (unsigned long)op;
-    hypercall.arg[1] = (unsigned long)nr_ops;
-    hypercall.arg[2] = (unsigned long)0;
-    hypercall.arg[3] = (unsigned long)dom;
-
-    if ( mlock(op, nr_ops*sizeof(*op)) != 0 )
-    {
-        PERROR("Could not lock memory for Xen hypercall");
-        goto out1;
-    }
-
-    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
-    {
-       fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to"
-                    " rebuild the user-space tool set?\n",ret,errno);
-    }
-
-    safe_munlock(op, nr_ops*sizeof(*op));
-
- out1:
-    return ret;
-}    
-
-
-/*
- * PFN mapping.
- */
-int get_pfn_type_batch(int xc_handle, u32 dom, int num, unsigned long *arr);
-unsigned long csum_page (void * page);
-
-/*
- * MMU updates.
- */
-#define MAX_MMU_UPDATES 1024
-typedef struct {
-    mmu_update_t updates[MAX_MMU_UPDATES];
-    int          idx;
-    domid_t      subject;
-} mmu_t;
-mmu_t *init_mmu_updates(int xc_handle, domid_t dom);
-int add_mmu_update(int xc_handle, mmu_t *mmu, 
-                   unsigned long ptr, unsigned long val);
-int finish_mmu_updates(int xc_handle, mmu_t *mmu);
-
 
 /*
  * ioctl-based mfn mapping interface
@@ -296,38 +107,4 @@
 } privcmd_mmap_t; 
 */
 
-#define mfn_mapper_queue_size 128
-
-typedef struct mfn_mapper {
-    int xc_handle;
-    int size;
-    int prot;
-    int error;
-    int max_queue_size;
-    void * addr;
-    privcmd_mmap_t ioctl; 
-    
-} mfn_mapper_t;
-
-unsigned long xc_get_m2p_start_mfn (int xc_handle);
-
-int xc_copy_to_domain_page(int xc_handle, u32 domid,
-                            unsigned long dst_pfn, void *src_page);
-
-unsigned long xc_get_filesz(int fd);
-
-char *xc_read_kernel_image(const char *filename, unsigned long *size);
-
-void xc_map_memcpy(unsigned long dst, char *src, unsigned long size,
-                   int xch, u32 dom, unsigned long *parray,
-                   unsigned long vstart);
-
-int pin_table(int xc_handle, unsigned int type, unsigned long mfn,
-             domid_t dom);
-
-/* image loading */
-int probe_elf(char *image, unsigned long image_size, struct load_funcs *funcs);
-int probe_bin(char *image, unsigned long image_size, struct load_funcs *funcs);
-int probe_aout9(char *image, unsigned long image_size, struct load_funcs 
*funcs);
-
 #endif /* __XC_PRIVATE_H__ */
diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c        Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xc_vmx_build.c        Thu Aug 25 18:18:47 2005
@@ -3,7 +3,7 @@
  */
 
 #include <stddef.h>
-#include "xc_private.h"
+#include "xg_private.h"
 #define ELFSIZE 32
 #include "xc_elf.h"
 #include <stdlib.h>
@@ -243,7 +243,7 @@
     shared_info_t *shared_info;
     struct linux_boot_params * boot_paramsp;
     __u16 * boot_gdtp;
-    mmu_t *mmu = NULL;
+    xc_mmu_t *mmu = NULL;
     int rc;
 
     unsigned long nr_pt_pages;
@@ -358,7 +358,7 @@
         }
     }
 
-    if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL )
+    if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL )
         goto error_out;
 
 #ifdef __i386__
@@ -459,9 +459,9 @@
     /* Write the machine->phys table entries. */
     for ( count = 0; count < nr_pages; count++ )
     {
-        if ( add_mmu_update(xc_handle, mmu,
-                            (page_array[count] << PAGE_SHIFT) | 
-                            MMU_MACHPHYS_UPDATE, count) )
+        if ( xc_add_mmu_update(xc_handle, mmu,
+                              (page_array[count] << PAGE_SHIFT) | 
+                              MMU_MACHPHYS_UPDATE, count) )
            goto error_out;
     }
     
@@ -587,7 +587,7 @@
 #endif
 
     /* Send the page update requests down to the hypervisor. */
-    if ( finish_mmu_updates(xc_handle, mmu) )
+    if ( xc_finish_mmu_updates(xc_handle, mmu) )
         goto error_out;
 
     free(mmu);
@@ -708,7 +708,7 @@
 
     op.cmd = DOM0_GETDOMAININFO;
     op.u.getdomaininfo.domain = (domid_t)domid;
-    if ( (do_dom0_op(xc_handle, &op) < 0) || 
+    if ( (xc_dom0_op(xc_handle, &op) < 0) || 
          ((u16)op.u.getdomaininfo.domain != domid) )
     {
         PERROR("Could not get info on domain");
@@ -789,7 +789,7 @@
     launch_op.u.setdomaininfo.ctxt   = ctxt;
 
     launch_op.cmd = DOM0_SETDOMAININFO;
-    rc = do_dom0_op(xc_handle, &launch_op);
+    rc = xc_dom0_op(xc_handle, &launch_op);
     
     return rc;
 
diff -r e2025593f702 -r 112d44270733 tools/misc/Makefile
--- a/tools/misc/Makefile       Wed Aug 24 23:16:52 2005
+++ b/tools/misc/Makefile       Thu Aug 25 18:18:47 2005
@@ -50,4 +50,4 @@
        $(CC) -c $(CFLAGS) -o $@ $<
 
 $(TARGETS): %: %.o Makefile
-       $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxc
+       $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxenctrl
diff -r e2025593f702 -r 112d44270733 tools/misc/cpuperf/Makefile
--- a/tools/misc/cpuperf/Makefile       Wed Aug 24 23:16:52 2005
+++ b/tools/misc/cpuperf/Makefile       Thu Aug 25 18:18:47 2005
@@ -37,7 +37,7 @@
        $(CC) $(CFLAGS) -o $@ $<
 
 cpuperf-xen: cpuperf.c $(HDRS) Makefile
-       $(CC) $(CFLAGS) -I $(XEN_LIBXC) -L$(XEN_LIBXC) -lxc -DXENO -o $@ $<
+       $(CC) $(CFLAGS) -I $(XEN_LIBXC) -L$(XEN_LIBXC) -lxenctrl -DXENO -o $@ $<
 
 cpuperf-perfcntr: cpuperf.c $(HDRS) Makefile
        $(CC) $(CFLAGS) -DPERFCNTR -o $@ $<
diff -r e2025593f702 -r 112d44270733 tools/misc/cpuperf/cpuperf_xeno.h
--- a/tools/misc/cpuperf/cpuperf_xeno.h Wed Aug 24 23:16:52 2005
+++ b/tools/misc/cpuperf/cpuperf_xeno.h Thu Aug 25 18:18:47 2005
@@ -9,7 +9,7 @@
  *
  */
 
-#include <xc.h>
+#include <xenctrl.h>
 
 static int xc_handle;
 
diff -r e2025593f702 -r 112d44270733 tools/misc/xc_shadow.c
--- a/tools/misc/xc_shadow.c    Wed Aug 24 23:16:52 2005
+++ b/tools/misc/xc_shadow.c    Thu Aug 25 18:18:47 2005
@@ -11,7 +11,7 @@
  */
 
 
-#include <xc.h>
+#include <xenctrl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/mman.h>
diff -r e2025593f702 -r 112d44270733 tools/misc/xenperf.c
--- a/tools/misc/xenperf.c      Wed Aug 24 23:16:52 2005
+++ b/tools/misc/xenperf.c      Thu Aug 25 18:18:47 2005
@@ -11,7 +11,7 @@
  */
 
 
-#include <xc.h>
+#include <xenctrl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/mman.h>
diff -r e2025593f702 -r 112d44270733 tools/python/setup.py
--- a/tools/python/setup.py     Wed Aug 24 23:16:52 2005
+++ b/tools/python/setup.py     Thu Aug 25 18:18:47 2005
@@ -17,7 +17,7 @@
                  XEN_ROOT + "/tools/xenstore",
                  ]
 
-libraries = [ "xc", "xenstore-pic" ]
+libraries = [ "xenctrl", "xenguest", "xenstore" ]
 
 xc = Extension("xc",
                extra_compile_args = extra_compile_args,
@@ -41,7 +41,7 @@
                sources            = [ "xen/lowlevel/xs/xs.c" ])
 
 setup(name            = 'xen',
-      version         = '2.0',
+      version         = '3.0',
       description     = 'Xen',
       packages        = ['xen',
                          'xen.lowlevel',
diff -r e2025593f702 -r 112d44270733 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Wed Aug 24 23:16:52 2005
+++ b/tools/python/xen/lowlevel/xc/xc.c Thu Aug 25 18:18:47 2005
@@ -5,7 +5,8 @@
  */
 
 #include <Python.h>
-#include <xc.h>
+#include <xenctrl.h>
+#include <xenguest.h>
 #include <zlib.h>
 #include <fcntl.h>
 #include <netinet/in.h>
diff -r e2025593f702 -r 112d44270733 tools/python/xen/lowlevel/xu/xu.c
--- a/tools/python/xen/lowlevel/xu/xu.c Wed Aug 24 23:16:52 2005
+++ b/tools/python/xen/lowlevel/xu/xu.c Thu Aug 25 18:18:47 2005
@@ -21,7 +21,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <signal.h>
-#include <xc.h>
+#include <xenctrl.h>
 
 #include <xen/xen.h>
 #include <xen/io/domain_controller.h>
diff -r e2025593f702 -r 112d44270733 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Aug 24 23:16:52 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Thu Aug 25 18:18:47 2005
@@ -265,6 +265,8 @@
         self.info = None
         self.blkif_backend = False
         self.netif_backend = False
+        self.netif_idx = 0
+        
         #todo: state: running, suspended
         self.state = STATE_VM_OK
         self.state_updated = threading.Condition()
@@ -400,8 +402,7 @@
             db['virtual-device'] = "%i" % devnum
             #db['backend'] = sxp.child_value(devconfig, 'backend', '0')
             db['backend'] = backdb.getPath()
-            db['backend-id'] = "%i" % int(sxp.child_value(devconfig,
-                                                          'backend', '0'))
+            db['backend-id'] = "%i" % backdom.id
 
             backdb['frontend'] = db.getPath()
             (type, params) = string.split(sxp.child_value(devconfig, 'uname'), 
':', 1)
@@ -417,6 +418,37 @@
             db.saveDB(save=True)
             
             return
+
+        if type == 'vif':
+            backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0'))
+
+            log.error(devconfig)
+            
+            devnum = self.netif_idx
+            self.netif_idx += 1
+
+            # create backend db
+            backdb = backdom.db.addChild("/backend/%s/%s/%d" %
+                                         (type, self.uuid, devnum))
+
+            # create frontend db
+            db = self.db.addChild("/device/%s/%d" % (type, devnum))
+            
+            backdb['frontend'] = db.getPath()
+            backdb['frontend-id'] = "%i" % self.id
+            backdb['handle'] = "%i" % devnum
+            backdb.saveDB(save=True)
+
+            db['backend'] = backdb.getPath()
+            db['backend-id'] = "%i" % backdom.id
+            db['handle'] = "%i" % devnum
+            log.error(sxp.child_value(devconfig, 'mac'))
+            db['mac'] = sxp.child_value(devconfig, 'mac')
+
+            db.saveDB(save=True)
+
+            return
+        
         ctrl = self.findDeviceController(type)
         return ctrl.createDevice(devconfig, recreate=self.recreate,
                                  change=change)
@@ -718,6 +750,11 @@
                                  devdb['node'].getData())
                     typedb[dev].delete()
                 typedb.saveDB(save=True)
+            if type == 'vif':
+                typedb = ddb.addChild(type)
+                for dev in typedb.keys():
+                    typedb[dev].delete()
+                typedb.saveDB(save=True)
 
     def show(self):
         """Print virtual machine info.
diff -r e2025593f702 -r 112d44270733 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Wed Aug 24 23:16:52 2005
+++ b/tools/python/xen/xm/main.py       Thu Aug 25 18:18:47 2005
@@ -665,8 +665,10 @@
             err("Most commands need root access.  Please try again as root")
             sys.exit(1)
         except XendError, ex:
+            if args[0] == "bogus":
+                args.remove("bogus")
             if len(args) > 0:
-                handle_xend_error(argv[1], args[1], ex)
+                handle_xend_error(argv[1], args[0], ex)
             else:
                 print "Unexpected error:", sys.exc_info()[0]
                 print
diff -r e2025593f702 -r 112d44270733 tools/xcs/Makefile
--- a/tools/xcs/Makefile        Wed Aug 24 23:16:52 2005
+++ b/tools/xcs/Makefile        Thu Aug 25 18:18:47 2005
@@ -34,10 +34,10 @@
 
 xcsdump: xcsdump.c dump.c
        $(CC) $(CFLAGS) -o xcsdump xcsdump.c -L$(XEN_LIBXC) \
-              ctrl_interface.c evtchn.c dump.c -lxc
+              ctrl_interface.c evtchn.c dump.c -lxenctrl
 
 $(BIN): $(OBJS)
-       $(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -lxc 
+       $(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -lxenctrl 
 
 $(OBJS): $(HDRS)
 
diff -r e2025593f702 -r 112d44270733 tools/xcs/dump.h
--- a/tools/xcs/dump.h  Wed Aug 24 23:16:52 2005
+++ b/tools/xcs/dump.h  Thu Aug 25 18:18:47 2005
@@ -20,7 +20,7 @@
 #define XENCTLD_ERROR_H
 
 #include <stdint.h>
-#include <xc.h>
+#include <xenctrl.h>
 #include <xen/io/domain_controller.h>
 
 void dump_msg(const control_msg_t *msg, uint64_t flags);
diff -r e2025593f702 -r 112d44270733 tools/xcs/xcs.h
--- a/tools/xcs/xcs.h   Wed Aug 24 23:16:52 2005
+++ b/tools/xcs/xcs.h   Thu Aug 25 18:18:47 2005
@@ -11,7 +11,7 @@
 #define __XCS_H__
 
 #include <pthread.h>
-#include <xc.h>
+#include <xenctrl.h>
 #include <xen/xen.h>
 #include <xen/io/domain_controller.h>
 #include <xen/linux/privcmd.h>
diff -r e2025593f702 -r 112d44270733 tools/xcs/xcsdump.c
--- a/tools/xcs/xcsdump.c       Wed Aug 24 23:16:52 2005
+++ b/tools/xcs/xcsdump.c       Thu Aug 25 18:18:47 2005
@@ -16,7 +16,7 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <ctype.h>
-#include <xc.h>
+#include <xenctrl.h>
 #include <xen/xen.h>
 #include <xen/io/domain_controller.h>
 #include <getopt.h>
diff -r e2025593f702 -r 112d44270733 tools/xcutils/Makefile
--- a/tools/xcutils/Makefile    Wed Aug 24 23:16:52 2005
+++ b/tools/xcutils/Makefile    Thu Aug 25 18:18:47 2005
@@ -30,7 +30,7 @@
 
 PROGRAMS               = xc_restore xc_save
 
-LDLIBS                 = -L$(XEN_LIBXC) -lxc
+LDLIBS                 = -L$(XEN_LIBXC) -lxenguest -lxenctrl
 
 .PHONY: all
 all: build
diff -r e2025593f702 -r 112d44270733 tools/xcutils/xc_restore.c
--- a/tools/xcutils/xc_restore.c        Wed Aug 24 23:16:52 2005
+++ b/tools/xcutils/xc_restore.c        Thu Aug 25 18:18:47 2005
@@ -7,11 +7,12 @@
  *
  */
 
+#include <err.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <stdio.h>
-#include <err.h>
 
-#include <xc.h>
+#include <xenguest.h>
 
 int
 main(int argc, char **argv)
diff -r e2025593f702 -r 112d44270733 tools/xcutils/xc_save.c
--- a/tools/xcutils/xc_save.c   Wed Aug 24 23:16:52 2005
+++ b/tools/xcutils/xc_save.c   Thu Aug 25 18:18:47 2005
@@ -7,11 +7,12 @@
  *
  */
 
+#include <err.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <stdio.h>
-#include <err.h>
 
-#include <xc.h>
+#include <xenguest.h>
 
 int
 main(int argc, char **argv)
diff -r e2025593f702 -r 112d44270733 tools/xenstore/Makefile
--- a/tools/xenstore/Makefile   Wed Aug 24 23:16:52 2005
+++ b/tools/xenstore/Makefile   Thu Aug 25 18:18:47 2005
@@ -32,7 +32,7 @@
        ln -sf $(XEN_ROOT)/xen/include/public $@
 
 xenstored: xenstored_core.o xenstored_watch.o xenstored_domain.o 
xenstored_transaction.o xs_lib.o talloc.o utils.o
-       $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxc -o $@
+       $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@
 
 xenstored_test: xenstored_core_test.o xenstored_watch_test.o 
xenstored_domain_test.o xenstored_transaction_test.o xs_lib.o talloc_test.o 
fake_libxc.o utils.o
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
@@ -109,7 +109,7 @@
        export $(TESTENV); PID=`./xenstored_test --output-pid 
--trace-file=/tmp/trace`; ./xs_stress 5000; ret=$$?; kill $$PID; exit $$ret
 
 xs_dom0_test: xs_dom0_test.o utils.o
-       $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxc -o $@
+       $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@
 
 TAGS:
        etags `find . -name '*.[ch]'`
diff -r e2025593f702 -r 112d44270733 tools/xenstore/xs_dom0_test.c
--- a/tools/xenstore/xs_dom0_test.c     Wed Aug 24 23:16:52 2005
+++ b/tools/xenstore/xs_dom0_test.c     Thu Aug 25 18:18:47 2005
@@ -3,7 +3,7 @@
 #include <sys/ioctl.h>
 #include "xs.h"
 #include "utils.h"
-#include <xc.h>
+#include <xenctrl.h>
 #include <xen/linux/privcmd.h>
 #include <stdio.h>
 #include <unistd.h>
diff -r e2025593f702 -r 112d44270733 tools/xenstore/xs_lib.h
--- a/tools/xenstore/xs_lib.h   Wed Aug 24 23:16:52 2005
+++ b/tools/xenstore/xs_lib.h   Thu Aug 25 18:18:47 2005
@@ -22,7 +22,7 @@
 
 #include <stdbool.h>
 #include <limits.h>
-#include <xc.h>
+#include <xenctrl.h>
 
 /* Bitmask of permissions. */
 enum xs_perm_type {
diff -r e2025593f702 -r 112d44270733 tools/xentrace/Makefile
--- a/tools/xentrace/Makefile   Wed Aug 24 23:16:52 2005
+++ b/tools/xentrace/Makefile   Thu Aug 25 18:18:47 2005
@@ -36,4 +36,4 @@
        $(RM) *.a *.so *.o *.rpm $(BIN)
 
 %: %.c $(HDRS) Makefile
-       $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxc
+       $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxenctrl
diff -r e2025593f702 -r 112d44270733 tools/xentrace/xenctx.c
--- a/tools/xentrace/xenctx.c   Wed Aug 24 23:16:52 2005
+++ b/tools/xentrace/xenctx.c   Thu Aug 25 18:18:47 2005
@@ -21,7 +21,7 @@
 #include <argp.h>
 #include <signal.h>
 
-#include "xc.h"
+#include "xenctrl.h"
 
 #ifdef __i386__
 void print_ctx(vcpu_guest_context_t *ctx1)
diff -r e2025593f702 -r 112d44270733 xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c  Wed Aug 24 23:16:52 2005
+++ b/xen/arch/x86/x86_32/mm.c  Thu Aug 25 18:18:47 2005
@@ -93,15 +93,10 @@
 
     /*
      * Allocate and map the machine-to-phys table and create read-only mapping 
-     * of MPT for guest-OS use.  Without PAE we'll end up with one 4MB page, 
-     * with PAE we'll allocate 2MB pages depending on the amount of memory 
-     * installed, but at least 4MB to cover 4GB address space.  This is needed 
-     * to make PCI I/O memory address lookups work in guests.
+     * of MPT for guest-OS use.
      */
     mpt_size  = (max_page * 4) + (1UL << L2_PAGETABLE_SHIFT) - 1UL;
     mpt_size &= ~((1UL << L2_PAGETABLE_SHIFT) - 1UL);
-    if ( mpt_size < (4 << 20) )
-        mpt_size = 4 << 20;
     for ( i = 0; i < (mpt_size >> L2_PAGETABLE_SHIFT); i++ )
     {
         if ( (pg = alloc_domheap_pages(NULL, PAGETABLE_ORDER, 0)) == NULL )
diff -r e2025593f702 -r 112d44270733 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c  Wed Aug 24 23:16:52 2005
+++ b/xen/arch/x86/x86_64/mm.c  Thu Aug 25 18:18:47 2005
@@ -74,7 +74,7 @@
 
 void __init paging_init(void)
 {
-    unsigned long i;
+    unsigned long i, mpt_size;
     l3_pgentry_t *l3_ro_mpt;
     l2_pgentry_t *l2_ro_mpt;
     struct pfn_info *pg;
@@ -98,16 +98,17 @@
      * Allocate and map the machine-to-phys table.
      * This also ensures L3 is present for fixmaps.
      */
-    for ( i = 0; i < max_page; i += ((1UL << L2_PAGETABLE_SHIFT) / 8) )
-    {
-        pg = alloc_domheap_pages(NULL, PAGETABLE_ORDER, 0);
-        if ( pg == NULL )
+    mpt_size  = (max_page * 4) + (1UL << L2_PAGETABLE_SHIFT) - 1UL;
+    mpt_size &= ~((1UL << L2_PAGETABLE_SHIFT) - 1UL);
+    for ( i = 0; i < (mpt_size >> L2_PAGETABLE_SHIFT); i++ )
+    {
+        if ( (pg = alloc_domheap_pages(NULL, PAGETABLE_ORDER, 0)) == NULL )
             panic("Not enough memory for m2p table\n");
         map_pages_to_xen(
-            RDWR_MPT_VIRT_START + i*8, page_to_pfn(pg), 
+            RDWR_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT), page_to_pfn(pg), 
             1UL << PAGETABLE_ORDER,
             PAGE_HYPERVISOR);
-        memset((void *)(RDWR_MPT_VIRT_START + i*8), 0x55,
+        memset((void *)(RDWR_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT)), 0x55,
                1UL << L2_PAGETABLE_SHIFT);
         *l2_ro_mpt++ = l2e_from_page(
             pg, _PAGE_GLOBAL|_PAGE_PSE|_PAGE_USER|_PAGE_PRESENT);
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- /dev/null   Wed Aug 24 23:16:52 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Thu Aug 25 18:18:47 2005
@@ -0,0 +1,257 @@
+/*  Xenbus code for netif backend
+    Copyright (C) 2005 Rusty Russell <rusty@xxxxxxxxxxxxxxx>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include <stdarg.h>
+#include <linux/module.h>
+#include <asm-xen/xenbus.h>
+#include "common.h"
+
+struct backend_info
+{
+       struct xenbus_device *dev;
+
+       /* our communications channel */
+       netif_t *netif;
+
+       long int frontend_id;
+#if 0
+       long int pdev;
+       long int readonly;
+#endif
+
+       /* watch back end for changes */
+       struct xenbus_watch backend_watch;
+
+       /* watch front end for changes */
+       struct xenbus_watch watch;
+       char *frontpath;
+};
+
+static int netback_remove(struct xenbus_device *dev)
+{
+       struct backend_info *be = dev->data;
+
+       if (be->watch.node)
+               unregister_xenbus_watch(&be->watch);
+       unregister_xenbus_watch(&be->backend_watch);
+       if (be->netif)
+               netif_disconnect(be->netif);
+       if (be->frontpath)
+               kfree(be->frontpath);
+       kfree(be);
+       return 0;
+}
+
+/* Front end tells us frame. */
+static void frontend_changed(struct xenbus_watch *watch, const char *node)
+{
+       unsigned long tx_ring_ref, rx_ring_ref;
+       unsigned int evtchn;
+       int err;
+       struct backend_info *be
+               = container_of(watch, struct backend_info, watch);
+       char *mac, *e, *s;
+       int i;
+
+       /* If other end is gone, delete ourself. */
+       if (node && !xenbus_exists(be->frontpath, "")) {
+               xenbus_rm(be->dev->nodename, "");
+               device_unregister(&be->dev->dev);
+               return;
+       }
+       if (be->netif == NULL || be->netif->status == CONNECTED)
+               return;
+
+       mac = xenbus_read(be->frontpath, "mac", NULL);
+       if (IS_ERR(mac)) {
+               err = PTR_ERR(mac);
+               xenbus_dev_error(be->dev, err, "reading %s/mac",
+                                be->dev->nodename);
+               return;
+       }
+       s = mac;
+       for (i = 0; i < ETH_ALEN; i++) {
+               be->netif->fe_dev_addr[i] = simple_strtoul(s, &e, 16);
+               if (s == e || (e[0] != ':' && e[0] != 0)) {
+                       kfree(mac);
+                       err = -ENOENT;
+                       xenbus_dev_error(be->dev, err, "parsing %s/mac",
+                                        be->dev->nodename);
+                       return;
+               }
+               s = &e[1];
+       }
+       kfree(mac);
+
+       err = xenbus_gather(be->frontpath, "tx-ring-ref", "%lu", &tx_ring_ref,
+                           "rx-ring-ref", "%lu", &rx_ring_ref,
+                           "event-channel", "%u", &evtchn, NULL);
+       if (err) {
+               xenbus_dev_error(be->dev, err,
+                                "reading %s/ring-ref and event-channel",
+                                be->frontpath);
+               return;
+       }
+
+       /* Map the shared frame, irq etc. */
+       err = netif_map(be->netif, tx_ring_ref, rx_ring_ref, evtchn);
+       if (err) {
+               xenbus_dev_error(be->dev, err,
+                                "mapping shared-frames %lu/%lu port %u",
+                                tx_ring_ref, rx_ring_ref, evtchn);
+               return;
+       }
+
+       xenbus_dev_ok(be->dev);
+
+       return;
+}
+
+/* 
+   Setup supplies physical device.  
+   We provide event channel and device details to front end.
+   Frontend supplies shared frame and event channel.
+ */
+static void backend_changed(struct xenbus_watch *watch, const char *node)
+{
+       int err;
+       long int handle;
+       struct backend_info *be
+               = container_of(watch, struct backend_info, backend_watch);
+       struct xenbus_device *dev = be->dev;
+       u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+
+       err = xenbus_scanf(dev->nodename, "handle", "%li", &handle);
+       if (XENBUS_EXIST_ERR(err))
+               return;
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "reading handle");
+               return;
+       }
+
+       if (be->netif == NULL) {
+               be->netif = alloc_netif(be->frontend_id, handle, be_mac);
+               if (IS_ERR(be->netif)) {
+                       err = PTR_ERR(be->netif);
+                       be->netif = NULL;
+                       xenbus_dev_error(dev, err, "creating interface");
+                       return;
+               }
+
+#if 0
+               err = vbd_create(be->netif, handle, be->pdev, be->readonly);
+               if (err) {
+                       xenbus_dev_error(dev, err, "creating vbd structure");
+                       return;
+               }
+#endif
+
+               /* Pass in NULL node to skip exist test. */
+               frontend_changed(&be->watch, NULL);
+       }
+}
+
+static int netback_probe(struct xenbus_device *dev,
+                        const struct xenbus_device_id *id)
+{
+       struct backend_info *be;
+       char *frontend;
+       int err;
+
+       be = kmalloc(sizeof(*be), GFP_KERNEL);
+       if (!be) {
+               xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
+               return -ENOMEM;
+       }
+       memset(be, 0, sizeof(*be));
+
+       frontend = NULL;
+       err = xenbus_gather(dev->nodename,
+                           "frontend-id", "%li", &be->frontend_id,
+                           "frontend", NULL, &frontend,
+                           NULL);
+       if (XENBUS_EXIST_ERR(err))
+               goto free_be;
+       if (err < 0) {
+               xenbus_dev_error(dev, err,
+                                "reading %s/frontend or frontend-id",
+                                dev->nodename);
+               goto free_be;
+       }
+       if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
+               /* If we can't get a frontend path and a frontend-id,
+                * then our bus-id is no longer valid and we need to
+                * destroy the backend device.
+                */
+               err = -ENOENT;
+               goto free_be;
+       }
+
+       be->dev = dev;
+       be->backend_watch.node = dev->nodename;
+       be->backend_watch.callback = backend_changed;
+       err = register_xenbus_watch(&be->backend_watch);
+       if (err) {
+               be->backend_watch.node = NULL;
+               xenbus_dev_error(dev, err, "adding backend watch on %s",
+                                dev->nodename);
+               goto free_be;
+       }
+
+       be->frontpath = frontend;
+       be->watch.node = be->frontpath;
+       be->watch.callback = frontend_changed;
+       err = register_xenbus_watch(&be->watch);
+       if (err) {
+               be->watch.node = NULL;
+               xenbus_dev_error(dev, err,
+                                "adding frontend watch on %s",
+                                be->frontpath);
+               goto free_be;
+       }
+
+       dev->data = be;
+
+       backend_changed(&be->backend_watch, dev->nodename);
+       return 0;
+
+ free_be:
+       if (be->backend_watch.node)
+               unregister_xenbus_watch(&be->backend_watch);
+       if (frontend)
+               kfree(frontend);
+       kfree(be);
+       return err;
+}
+
+static struct xenbus_device_id netback_ids[] = {
+       { "vif" },
+       { "" }
+};
+
+static struct xenbus_driver netback = {
+       .name = "vif",
+       .owner = THIS_MODULE,
+       .ids = netback_ids,
+       .probe = netback_probe,
+       .remove = netback_remove,
+};
+
+void netif_xenbus_init(void)
+{
+       xenbus_register_backend(&netback);
+}
diff -r e2025593f702 -r 112d44270733 tools/examples/backend.hotplug
--- /dev/null   Wed Aug 24 23:16:52 2005
+++ b/tools/examples/backend.hotplug    Thu Aug 25 18:18:47 2005
@@ -0,0 +1,21 @@
+#! /bin/sh
+
+#DEVPATH=/devices/xen-backend/vif-1-0
+#ACTION=add
+
+PATH=/etc/xen/scripts:$PATH
+
+DEV=$(basename "$DEVPATH")
+case "$ACTION" in
+  add)
+    case "$DEV" in
+      vif-*)
+        vif=$(echo "$DEV" | sed 's/-\([0-9]*\)-\([0-9]*\)/\1.\2/')
+        vif-bridge up domain=unknown vif="$vif" mac=fe:ff:ff:ff:ff:ff 
bridge=xen-br0 >/dev/null 2>&1
+        ;;
+    esac
+    ;;
+  remove)
+    ;;
+esac
+
diff -r e2025593f702 -r 112d44270733 tools/libxc/xenctrl.h
--- /dev/null   Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xenctrl.h     Thu Aug 25 18:18:47 2005
@@ -0,0 +1,526 @@
+/******************************************************************************
+ * xenctrl.h
+ * 
+ * A library for low-level access to the Xen control interfaces.
+ * 
+ * Copyright (c) 2003-2004, K A Fraser.
+ */
+
+#ifndef XENCTRL_H
+#define XENCTRL_H
+
+#include <stdint.h>
+
+typedef uint8_t            u8;
+typedef uint16_t           u16;
+typedef uint32_t           u32;
+typedef uint64_t           u64;
+typedef int8_t             s8;
+typedef int16_t            s16;
+typedef int32_t            s32;
+typedef int64_t            s64;
+
+#include <sys/ptrace.h>
+#include <xen/xen.h>
+#include <xen/dom0_ops.h>
+#include <xen/event_channel.h>
+#include <xen/sched_ctl.h>
+#include <xen/acm.h>
+
+#ifdef __ia64__
+#define XC_PAGE_SHIFT           14
+#else
+#define XC_PAGE_SHIFT           12
+#endif
+#define XC_PAGE_SIZE            (1UL << XC_PAGE_SHIFT)
+#define XC_PAGE_MASK            (~(XC_PAGE_SIZE-1))
+
+/*
+ *  DEFINITIONS FOR CPU BARRIERS
+ */ 
+
+#if defined(__i386__)
+#define mb()  __asm__ __volatile__ ( "lock; addl $0,0(%%esp)" : : : "memory" )
+#define rmb() __asm__ __volatile__ ( "lock; addl $0,0(%%esp)" : : : "memory" )
+#define wmb() __asm__ __volatile__ ( "" : : : "memory")
+#elif defined(__x86_64__)
+#define mb()  __asm__ __volatile__ ( "mfence" : : : "memory")
+#define rmb() __asm__ __volatile__ ( "lfence" : : : "memory")
+#define wmb() __asm__ __volatile__ ( "" : : : "memory")
+#elif defined(__ia64__)
+/* FIXME */
+#define mb()
+#define rmb()
+#define wmb()
+#else
+#error "Define barriers"
+#endif
+
+/*
+ *  INITIALIZATION FUNCTIONS
+ */ 
+
+/**
+ * This function opens a handle to the hypervisor interface.  This function can
+ * be called multiple times within a single process.  Multiple processes can
+ * have an open hypervisor interface at the same time.
+ *
+ * Each call to this function should have a corresponding call to
+ * xc_interface_close().
+ *
+ * This function can fail if the caller does not have superuser permission or
+ * if a Xen-enabled kernel is not currently running.
+ *
+ * @return a handle to the hypervisor interface or -1 on failure
+ */
+int xc_interface_open(void);
+
+/**
+ * This function closes an open hypervisor interface.
+ *
+ * This function can fail if the handle does not represent an open interface or
+ * if there were problems closing the interface.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @return 0 on success, -1 otherwise.
+ */
+int xc_interface_close(int xc_handle);
+
+/*
+ * DOMAIN DEBUGGING FUNCTIONS
+ */
+
+typedef struct xc_core_header {
+    unsigned int xch_magic;
+    unsigned int xch_nr_vcpus;
+    unsigned int xch_nr_pages;
+    unsigned int xch_ctxt_offset;
+    unsigned int xch_index_offset;
+    unsigned int xch_pages_offset;
+} xc_core_header_t;
+
+
+long xc_ptrace(enum __ptrace_request request, 
+               u32  domid,
+               long addr, 
+               long data);
+
+long xc_ptrace_core(enum __ptrace_request request, 
+                    u32 domid, 
+                    long addr, 
+                    long data);
+
+int xc_waitdomain(int domain, 
+                  int *status, 
+                  int options);
+
+int xc_waitdomain_core(int domain, 
+                       int *status, 
+                       int options);
+
+/*
+ * DOMAIN MANAGEMENT FUNCTIONS
+ */
+
+typedef struct {
+    u32           domid;
+    u32           ssidref;
+    unsigned int  dying:1, crashed:1, shutdown:1, 
+                  paused:1, blocked:1, running:1;
+    unsigned int  shutdown_reason; /* only meaningful if shutdown==1 */
+    unsigned long nr_pages;
+    unsigned long shared_info_frame;
+    u64           cpu_time;
+    unsigned long max_memkb;
+    unsigned int  vcpus;
+    s32           vcpu_to_cpu[MAX_VIRT_CPUS];
+    cpumap_t      cpumap[MAX_VIRT_CPUS];
+} xc_dominfo_t;
+
+typedef dom0_getdomaininfo_t xc_domaininfo_t;
+int xc_domain_create(int xc_handle, 
+                     u32 ssidref,
+                     u32 *pdomid);
+
+
+int xc_domain_dumpcore(int xc_handle, 
+                       u32 domid,
+                       const char *corename);
+
+
+/**
+ * This function pauses a domain. A paused domain still exists in memory
+ * however it does not receive any timeslices from the hypervisor.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm domid the domain id to pause
+ * @return 0 on success, -1 on failure.
+ */
+int xc_domain_pause(int xc_handle, 
+                    u32 domid);
+/**
+ * This function unpauses a domain.  The domain should have been previously
+ * paused.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm domid the domain id to unpause
+ * return 0 on success, -1 on failure
+ */
+int xc_domain_unpause(int xc_handle, 
+                      u32 domid);
+
+/**
+ * This function will destroy a domain.  Destroying a domain removes the domain
+ * completely from memory.  This function should be called after sending the
+ * domain a SHUTDOWN control message to free up the domain resources.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm domid the domain id to destroy
+ * @return 0 on success, -1 on failure
+ */
+int xc_domain_destroy(int xc_handle, 
+                      u32 domid);
+int xc_domain_pincpu(int xc_handle,
+                     u32 domid,
+                     int vcpu,
+                     cpumap_t *cpumap);
+/**
+ * This function will return information about one or more domains. It is
+ * designed to iterate over the list of domains. If a single domain is
+ * requested, this function will return the next domain in the list - if
+ * one exists. It is, therefore, important in this case to make sure the
+ * domain requested was the one returned.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm first_domid the first domain to enumerate information from.  Domains
+ *                   are currently enumerate in order of creation.
+ * @parm max_doms the number of elements in info
+ * @parm info an array of max_doms size that will contain the information for
+ *            the enumerated domains.
+ * @return the number of domains enumerated or -1 on error
+ */
+int xc_domain_getinfo(int xc_handle,
+                      u32 first_domid, 
+                      unsigned int max_doms,
+                      xc_dominfo_t *info);
+
+/**
+ * This function will return information about one or more domains, using a
+ * single hypercall.  The domain information will be stored into the supplied
+ * array of xc_domaininfo_t structures.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm first_domain the first domain to enumerate information from.
+ *                    Domains are currently enumerate in order of creation.
+ * @parm max_domains the number of elements in info
+ * @parm info an array of max_doms size that will contain the information for
+ *            the enumerated domains.
+ * @return the number of domains enumerated or -1 on error
+ */
+int xc_domain_getinfolist(int xc_handle,
+                          u32 first_domain,
+                          unsigned int max_domains,
+                          xc_domaininfo_t *info);
+
+/**
+ * This function returns information about one domain.  This information is
+ * more detailed than the information from xc_domain_getinfo().
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm domid the domain to get information from
+ * @parm info a pointer to an xc_domaininfo_t to store the domain information
+ * @parm ctxt a pointer to a structure to store the execution context of the
+ *            domain
+ * @return 0 on success, -1 on failure
+ */
+int xc_domain_get_vcpu_context(int xc_handle,
+                               u32 domid,
+                               u32 vcpu,
+                               vcpu_guest_context_t *ctxt);
+
+int xc_domain_setcpuweight(int xc_handle,
+                           u32 domid,
+                           float weight);
+long long xc_domain_get_cpu_usage(int xc_handle,
+                                  domid_t domid,
+                                  int vcpu);
+
+
+typedef dom0_shadow_control_stats_t xc_shadow_control_stats_t;
+int xc_shadow_control(int xc_handle,
+                      u32 domid, 
+                      unsigned int sop,
+                      unsigned long *dirty_bitmap,
+                      unsigned long pages,
+                      xc_shadow_control_stats_t *stats);
+
+int xc_bvtsched_global_set(int xc_handle,
+                           unsigned long ctx_allow);
+
+int xc_bvtsched_domain_set(int xc_handle,
+                           u32 domid,
+                           u32 mcuadv,
+                           int warpback,
+                           s32 warpvalue,
+                           long long warpl,
+                           long long warpu);
+
+int xc_bvtsched_global_get(int xc_handle,
+                           unsigned long *ctx_allow);
+
+int xc_bvtsched_domain_get(int xc_handle,
+                           u32 domid,
+                           u32 *mcuadv,
+                           int *warpback,
+                           s32 *warpvalue,
+                           long long *warpl,
+                           long long *warpu);
+
+int xc_sedf_domain_set(int xc_handle,
+                          u32 domid,
+                          u64 period, u64 slice, u64 latency, u16 extratime, 
u16 weight);
+
+int xc_sedf_domain_get(int xc_handle,
+                          u32 domid,
+                          u64* period, u64 *slice, u64 *latency, u16 
*extratime, u16* weight);
+
+typedef evtchn_status_t xc_evtchn_status_t;
+
+/*
+ * EVENT CHANNEL FUNCTIONS
+ */
+
+/**
+ * This function allocates an unbound port.  Ports are named endpoints used for
+ * interdomain communication.  This function is most useful in opening a
+ * well-known port within a domain to receive events on.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm dom the ID of the domain.  This maybe DOMID_SELF
+ * @parm port a pointer to a port.  This is an in/out parameter.  If *port is
+ *            0, then a new port will be assigned, if port is > 0 then that
+ *            port is allocated if the port is unallocated.
+ * @return 0 on success, -1 on failure
+ */
+int xc_evtchn_alloc_unbound(int xc_handle,
+                            u32 dom,
+                            int *port);
+
+/**
+ * This function creates a pair of ports between two domains.  A port can only
+ * be bound once within a domain.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm dom1 one of the two domains to connect.  Can be DOMID_SELF.
+ * @parm dom2 the other domain to connect.  Can be DOMID_SELF.
+ * @parm port1 an in/out parameter.  If > 0, then try to connect *port.  If
+ *             0, then allocate a new port and store the port in *port.
+ * @parm port2 the port connected on port2.  This parameter behaves the same
+ *             way as port1.
+ * @return 0 on success, -1 on error.
+ */
+int xc_evtchn_bind_interdomain(int xc_handle,
+                               u32 dom1,
+                               u32 dom2,
+                               int *port1,
+                               int *port2);
+int xc_evtchn_bind_virq(int xc_handle,
+                        int virq,
+                        int *port);
+
+/**
+ * This function will close a single port on an event channel.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm dom the domain that the port exists on.  May be DOMID_SELF.
+ * @parm port the port to close
+ * @return 0 on success, -1 on error
+ */
+int xc_evtchn_close(int xc_handle,
+                    u32 dom,   /* may be DOMID_SELF */
+                    int port);
+
+/**
+ * This function generates a notify event on a bound port.
+ *
+ * Notifies can be read within Linux by opening /dev/xen/evtchn and reading
+ * a 16 bit value.  The result will be the port the event occurred on.  When
+ * events occur, the port is masked until the 16 bit port value is written back
+ * to the file.  When /dev/xen/evtchn is opened, it has to be bound via an
+ * ioctl to each port to listen on.  The ioctl for binding is _IO('E', 2).  The
+ * parameter is the port to listen on.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm local_port the port to generate the notify on
+ * @return 0 on success, -1 on error
+ */
+int xc_evtchn_send(int xc_handle,
+                   int local_port);
+int xc_evtchn_status(int xc_handle,
+                     u32 dom, /* may be DOMID_SELF */
+                     int port,
+                     xc_evtchn_status_t *status);
+
+int xc_physdev_pci_access_modify(int xc_handle,
+                                 u32 domid,
+                                 int bus,
+                                 int dev,
+                                 int func,
+                                 int enable);
+
+int xc_readconsolering(int xc_handle,
+                       char **pbuffer,
+                       unsigned int *pnr_chars, 
+                       int clear);
+
+typedef dom0_physinfo_t xc_physinfo_t;
+int xc_physinfo(int xc_handle,
+                xc_physinfo_t *info);
+
+int xc_sched_id(int xc_handle,
+                int *sched_id);
+
+int xc_domain_setmaxmem(int xc_handle,
+                        u32 domid, 
+                        unsigned int max_memkb);
+
+int xc_domain_memory_increase_reservation(int xc_handle,
+                                          u32 domid, 
+                                          unsigned int mem_kb);
+
+typedef dom0_perfc_desc_t xc_perfc_desc_t;
+/* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */
+int xc_perfc_control(int xc_handle,
+                     u32 op,
+                     xc_perfc_desc_t *desc);
+
+/* read/write msr */
+long long xc_msr_read(int xc_handle, int cpu_mask, int msr);
+int xc_msr_write(int xc_handle, int cpu_mask, int msr, unsigned int low,
+                  unsigned int high);
+
+/**
+ * Memory maps a range within one domain to a local address range.  Mappings
+ * should be unmapped with munmap and should follow the same rules as mmap
+ * regarding page alignment.  Returns NULL on failure.
+ *
+ * In Linux, the ring queue for the control channel is accessible by mapping
+ * the shared_info_frame (from xc_domain_getinfo()) + 2048.  The structure
+ * stored there is of type control_if_t.
+ *
+ * @parm xc_handle a handle on an open hypervisor interface
+ * @parm dom the domain to map memory from
+ * @parm size the amount of memory to map (in multiples of page size)
+ * @parm prot same flag as in mmap().
+ * @parm mfn the frame address to map.
+ */
+void *xc_map_foreign_range(int xc_handle, u32 dom,
+                            int size, int prot,
+                            unsigned long mfn );
+
+void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot,
+                           unsigned long *arr, int num );
+
+int xc_get_pfn_list(int xc_handle, u32 domid, unsigned long *pfn_buf, 
+                    unsigned long max_pfns);
+
+int xc_ia64_get_pfn_list(int xc_handle, u32 domid, unsigned long *pfn_buf, 
+                    unsigned int start_page, unsigned int nr_pages);
+
+int xc_mmuext_op(int xc_handle, struct mmuext_op *op, unsigned int nr_ops,
+                domid_t dom);
+
+int xc_dom_mem_op(int xc_handle, unsigned int memop, unsigned int *extent_list,
+                 unsigned int nr_extents, unsigned int extent_order,
+                 domid_t domid);
+
+int xc_get_pfn_type_batch(int xc_handle, u32 dom, int num, unsigned long *arr);
+
+
+/*\
+ *  GRANT TABLE FUNCTIONS
+\*/ 
+
+/**
+ * This function opens a handle to the more restricted grant table hypervisor
+ * interface. This may be used where the standard interface is not
+ * available because the domain is not privileged.
+ * This function can  be called multiple times within a single process.
+ * Multiple processes can have an open hypervisor interface at the same time.
+ *
+ * Each call to this function should have a corresponding call to
+ * xc_grant_interface_close().
+ *
+ * This function can fail if a Xen-enabled kernel is not currently running.
+ *
+ * @return a handle to the hypervisor grant table interface or -1 on failure
+ */
+int xc_grant_interface_open(void);
+
+/**
+ * This function closes an open grant table hypervisor interface.
+ *
+ * This function can fail if the handle does not represent an open interface or
+ * if there were problems closing the interface.
+ *
+ * @parm xc_handle a handle to an open grant table hypervisor interface
+ * @return 0 on success, -1 otherwise.
+ */
+int xc_grant_interface_close(int xc_handle);
+
+int xc_gnttab_map_grant_ref(int  xc_handle,
+                            u64  host_virt_addr,
+                            u32  dom,
+                            u16  ref,
+                            u16  flags,
+                            s16 *handle,
+                            u64 *dev_bus_addr);
+
+int xc_gnttab_unmap_grant_ref(int  xc_handle,
+                              u64  host_virt_addr,
+                              u64  dev_bus_addr,
+                              u16  handle,
+                              s16 *status);
+
+int xc_gnttab_setup_table(int        xc_handle,
+                          u32        dom,
+                          u16        nr_frames,
+                          s16       *status,
+                          unsigned long **frame_list);
+
+/* Grant debug builds only: */
+int xc_gnttab_dump_table(int        xc_handle,
+                         u32        dom,
+                         s16       *status);
+
+/* Get current total pages allocated to a domain. */
+long xc_get_tot_pages(int xc_handle, u32 domid);
+
+/* Execute a privileged dom0 operation. */
+int xc_dom0_op(int xc_handle, dom0_op_t *op);
+
+/* Initializes the store (for dom0)
+   remote_port should be the remote end of a bound interdomain channel between
+   the store and dom0.
+
+   This function returns a shared frame that should be passed to
+   xs_introduce_domain
+ */
+long xc_init_store(int xc_handle, int remote_port);
+
+/*
+ * MMU updates.
+ */
+#define MAX_MMU_UPDATES 1024
+struct xc_mmu {
+    mmu_update_t updates[MAX_MMU_UPDATES];
+    int          idx;
+    domid_t      subject;
+};
+typedef struct xc_mmu xc_mmu_t;
+xc_mmu_t *xc_init_mmu_updates(int xc_handle, domid_t dom);
+int xc_add_mmu_update(int xc_handle, xc_mmu_t *mmu, 
+                   unsigned long ptr, unsigned long val);
+int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu);
+
+#endif
diff -r e2025593f702 -r 112d44270733 tools/libxc/xenguest.h
--- /dev/null   Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xenguest.h    Thu Aug 25 18:18:47 2005
@@ -0,0 +1,66 @@
+/******************************************************************************
+ * xenguest.h
+ * 
+ * A library for guest domain management in Xen.
+ * 
+ * Copyright (c) 2003-2004, K A Fraser.
+ */
+
+#ifndef XENBUILD_H
+#define XENBUILD_H
+
+#define XCFLAGS_VERBOSE   1
+#define XCFLAGS_LIVE      2
+#define XCFLAGS_DEBUG     4
+#define XCFLAGS_CONFIGURE 8
+
+/**
+ * This function will save a domain running Linux.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm fd the file descriptor to save a domain to
+ * @parm dom the id of the domain
+ * @return 0 on success, -1 on failure
+ */
+int xc_linux_save(int xc_handle, int fd, uint32_t dom);
+
+/**
+ * This function will restore a saved domain running Linux.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm fd the file descriptor to restore a domain from
+ * @parm dom the id of the domain
+ * @parm nr_pfns the number of pages
+ * @parm store_evtchn the store event channel for this domain to use
+ * @parm store_mfn returned with the mfn of the store page
+ * @return 0 on success, -1 on failure
+ */
+int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, unsigned long 
nr_pfns,
+                    unsigned int store_evtchn, unsigned long *store_mfn);
+
+int xc_linux_build(int xc_handle,
+                   uint32_t domid,
+                   const char *image_name,
+                   const char *ramdisk_name,
+                   const char *cmdline,
+                   unsigned int control_evtchn,
+                   unsigned long flags,
+                   unsigned int vcpus,
+                   unsigned int store_evtchn,
+                   unsigned long *store_mfn);
+
+struct mem_map;
+int xc_vmx_build(int xc_handle,
+                 uint32_t domid,
+                 int memsize,
+                 const char *image_name,
+                 struct mem_map *memmap,
+                 const char *ramdisk_name,
+                 const char *cmdline,
+                 unsigned int control_evtchn,
+                 unsigned long flags,
+                 unsigned int vcpus,
+                 unsigned int store_evtchn,
+                 unsigned long *store_mfn);
+
+#endif
diff -r e2025593f702 -r 112d44270733 tools/libxc/xg_private.c
--- /dev/null   Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xg_private.c  Thu Aug 25 18:18:47 2005
@@ -0,0 +1,86 @@
+/******************************************************************************
+ * xg_private.c
+ * 
+ * Helper functions for the rest of the library.
+ */
+
+#include <stdlib.h>
+#include <zlib.h>
+
+#include "xg_private.h"
+
+char *xc_read_kernel_image(const char *filename, unsigned long *size)
+{
+    int kernel_fd = -1;
+    gzFile kernel_gfd = NULL;
+    char *image = NULL;
+    unsigned int bytes;
+
+    if ( (kernel_fd = open(filename, O_RDONLY)) < 0 )
+    {
+        PERROR("Could not open kernel image");
+        goto out;
+    }
+
+    if ( (*size = xc_get_filesz(kernel_fd)) == 0 )
+    {
+        PERROR("Could not read kernel image");
+        goto out;
+    }
+
+    if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL )
+    {
+        PERROR("Could not allocate decompression state for state file");
+        goto out;
+    }
+
+    if ( (image = malloc(*size)) == NULL )
+    {
+        PERROR("Could not allocate memory for kernel image");
+        goto out;
+    }
+
+    if ( (bytes = gzread(kernel_gfd, image, *size)) != *size )
+    {
+        PERROR("Error reading kernel image, could not"
+               " read the whole image (%d != %ld).", bytes, *size);
+        free(image);
+        image = NULL;
+    }
+
+ out:
+    if ( kernel_gfd != NULL )
+        gzclose(kernel_gfd);
+    else if ( kernel_fd >= 0 )
+        close(kernel_fd);
+    return image;
+}
+
+/*******************/
+
+int pin_table(
+    int xc_handle, unsigned int type, unsigned long mfn, domid_t dom)
+{
+    struct mmuext_op op;
+
+    op.cmd = type;
+    op.mfn = mfn;
+
+    if ( xc_mmuext_op(xc_handle, &op, 1, dom) < 0 )
+        return 1;
+
+    return 0;
+}
+
+/* This is shared between save and restore, and may generally be useful. */
+unsigned long csum_page (void * page)
+{
+    int i;
+    unsigned long *p = page;
+    unsigned long long sum=0;
+
+    for ( i = 0; i < (PAGE_SIZE/sizeof(unsigned long)); i++ )
+        sum += p[i];
+
+    return sum ^ (sum>>32);
+}
diff -r e2025593f702 -r 112d44270733 tools/libxc/xg_private.h
--- /dev/null   Wed Aug 24 23:16:52 2005
+++ b/tools/libxc/xg_private.h  Thu Aug 25 18:18:47 2005
@@ -0,0 +1,170 @@
+#ifndef XG_PRIVATE_H
+#define XG_PRIVATE_H
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "xenctrl.h"
+
+#include <xen/linux/privcmd.h>
+
+char *xc_read_kernel_image(const char *filename, unsigned long *size);
+unsigned long csum_page (void * page);
+
+#define _PAGE_PRESENT   0x001
+#define _PAGE_RW        0x002
+#define _PAGE_USER      0x004
+#define _PAGE_PWT       0x008
+#define _PAGE_PCD       0x010
+#define _PAGE_ACCESSED  0x020
+#define _PAGE_DIRTY     0x040
+#define _PAGE_PAT       0x080
+#define _PAGE_PSE       0x080
+#define _PAGE_GLOBAL    0x100
+
+#if defined(__i386__)
+#define L1_PAGETABLE_SHIFT       12
+#define L2_PAGETABLE_SHIFT       22
+#define L1_PAGETABLE_SHIFT_PAE   12
+#define L2_PAGETABLE_SHIFT_PAE   21
+#define L3_PAGETABLE_SHIFT_PAE   30
+#elif defined(__x86_64__)
+#define L1_PAGETABLE_SHIFT      12
+#define L2_PAGETABLE_SHIFT      21
+#define L3_PAGETABLE_SHIFT      30
+#define L4_PAGETABLE_SHIFT      39
+#endif
+
+#if defined(__i386__) 
+#define ENTRIES_PER_L1_PAGETABLE 1024
+#define ENTRIES_PER_L2_PAGETABLE 1024
+#define L1_PAGETABLE_ENTRIES_PAE  512
+#define L2_PAGETABLE_ENTRIES_PAE  512
+#define L3_PAGETABLE_ENTRIES_PAE    4
+#elif defined(__x86_64__)
+#define L1_PAGETABLE_ENTRIES    512
+#define L2_PAGETABLE_ENTRIES    512
+#define L3_PAGETABLE_ENTRIES    512
+#define L4_PAGETABLE_ENTRIES    512
+#endif
+ 
+#define PAGE_SHIFT              XC_PAGE_SHIFT
+#define PAGE_SIZE               (1UL << PAGE_SHIFT)
+#define PAGE_MASK               (~(PAGE_SIZE-1))
+
+typedef u32 l1_pgentry_32_t;
+typedef u32 l2_pgentry_32_t;
+typedef u64 l1_pgentry_64_t;
+typedef u64 l2_pgentry_64_t;
+typedef u64 l3_pgentry_64_t;
+typedef unsigned long l1_pgentry_t;
+typedef unsigned long l2_pgentry_t;
+#if defined(__x86_64__)
+typedef unsigned long l3_pgentry_t;
+typedef unsigned long l4_pgentry_t;
+#endif
+
+#if defined(__i386__)
+#define l1_table_offset(_a) \
+          (((_a) >> L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE - 1))
+#define l2_table_offset(_a) \
+          ((_a) >> L2_PAGETABLE_SHIFT)
+#define l1_table_offset_pae(_a) \
+  (((_a) >> L1_PAGETABLE_SHIFT_PAE) & (L1_PAGETABLE_ENTRIES_PAE - 1))
+#define l2_table_offset_pae(_a) \
+  (((_a) >> L2_PAGETABLE_SHIFT_PAE) & (L2_PAGETABLE_ENTRIES_PAE - 1))
+#define l3_table_offset_pae(_a) \
+       (((_a) >> L3_PAGETABLE_SHIFT_PAE) & (L3_PAGETABLE_ENTRIES_PAE - 1))
+#elif defined(__x86_64__)
+#define l1_table_offset(_a) \
+  (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
+#define l2_table_offset(_a) \
+  (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
+#define l3_table_offset(_a) \
+       (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
+#define l4_table_offset(_a) \
+       (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
+#endif
+
+#define ERROR(_m, _a...)                                \
+do {                                                    \
+    int __saved_errno = errno;                          \
+    fprintf(stderr, "ERROR: " _m "\n" , ## _a );        \
+    errno = __saved_errno;                              \
+} while (0)
+
+
+#define PERROR(_m, _a...)                                       \
+do {                                                            \
+    int __saved_errno = errno;                                  \
+    fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a ,       \
+            __saved_errno, strerror(__saved_errno));            \
+    errno = __saved_errno;                                      \
+} while (0)
+
+
+struct domain_setup_info
+{
+    unsigned long v_start;
+    unsigned long v_end;
+    unsigned long v_kernstart;
+    unsigned long v_kernend;
+    unsigned long v_kernentry;
+
+    unsigned int  load_symtab;
+    unsigned int  pae_kernel;
+    unsigned long symtab_addr;
+    unsigned long symtab_len;
+};
+
+typedef int (*parseimagefunc)(char *image, unsigned long image_size,
+                             struct domain_setup_info *dsi);
+typedef int (*loadimagefunc)(char *image, unsigned long image_size, int xch,
+                            u32 dom, unsigned long *parray,
+                            struct domain_setup_info *dsi);
+
+struct load_funcs
+{
+    parseimagefunc parseimage;
+    loadimagefunc loadimage;
+};
+
+#define mfn_mapper_queue_size 128
+
+typedef struct mfn_mapper {
+    int xc_handle;
+    int size;
+    int prot;
+    int error;
+    int max_queue_size;
+    void * addr;
+    privcmd_mmap_t ioctl; 
+    
+} mfn_mapper_t;
+
+unsigned long xc_get_m2p_start_mfn (int xc_handle);
+
+int xc_copy_to_domain_page(int xc_handle, u32 domid,
+                            unsigned long dst_pfn, void *src_page);
+
+unsigned long xc_get_filesz(int fd);
+
+void xc_map_memcpy(unsigned long dst, char *src, unsigned long size,
+                   int xch, u32 dom, unsigned long *parray,
+                   unsigned long vstart);
+
+int pin_table(int xc_handle, unsigned int type, unsigned long mfn,
+             domid_t dom);
+
+/* image loading */
+int probe_elf(char *image, unsigned long image_size, struct load_funcs *funcs);
+int probe_bin(char *image, unsigned long image_size, struct load_funcs *funcs);
+int probe_aout9(char *image, unsigned long image_size, struct load_funcs 
*funcs);
+
+#endif
+
diff -r e2025593f702 -r 112d44270733 
linux-2.6-xen-sparse/drivers/xen/netback/control.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/control.c        Wed Aug 24 
23:16:52 2005
+++ /dev/null   Thu Aug 25 18:18:47 2005
@@ -1,58 +0,0 @@
-/******************************************************************************
- * arch/xen/drivers/netif/backend/control.c
- * 
- * Routines for interfacing with the control plane.
- * 
- * Copyright (c) 2004, Keir Fraser
- */
-
-#include "common.h"
-
-static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
-{
-    DPRINTK("Received netif backend message, subtype=%d\n", msg->subtype);
-    
-    switch ( msg->subtype )
-    {
-    case CMSG_NETIF_BE_CREATE:
-        netif_create((netif_be_create_t *)&msg->msg[0]);
-        break;        
-    case CMSG_NETIF_BE_DESTROY:
-        netif_destroy((netif_be_destroy_t *)&msg->msg[0]);
-        break;  
-    case CMSG_NETIF_BE_CREDITLIMIT:
-        netif_creditlimit((netif_be_creditlimit_t *)&msg->msg[0]);
-        break;       
-    case CMSG_NETIF_BE_CONNECT:
-        netif_connect((netif_be_connect_t *)&msg->msg[0]);
-        break; 
-    case CMSG_NETIF_BE_DISCONNECT:
-        if ( !netif_disconnect((netif_be_disconnect_t *)&msg->msg[0],msg->id) )
-            return; /* Sending the response is deferred until later. */
-        break;        
-    default:
-        DPRINTK("Parse error while reading message subtype %d, len %d\n",
-                msg->subtype, msg->length);
-        msg->length = 0;
-        break;
-    }
-
-    ctrl_if_send_response(msg);
-}
-
-void netif_ctrlif_init(void)
-{
-    ctrl_msg_t cmsg;
-    netif_be_driver_status_t st;
-
-    (void)ctrl_if_register_receiver(CMSG_NETIF_BE, netif_ctrlif_rx,
-                                    CALLBACK_IN_BLOCKING_CONTEXT);
-
-    /* Send a driver-UP notification to the domain controller. */
-    cmsg.type      = CMSG_NETIF_BE;
-    cmsg.subtype   = CMSG_NETIF_BE_DRIVER_STATUS;
-    cmsg.length    = sizeof(netif_be_driver_status_t);
-    st.status      = NETIF_DRIVER_STATUS_UP;
-    memcpy(cmsg.msg, &st, sizeof(st));
-    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
-}
diff -r e2025593f702 -r 112d44270733 
patches/linux-2.6.12/workaround_double_br_del_if.patch
--- a/patches/linux-2.6.12/workaround_double_br_del_if.patch    Wed Aug 24 
23:16:52 2005
+++ /dev/null   Thu Aug 25 18:18:47 2005
@@ -1,11 +0,0 @@
---- linux-2.6.12/net/bridge/br_if.c    2005-06-17 14:48:29.000000000 -0500
-+++ linux-2.6.12-xen0-smp/net/bridge/br_if.c   2005-08-18 15:17:27.302615846 
-0500
-@@ -382,7 +382,7 @@
- {
-       struct net_bridge_port *p = dev->br_port;
-       
--      if (!p || p->br != br) 
-+      if (!p || p->br != br || p->state == BR_STATE_DISABLED)
-               return -EINVAL;
- 
-       br_sysfs_removeif(p);
diff -r e2025593f702 -r 112d44270733 tools/libxc/xc.h
--- a/tools/libxc/xc.h  Wed Aug 24 23:16:52 2005
+++ /dev/null   Thu Aug 25 18:18:47 2005
@@ -1,558 +0,0 @@
-/******************************************************************************
- * xc.h
- * 
- * A library for low-level access to the Xen control interfaces.
- * 
- * Copyright (c) 2003-2004, K A Fraser.
- */
-
-#ifndef __XC_H__
-#define __XC_H__
-
-#include <stdint.h>
-
-typedef uint8_t            u8;
-typedef uint16_t           u16;
-typedef uint32_t           u32;
-typedef uint64_t           u64;
-typedef int8_t             s8;
-typedef int16_t            s16;
-typedef int32_t            s32;
-typedef int64_t            s64;
-
-#include <sys/ptrace.h>
-#include <xen/xen.h>
-#include <xen/dom0_ops.h>
-#include <xen/event_channel.h>
-#include <xen/sched_ctl.h>
-#include <xen/acm.h>
-
-#ifdef __ia64__
-#define XC_PAGE_SHIFT           14
-#else
-#define XC_PAGE_SHIFT           12
-#endif
-#define XC_PAGE_SIZE            (1UL << XC_PAGE_SHIFT)
-#define XC_PAGE_MASK            (~(XC_PAGE_SIZE-1))
-
-/*
- *  DEFINITIONS FOR CPU BARRIERS
- */ 
-
-#if defined(__i386__)
-#define mb()  __asm__ __volatile__ ( "lock; addl $0,0(%%esp)" : : : "memory" )
-#define rmb() __asm__ __volatile__ ( "lock; addl $0,0(%%esp)" : : : "memory" )
-#define wmb() __asm__ __volatile__ ( "" : : : "memory")
-#elif defined(__x86_64__)
-#define mb()  __asm__ __volatile__ ( "mfence" : : : "memory")
-#define rmb() __asm__ __volatile__ ( "lfence" : : : "memory")
-#define wmb() __asm__ __volatile__ ( "" : : : "memory")
-#elif defined(__ia64__)
-/* FIXME */
-#define mb()
-#define rmb()
-#define wmb()
-#else
-#error "Define barriers"
-#endif
-
-/*
- *  INITIALIZATION FUNCTIONS
- */ 
-
-/**
- * This function opens a handle to the hypervisor interface.  This function can
- * be called multiple times within a single process.  Multiple processes can
- * have an open hypervisor interface at the same time.
- *
- * Each call to this function should have a corresponding call to
- * xc_interface_close().
- *
- * This function can fail if the caller does not have superuser permission or
- * if a Xen-enabled kernel is not currently running.
- *
- * @return a handle to the hypervisor interface or -1 on failure
- */
-int xc_interface_open(void);
-
-/**
- * This function closes an open hypervisor interface.
- *
- * This function can fail if the handle does not represent an open interface or
- * if there were problems closing the interface.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @return 0 on success, -1 otherwise.
- */
-int xc_interface_close(int xc_handle);
-
-/*
- * DOMAIN DEBUGGING FUNCTIONS
- */
-
-typedef struct xc_core_header {
-    unsigned int xch_magic;
-    unsigned int xch_nr_vcpus;
-    unsigned int xch_nr_pages;
-    unsigned int xch_ctxt_offset;
-    unsigned int xch_index_offset;
-    unsigned int xch_pages_offset;
-} xc_core_header_t;
-
-
-long xc_ptrace(enum __ptrace_request request, 
-               u32  domid,
-               long addr, 
-               long data);
-
-long xc_ptrace_core(enum __ptrace_request request, 
-                    u32 domid, 
-                    long addr, 
-                    long data);
-
-int xc_waitdomain(int domain, 
-                  int *status, 
-                  int options);
-
-int xc_waitdomain_core(int domain, 
-                       int *status, 
-                       int options);
-
-/*
- * DOMAIN MANAGEMENT FUNCTIONS
- */
-
-typedef struct {
-    u32           domid;
-    u32           ssidref;
-    unsigned int  dying:1, crashed:1, shutdown:1, 
-                  paused:1, blocked:1, running:1;
-    unsigned int  shutdown_reason; /* only meaningful if shutdown==1 */
-    unsigned long nr_pages;
-    unsigned long shared_info_frame;
-    u64           cpu_time;
-    unsigned long max_memkb;
-    unsigned int  vcpus;
-    s32           vcpu_to_cpu[MAX_VIRT_CPUS];
-    cpumap_t      cpumap[MAX_VIRT_CPUS];
-} xc_dominfo_t;
-
-typedef dom0_getdomaininfo_t xc_domaininfo_t;
-int xc_domain_create(int xc_handle, 
-                     u32 ssidref,
-                     u32 *pdomid);
-
-
-int xc_domain_dumpcore(int xc_handle, 
-                       u32 domid,
-                       const char *corename);
-
-
-/**
- * This function pauses a domain. A paused domain still exists in memory
- * however it does not receive any timeslices from the hypervisor.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm domid the domain id to pause
- * @return 0 on success, -1 on failure.
- */
-int xc_domain_pause(int xc_handle, 
-                    u32 domid);
-/**
- * This function unpauses a domain.  The domain should have been previously
- * paused.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm domid the domain id to unpause
- * return 0 on success, -1 on failure
- */
-int xc_domain_unpause(int xc_handle, 
-                      u32 domid);
-
-/**
- * This function will destroy a domain.  Destroying a domain removes the domain
- * completely from memory.  This function should be called after sending the
- * domain a SHUTDOWN control message to free up the domain resources.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm domid the domain id to destroy
- * @return 0 on success, -1 on failure
- */
-int xc_domain_destroy(int xc_handle, 
-                      u32 domid);
-int xc_domain_pincpu(int xc_handle,
-                     u32 domid,
-                     int vcpu,
-                     cpumap_t *cpumap);
-/**
- * This function will return information about one or more domains. It is
- * designed to iterate over the list of domains. If a single domain is
- * requested, this function will return the next domain in the list - if
- * one exists. It is, therefore, important in this case to make sure the
- * domain requested was the one returned.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm first_domid the first domain to enumerate information from.  Domains
- *                   are currently enumerate in order of creation.
- * @parm max_doms the number of elements in info
- * @parm info an array of max_doms size that will contain the information for
- *            the enumerated domains.
- * @return the number of domains enumerated or -1 on error
- */
-int xc_domain_getinfo(int xc_handle,
-                      u32 first_domid, 
-                      unsigned int max_doms,
-                      xc_dominfo_t *info);
-
-/**
- * This function will return information about one or more domains, using a
- * single hypercall.  The domain information will be stored into the supplied
- * array of xc_domaininfo_t structures.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm first_domain the first domain to enumerate information from.
- *                    Domains are currently enumerate in order of creation.
- * @parm max_domains the number of elements in info
- * @parm info an array of max_doms size that will contain the information for
- *            the enumerated domains.
- * @return the number of domains enumerated or -1 on error
- */
-int xc_domain_getinfolist(int xc_handle,
-                          u32 first_domain,
-                          unsigned int max_domains,
-                          xc_domaininfo_t *info);
-
-/**
- * This function returns information about one domain.  This information is
- * more detailed than the information from xc_domain_getinfo().
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm domid the domain to get information from
- * @parm info a pointer to an xc_domaininfo_t to store the domain information
- * @parm ctxt a pointer to a structure to store the execution context of the
- *            domain
- * @return 0 on success, -1 on failure
- */
-int xc_domain_get_vcpu_context(int xc_handle,
-                               u32 domid,
-                               u32 vcpu,
-                               vcpu_guest_context_t *ctxt);
-
-int xc_domain_setcpuweight(int xc_handle,
-                           u32 domid,
-                           float weight);
-long long xc_domain_get_cpu_usage(int xc_handle,
-                                  domid_t domid,
-                                  int vcpu);
-
-
-typedef dom0_shadow_control_stats_t xc_shadow_control_stats_t;
-int xc_shadow_control(int xc_handle,
-                      u32 domid, 
-                      unsigned int sop,
-                      unsigned long *dirty_bitmap,
-                      unsigned long pages,
-                      xc_shadow_control_stats_t *stats);
-
-
-#define XCFLAGS_VERBOSE   1
-#define XCFLAGS_LIVE      2
-#define XCFLAGS_DEBUG     4
-#define XCFLAGS_CONFIGURE 8
-
-struct XcIOContext;
-
-/**
- * This function will save a domain running Linux.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm fd the file descriptor to save a domain to
- * @parm dom the id of the domain
- * @return 0 on success, -1 on failure
- */
-int xc_linux_save(int xc_handle, int fd, u32 dom);
-
-/**
- * This function will restore a saved domain running Linux.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm fd the file descriptor to restore a domain from
- * @parm dom the id of the domain
- * @parm nr_pfns the number of pages
- * @parm store_evtchn the store event channel for this domain to use
- * @parm store_mfn returned with the mfn of the store page
- * @return 0 on success, -1 on failure
- */
-int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns,
-                    unsigned int store_evtchn, unsigned long *store_mfn);
-
-int xc_linux_build(int xc_handle,
-                   u32 domid,
-                   const char *image_name,
-                   const char *ramdisk_name,
-                   const char *cmdline,
-                   unsigned int control_evtchn,
-                   unsigned long flags,
-                   unsigned int vcpus,
-                   unsigned int store_evtchn,
-                   unsigned long *store_mfn);
-
-struct mem_map;
-int xc_vmx_build(int xc_handle,
-                 u32 domid,
-                 int memsize,
-                 const char *image_name,
-                 struct mem_map *memmap,
-                 const char *ramdisk_name,
-                 const char *cmdline,
-                 unsigned int control_evtchn,
-                 unsigned long flags,
-                 unsigned int vcpus,
-                 unsigned int store_evtchn,
-                 unsigned long *store_mfn);
-
-int xc_bvtsched_global_set(int xc_handle,
-                           unsigned long ctx_allow);
-
-int xc_bvtsched_domain_set(int xc_handle,
-                           u32 domid,
-                           u32 mcuadv,
-                           int warpback,
-                           s32 warpvalue,
-                           long long warpl,
-                           long long warpu);
-
-int xc_bvtsched_global_get(int xc_handle,
-                           unsigned long *ctx_allow);
-
-int xc_bvtsched_domain_get(int xc_handle,
-                           u32 domid,
-                           u32 *mcuadv,
-                           int *warpback,
-                           s32 *warpvalue,
-                           long long *warpl,
-                           long long *warpu);
-
-int xc_sedf_domain_set(int xc_handle,
-                          u32 domid,
-                          u64 period, u64 slice, u64 latency, u16 extratime, 
u16 weight);
-
-int xc_sedf_domain_get(int xc_handle,
-                          u32 domid,
-                          u64* period, u64 *slice, u64 *latency, u16 
*extratime, u16* weight);
-
-typedef evtchn_status_t xc_evtchn_status_t;
-
-/*
- * EVENT CHANNEL FUNCTIONS
- */
-
-/**
- * This function allocates an unbound port.  Ports are named endpoints used for
- * interdomain communication.  This function is most useful in opening a
- * well-known port within a domain to receive events on.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm dom the ID of the domain.  This maybe DOMID_SELF
- * @parm port a pointer to a port.  This is an in/out parameter.  If *port is
- *            0, then a new port will be assigned, if port is > 0 then that
- *            port is allocated if the port is unallocated.
- * @return 0 on success, -1 on failure
- */
-int xc_evtchn_alloc_unbound(int xc_handle,
-                            u32 dom,
-                            int *port);
-
-/**
- * This function creates a pair of ports between two domains.  A port can only
- * be bound once within a domain.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm dom1 one of the two domains to connect.  Can be DOMID_SELF.
- * @parm dom2 the other domain to connect.  Can be DOMID_SELF.
- * @parm port1 an in/out parameter.  If > 0, then try to connect *port.  If
- *             0, then allocate a new port and store the port in *port.
- * @parm port2 the port connected on port2.  This parameter behaves the same
- *             way as port1.
- * @return 0 on success, -1 on error.
- */
-int xc_evtchn_bind_interdomain(int xc_handle,
-                               u32 dom1,
-                               u32 dom2,
-                               int *port1,
-                               int *port2);
-int xc_evtchn_bind_virq(int xc_handle,
-                        int virq,
-                        int *port);
-
-/**
- * This function will close a single port on an event channel.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm dom the domain that the port exists on.  May be DOMID_SELF.
- * @parm port the port to close
- * @return 0 on success, -1 on error
- */
-int xc_evtchn_close(int xc_handle,
-                    u32 dom,   /* may be DOMID_SELF */
-                    int port);
-
-/**
- * This function generates a notify event on a bound port.
- *
- * Notifies can be read within Linux by opening /dev/xen/evtchn and reading
- * a 16 bit value.  The result will be the port the event occurred on.  When
- * events occur, the port is masked until the 16 bit port value is written back
- * to the file.  When /dev/xen/evtchn is opened, it has to be bound via an
- * ioctl to each port to listen on.  The ioctl for binding is _IO('E', 2).  The
- * parameter is the port to listen on.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm local_port the port to generate the notify on
- * @return 0 on success, -1 on error
- */
-int xc_evtchn_send(int xc_handle,
-                   int local_port);
-int xc_evtchn_status(int xc_handle,
-                     u32 dom, /* may be DOMID_SELF */
-                     int port,
-                     xc_evtchn_status_t *status);
-
-int xc_physdev_pci_access_modify(int xc_handle,
-                                 u32 domid,
-                                 int bus,
-                                 int dev,
-                                 int func,
-                                 int enable);
-
-int xc_readconsolering(int xc_handle,
-                       char **pbuffer,
-                       unsigned int *pnr_chars, 
-                       int clear);
-
-typedef dom0_physinfo_t xc_physinfo_t;
-int xc_physinfo(int xc_handle,
-                xc_physinfo_t *info);
-
-int xc_sched_id(int xc_handle,
-                int *sched_id);
-
-int xc_domain_setmaxmem(int xc_handle,
-                        u32 domid, 
-                        unsigned int max_memkb);
-
-int xc_domain_memory_increase_reservation(int xc_handle,
-                                          u32 domid, 
-                                          unsigned int mem_kb);
-
-typedef dom0_perfc_desc_t xc_perfc_desc_t;
-/* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */
-int xc_perfc_control(int xc_handle,
-                     u32 op,
-                     xc_perfc_desc_t *desc);
-
-/* read/write msr */
-long long xc_msr_read(int xc_handle, int cpu_mask, int msr);
-int xc_msr_write(int xc_handle, int cpu_mask, int msr, unsigned int low,
-                  unsigned int high);
-
-/**
- * Memory maps a range within one domain to a local address range.  Mappings
- * should be unmapped with munmap and should follow the same rules as mmap
- * regarding page alignment.  Returns NULL on failure.
- *
- * In Linux, the ring queue for the control channel is accessible by mapping
- * the shared_info_frame (from xc_domain_getinfo()) + 2048.  The structure
- * stored there is of type control_if_t.
- *
- * @parm xc_handle a handle on an open hypervisor interface
- * @parm dom the domain to map memory from
- * @parm size the amount of memory to map (in multiples of page size)
- * @parm prot same flag as in mmap().
- * @parm mfn the frame address to map.
- */
-void *xc_map_foreign_range(int xc_handle, u32 dom,
-                            int size, int prot,
-                            unsigned long mfn );
-
-void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot,
-                           unsigned long *arr, int num );
-
-int xc_get_pfn_list(int xc_handle, u32 domid, unsigned long *pfn_buf, 
-                    unsigned long max_pfns);
-
-int xc_ia64_get_pfn_list(int xc_handle, u32 domid, unsigned long *pfn_buf, 
-                    unsigned int start_page, unsigned int nr_pages);
-
-/*\
- *  GRANT TABLE FUNCTIONS
-\*/ 
-
-/**
- * This function opens a handle to the more restricted grant table hypervisor
- * interface. This may be used where the standard interface is not
- * available because the domain is not privileged.
- * This function can  be called multiple times within a single process.
- * Multiple processes can have an open hypervisor interface at the same time.
- *
- * Each call to this function should have a corresponding call to
- * xc_grant_interface_close().
- *
- * This function can fail if a Xen-enabled kernel is not currently running.
- *
- * @return a handle to the hypervisor grant table interface or -1 on failure
- */
-int xc_grant_interface_open(void);
-
-/**
- * This function closes an open grant table hypervisor interface.
- *
- * This function can fail if the handle does not represent an open interface or
- * if there were problems closing the interface.
- *
- * @parm xc_handle a handle to an open grant table hypervisor interface
- * @return 0 on success, -1 otherwise.
- */
-int xc_grant_interface_close(int xc_handle);
-
-int xc_gnttab_map_grant_ref(int  xc_handle,
-                            u64  host_virt_addr,
-                            u32  dom,
-                            u16  ref,
-                            u16  flags,
-                            s16 *handle,
-                            u64 *dev_bus_addr);
-
-int xc_gnttab_unmap_grant_ref(int  xc_handle,
-                              u64  host_virt_addr,
-                              u64  dev_bus_addr,
-                              u16  handle,
-                              s16 *status);
-
-int xc_gnttab_setup_table(int        xc_handle,
-                          u32        dom,
-                          u16        nr_frames,
-                          s16       *status,
-                          unsigned long **frame_list);
-
-/* Grant debug builds only: */
-int xc_gnttab_dump_table(int        xc_handle,
-                         u32        dom,
-                         s16       *status);
-
-/* Get current total pages allocated to a domain. */
-long xc_get_tot_pages(int xc_handle, u32 domid);
-
-/* Execute a privileged dom0 operation. */
-int xc_dom0_op(int xc_handle, dom0_op_t *op);
-
-/* Initializes the store (for dom0)
-   remote_port should be the remote end of a bound interdomain channel between
-   the store and dom0.
-
-   This function returns a shared frame that should be passed to
-   xs_introduce_domain
- */
-long xc_init_store(int xc_handle, int remote_port);
-
-#endif /* __XC_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.