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

[Xen-changelog] Merge.



# HG changeset patch
# User adsharma@xxxxxxxxxxxxxxxxxxxx
# Node ID 81576d3d1ca891cdcd81fada9025b2279a974458
# Parent  99914b54f7bffc8c27757a1ac2bc7a0d97597ac8
# Parent  0608852073c86cfa432ac32cb9223531950be896
Merge.

diff -r 99914b54f7bf -r 81576d3d1ca8 Config.mk
--- a/Config.mk Thu Aug 18 18:40:02 2005
+++ b/Config.mk Fri Aug 19 18:19:28 2005
@@ -35,3 +35,11 @@
 
 # Choose the best mirror to download linux kernel
 KERNEL_REPO = http://www.kernel.org
+
+# ACM_USE_SECURITY_POLICY is set to security policy of Xen
+# Supported models are:
+#      ACM_NULL_POLICY (ACM will not be built with this policy)
+#      ACM_CHINESE_WALL_POLICY
+#      ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY
+#      ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY
+ACM_USE_SECURITY_POLICY ?= ACM_NULL_POLICY
diff -r 99914b54f7bf -r 81576d3d1ca8 docs/src/user.tex
--- a/docs/src/user.tex Thu Aug 18 18:40:02 2005
+++ b/docs/src/user.tex Fri Aug 19 18:19:28 2005
@@ -1763,7 +1763,7 @@
  physical address in the memory map will be ignored. This parameter
  may be specified with a B, K, M or G suffix, representing bytes,
  kilobytes, megabytes and gigabytes respectively. The
- default unit, if no suffix is specified, is bytes.
+ default unit, if no suffix is specified, is kilobytes.
 
 \item [dom0\_mem=xxx ] 
  Set the amount of memory to be allocated to domain0. In Xen 3.x the parameter
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile        Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile        Fri Aug 19 
18:19:28 2005
@@ -14,8 +14,7 @@
 
 c-obj-y        := semaphore.o vm86.o \
                ptrace.o sys_i386.o \
-               i387.o dmi_scan.o bootflag.o \
-               doublefault.o
+               i387.o dmi_scan.o bootflag.o
 s-obj-y        :=
 
 obj-y                          += cpu/
@@ -85,7 +84,7 @@
                        $(obj)/vsyscall-sysenter.o FORCE
        $(call if_changed,syscall)
 
-c-link := init_task.o
+c-link :=
 s-link := vsyscall-int80.o vsyscall-sysenter.o vsyscall-sigreturn.o 
vsyscall.lds.o syscall_table.o
 
 $(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-obj-m) $(c-link)) $(patsubst 
%.o,$(obj)/%.S,$(s-obj-y) $(s-link)):
diff -r 99914b54f7bf -r 81576d3d1ca8 
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    Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c    Fri Aug 19 
18:19:28 2005
@@ -569,7 +569,7 @@
        for (va = gdt_descr->address, f = 0;
             va < gdt_descr->address + gdt_descr->size;
             va += PAGE_SIZE, f++) {
-               frames[f] = virt_to_machine(va) >> PAGE_SHIFT;
+               frames[f] = virt_to_mfn(va);
                make_page_readonly((void *)va);
        }
        if (HYPERVISOR_set_gdt(frames, gdt_descr->size / 8))
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S  Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S  Fri Aug 19 18:19:28 2005
@@ -136,9 +136,6 @@
 ENTRY(empty_zero_page)
 
 .org 0x2000
-ENTRY(swapper_pg_dir)
-
-.org 0x3000
 ENTRY(cpu_gdt_table)
        .quad 0x0000000000000000        /* NULL descriptor */
        .quad 0x0000000000000000        /* 0x0b reserved */
@@ -190,10 +187,10 @@
        .quad 0x0000000000000000        /* 0xf8 - GDT entry 31: double-fault 
TSS */
        .fill GDT_ENTRIES-32,8,0
 
-.org 0x4000
+.org 0x3000
 ENTRY(default_ldt)
 
-.org 0x5000
+.org 0x4000
 /*
  * Real beginning of normal "text" segment
  */
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/i386/kernel/ioport.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/ioport.c        Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/ioport.c        Fri Aug 19 
18:19:28 2005
@@ -80,7 +80,7 @@
                t->io_bitmap_ptr = bitmap;
 
                op.cmd = PHYSDEVOP_SET_IOBITMAP;
-               op.u.set_iobitmap.bitmap   = (unsigned long)bitmap;
+               op.u.set_iobitmap.bitmap   = (char *)bitmap;
                op.u.set_iobitmap.nr_ports = IO_BITMAP_BITS;
                HYPERVISOR_physdev_op(&op);
        }
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c   Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c   Fri Aug 19 18:19:28 2005
@@ -198,7 +198,7 @@
 {
        struct mm_struct * mm = current->mm;
        __u32 entry_1, entry_2, *lp;
-       unsigned long mach_lp;
+       maddr_t mach_lp;
        int error;
        struct user_desc ldt_info;
 
@@ -245,7 +245,8 @@
 
        /* Install the new entry ...  */
 install:
-       error = HYPERVISOR_update_descriptor(mach_lp, entry_1, entry_2);
+       error = HYPERVISOR_update_descriptor(
+               mach_lp, (u64)entry_1 | ((u64)entry_2<<32));
 
 out_unlock:
        up(&mm->context.sem);
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c       Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c       Fri Aug 19 
18:19:28 2005
@@ -115,20 +115,12 @@
 /* We don't actually take CPU down, just spin without interrupts. */
 static inline void play_dead(void)
 {
-       /* Ack it */
-       __get_cpu_var(cpu_state) = CPU_DEAD;
-
-       /* We shouldn't have to disable interrupts while dead, but
-        * some interrupts just don't seem to go away, and this makes
-        * it "work" for testing purposes. */
        /* Death loop */
        while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
                HYPERVISOR_yield();
 
-       local_irq_disable();
        __flush_tlb_all();
        cpu_set(smp_processor_id(), cpu_online_map);
-       local_irq_enable();
 }
 #else
 static inline void play_dead(void)
@@ -156,12 +148,19 @@
                        rmb();
 
                        if (cpu_is_offline(cpu)) {
+                               local_irq_disable();
+                               /* Ack it.  From this point on until
+                                  we get woken up, we're not allowed
+                                  to take any locks.  In particular,
+                                  don't printk. */
+                               __get_cpu_var(cpu_state) = CPU_DEAD;
 #if defined(CONFIG_XEN) && defined(CONFIG_HOTPLUG_CPU)
                                /* Tell hypervisor to take vcpu down. */
                                HYPERVISOR_vcpu_down(cpu);
 #endif
                                play_dead();
-         }
+                               local_irq_enable();
+                       }
 
                        __get_cpu_var(irq_stat).idle_timestamp = jiffies;
                        xen_idle();
@@ -523,16 +522,15 @@
         * Load the per-thread Thread-Local Storage descriptor.
         * This is load_TLS(next, cpu) with multicalls.
         */
-#define C(i) do {                                                       \
-       if (unlikely(next->tls_array[i].a != prev->tls_array[i].a ||    \
-                    next->tls_array[i].b != prev->tls_array[i].b)) {   \
-               mcl->op      = __HYPERVISOR_update_descriptor;          \
-               mcl->args[0] = virt_to_machine(&get_cpu_gdt_table(cpu)  \
-                                        [GDT_ENTRY_TLS_MIN + i]);      \
-               mcl->args[1] = ((u32 *)&next->tls_array[i])[0];         \
-               mcl->args[2] = ((u32 *)&next->tls_array[i])[1];         \
-               mcl++;                                                  \
-       }                                                               \
+#define C(i) do {                                                      \
+       if (unlikely(next->tls_array[i].a != prev->tls_array[i].a ||    \
+                    next->tls_array[i].b != prev->tls_array[i].b)) {   \
+               mcl->op = __HYPERVISOR_update_descriptor;               \
+               *(u64 *)&mcl->args[0] = virt_to_machine(                \
+                       &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i]);\
+               *(u64 *)&mcl->args[2] = *(u64 *)&next->tls_array[i];    \
+               mcl++;                                                  \
+       }                                                               \
 } while (0)
        C(0); C(1); C(2);
 #undef C
@@ -549,7 +547,7 @@
                iobmp_op.cmd                     =
                        PHYSDEVOP_SET_IOBITMAP;
                iobmp_op.u.set_iobitmap.bitmap   =
-                       (unsigned long)next->io_bitmap_ptr;
+                       (char *)next->io_bitmap_ptr;
                iobmp_op.u.set_iobitmap.nr_ports =
                        next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
                mcl->op      = __HYPERVISOR_physdev_op;
@@ -791,3 +789,10 @@
                sp -= get_random_int() % 8192;
        return sp & ~0xf;
 }
+
+
+#ifndef CONFIG_X86_SMP
+void _restore_vcpu(void)
+{
+}
+#endif
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c Fri Aug 19 18:19:28 2005
@@ -1604,11 +1604,10 @@
        for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
        {       
             pfn_to_mfn_frame_list[j] = 
-                 virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT;
+                 virt_to_mfn(&phys_to_machine_mapping[i]);
        }
        HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list =
-            virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT;
-
+            virt_to_mfn(pfn_to_mfn_frame_list);
 
        /*
         * NOTE: at this point the bootmem allocator is fully available.
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Fri Aug 19 
18:19:28 2005
@@ -904,7 +904,7 @@
                for (va = cpu_gdt_descr[cpu].address, f = 0;
                     va < cpu_gdt_descr[cpu].address + cpu_gdt_descr[cpu].size;
                     va += PAGE_SIZE, f++) {
-                       ctxt.gdt_frames[f] = virt_to_machine(va) >> PAGE_SHIFT;
+                       ctxt.gdt_frames[f] = virt_to_mfn(va);
                        make_page_readonly((void *)va);
                }
                ctxt.gdt_ents = cpu_gdt_descr[cpu].size / 8;
@@ -920,7 +920,7 @@
        ctxt.failsafe_callback_cs  = __KERNEL_CS;
        ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
 
-       ctxt.ctrlreg[3] = (unsigned long)virt_to_machine(swapper_pg_dir);
+       ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT;
 
        boot_error = HYPERVISOR_boot_vcpu(cpu, &ctxt);
        printk("boot error: %ld\n", boot_error);
@@ -1616,3 +1616,21 @@
        smp_intr_init();
        local_setup_timer_irq();
 }
+
+DECLARE_PER_CPU(int, timer_irq);
+
+void _restore_vcpu(void)
+{
+       int cpu = smp_processor_id();
+       extern atomic_t vcpus_rebooting;
+
+       /* We are the first thing the vcpu runs when it comes back,
+          and we are supposed to restore the IPIs and timer
+          interrupts etc.  When we return, the vcpu's idle loop will
+          start up again. */
+       _bind_virq_to_irq(VIRQ_TIMER, cpu, per_cpu(timer_irq, cpu));
+       _bind_virq_to_irq(VIRQ_DEBUG, cpu, per_cpu(ldebug_irq, cpu));
+       _bind_ipi_to_irq(RESCHEDULE_VECTOR, cpu, per_cpu(resched_irq, cpu) );
+       _bind_ipi_to_irq(CALL_FUNCTION_VECTOR, cpu, per_cpu(callfunc_irq, cpu) 
);
+       atomic_dec(&vcpus_rebooting);
+}
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c       Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c       Fri Aug 19 
18:19:28 2005
@@ -94,9 +94,6 @@
                iotlb_nslabs = simple_strtoul(str, &str, 0) <<
                        (20 - IO_TLB_SHIFT);
                iotlb_nslabs = ALIGN(iotlb_nslabs, IO_TLB_SEGSIZE);
-               /* Round up to power of two (xen_create_contiguous_region). */
-               while (iotlb_nslabs & (iotlb_nslabs-1))
-                       iotlb_nslabs += iotlb_nslabs & ~(iotlb_nslabs-1);
        }
        if (*str == ',')
                ++str;
@@ -123,9 +120,6 @@
        if (!iotlb_nslabs) {
                iotlb_nslabs = (default_size >> IO_TLB_SHIFT);
                iotlb_nslabs = ALIGN(iotlb_nslabs, IO_TLB_SEGSIZE);
-               /* Round up to power of two (xen_create_contiguous_region). */
-               while (iotlb_nslabs & (iotlb_nslabs-1))
-                       iotlb_nslabs += iotlb_nslabs & ~(iotlb_nslabs-1);
        }
 
        bytes = iotlb_nslabs * (1UL << IO_TLB_SHIFT);
@@ -135,10 +129,14 @@
         */
        iotlb_virt_start = alloc_bootmem_low_pages(bytes);
        if (!iotlb_virt_start)
-               panic("Cannot allocate SWIOTLB buffer");
-
-       xen_create_contiguous_region(
-               (unsigned long)iotlb_virt_start, get_order(bytes));
+               panic("Cannot allocate SWIOTLB buffer!\n"
+                     "Use dom0_mem Xen boot parameter to reserve\n"
+                     "some DMA memory (e.g., dom0_mem=-128M).\n");
+
+       for (i = 0; i < iotlb_nslabs; i += IO_TLB_SEGSIZE)
+               xen_create_contiguous_region(
+                       (unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT),
+                       get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT));
 
        iotlb_virt_end = iotlb_virt_start + bytes;
 
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c  Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c  Fri Aug 19 18:19:28 2005
@@ -745,7 +745,7 @@
 #endif
 
 /* Dynamically-mapped IRQ. */
-static DEFINE_PER_CPU(int, timer_irq);
+DEFINE_PER_CPU(int, timer_irq);
 
 static struct irqaction irq_timer = {
        timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer0",
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/i386/mm/init.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c      Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c      Fri Aug 19 18:19:28 2005
@@ -342,11 +342,15 @@
 extern void __init remap_numa_kva(void);
 #endif
 
+pgd_t *swapper_pg_dir;
+
 static void __init pagetable_init (void)
 {
        unsigned long vaddr;
-       pgd_t *pgd_base = swapper_pg_dir;
-       pgd_t *old_pgd = (pgd_t *)xen_start_info.pt_base;
+       pgd_t *pgd_base = (pgd_t *)xen_start_info.pt_base;
+
+       swapper_pg_dir = pgd_base;
+       init_mm.pgd    = pgd_base;
 
 #ifdef CONFIG_X86_PAE
        int i;
@@ -366,44 +370,6 @@
                __PAGE_KERNEL |= _PAGE_GLOBAL;
                __PAGE_KERNEL_EXEC |= _PAGE_GLOBAL;
        }
-
-       /*
-        * Switch to proper mm_init page directory. Initialise from the current
-        * page directory, write-protect the new page directory, then switch to
-        * it. We clean up by write-enabling and then freeing the old page dir.
-        */
-#ifndef CONFIG_X86_PAE
-       memcpy(pgd_base, old_pgd, PTRS_PER_PGD_NO_HV*sizeof(pgd_t));
-       make_page_readonly(pgd_base);
-       xen_pgd_pin(__pa(pgd_base));
-       load_cr3(pgd_base);
-       xen_pgd_unpin(__pa(old_pgd));
-       make_page_writable(old_pgd);
-       __flush_tlb_all();
-       free_bootmem(__pa(old_pgd), PAGE_SIZE);
-#else
-       {
-               pud_t *old_pud = pud_offset(old_pgd+3, PAGE_OFFSET);
-               pmd_t *old_pmd = pmd_offset(old_pud, PAGE_OFFSET);
-               pmd_t *new_pmd = alloc_bootmem_low_pages(PAGE_SIZE);
-
-               memcpy(new_pmd,  old_pmd, PAGE_SIZE);
-               memcpy(pgd_base, old_pgd, PTRS_PER_PGD_NO_HV*sizeof(pgd_t));
-               set_pgd(&pgd_base[3], __pgd(__pa(new_pmd) | _PAGE_PRESENT));
-
-               make_page_readonly(new_pmd);
-               make_page_readonly(pgd_base);
-               xen_pgd_pin(__pa(pgd_base));
-               load_cr3(pgd_base);
-               xen_pgd_unpin(__pa(old_pgd));
-               make_page_writable(old_pgd);
-               make_page_writable(old_pmd);
-               __flush_tlb_all();
-
-               free_bootmem(__pa(old_pgd), PAGE_SIZE);
-               free_bootmem(__pa(old_pmd), PAGE_SIZE);
-       }
-#endif
 
        init_mm.context.pinned = 1;
        kernel_physical_mapping_init(pgd_base);
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c   Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c   Fri Aug 19 18:19:28 2005
@@ -306,7 +306,7 @@
 {
        mmu_update_t **v = (mmu_update_t **)data;
 
-       (*v)->ptr = ((physaddr_t)pfn_to_mfn(page_to_pfn(pte_page)) <<
+       (*v)->ptr = ((maddr_t)pfn_to_mfn(page_to_pfn(pte_page)) <<
                     PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
        (*v)++;
 
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c   Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c   Fri Aug 19 18:19:28 2005
@@ -170,7 +170,7 @@
        __flush_tlb_one(vaddr);
 }
 
-void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t 
flags)
+void __set_fixmap (enum fixed_addresses idx, maddr_t phys, pgprot_t flags)
 {
        unsigned long address = __fix_to_virt(idx);
 
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Fri Aug 19 18:19:28 2005
@@ -144,7 +144,7 @@
     vcpu_info_t   *vcpu_info = &s->vcpu_data[cpu];
 
     vcpu_info->evtchn_upcall_pending = 0;
-    
+
     /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
     l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
     while ( l1 != 0 )
@@ -158,9 +158,9 @@
             l2 &= ~(1 << l2i);
             
             port = (l1i << 5) + l2i;
-            if ( (irq = evtchn_to_irq[port]) != -1 )
+            if ( (irq = evtchn_to_irq[port]) != -1 ) {
                 do_IRQ(irq, regs);
-            else
+           } else
                 evtchn_device_upcall(port);
         }
     }
@@ -243,6 +243,74 @@
     }
 
     spin_unlock(&irq_mapping_update_lock);
+}
+
+/* This is only used when a vcpu from an xm save.  The ipi is expected
+   to have been bound before we suspended, and so all of the xenolinux
+   state is set up; we only need to restore the Xen side of things.
+   The irq number has to be the same, but the evtchn number can
+   change. */
+void _bind_ipi_to_irq(int ipi, int vcpu, int irq)
+{
+    evtchn_op_t op;
+    int evtchn;
+
+    spin_lock(&irq_mapping_update_lock);
+
+    op.cmd = EVTCHNOP_bind_ipi;
+    if ( HYPERVISOR_event_channel_op(&op) != 0 )
+       panic("Failed to bind virtual IPI %d on cpu %d\n", ipi, vcpu);
+    evtchn = op.u.bind_ipi.port;
+
+    printk("<0>IPI %d, old evtchn %d, evtchn %d.\n",
+          ipi, per_cpu(ipi_to_evtchn, vcpu)[ipi],
+          evtchn);
+
+    evtchn_to_irq[irq_to_evtchn[irq]] = -1;
+    irq_to_evtchn[irq] = -1;
+
+    evtchn_to_irq[evtchn] = irq;
+    irq_to_evtchn[irq]    = evtchn;
+
+    printk("<0>evtchn_to_irq[%d] = %d.\n", evtchn,
+          evtchn_to_irq[evtchn]);
+    per_cpu(ipi_to_evtchn, vcpu)[ipi] = evtchn;
+
+    bind_evtchn_to_cpu(evtchn, vcpu);
+
+    spin_unlock(&irq_mapping_update_lock);
+
+    clear_bit(evtchn, (unsigned long *)HYPERVISOR_shared_info->evtchn_mask);
+    clear_bit(evtchn, (unsigned long *)HYPERVISOR_shared_info->evtchn_pending);
+}
+
+void _bind_virq_to_irq(int virq, int cpu, int irq)
+{
+    evtchn_op_t op;
+    int evtchn;
+
+    spin_lock(&irq_mapping_update_lock);
+
+    op.cmd              = EVTCHNOP_bind_virq;
+    op.u.bind_virq.virq = virq;
+    if ( HYPERVISOR_event_channel_op(&op) != 0 )
+            panic("Failed to bind virtual IRQ %d\n", virq);
+    evtchn = op.u.bind_virq.port;
+
+    evtchn_to_irq[irq_to_evtchn[irq]] = -1;
+    irq_to_evtchn[irq] = -1;
+
+    evtchn_to_irq[evtchn] = irq;
+    irq_to_evtchn[irq]    = evtchn;
+
+    per_cpu(virq_to_irq, cpu)[virq] = irq;
+
+    bind_evtchn_to_cpu(evtchn, cpu);
+
+    spin_unlock(&irq_mapping_update_lock);
+
+    clear_bit(evtchn, (unsigned long *)HYPERVISOR_shared_info->evtchn_mask);
+    clear_bit(evtchn, (unsigned long *)HYPERVISOR_shared_info->evtchn_pending);
 }
 
 int bind_ipi_to_irq(int ipi)
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Fri Aug 19 18:19:28 2005
@@ -16,6 +16,8 @@
 #include <asm-xen/queues.h>
 #include <asm-xen/xenbus.h>
 #include <asm-xen/ctrl_if.h>
+#include <linux/cpu.h>
+#include <linux/kthread.h>
 
 #define SHUTDOWN_INVALID  -1
 #define SHUTDOWN_POWEROFF  0
@@ -58,20 +60,74 @@
 /* Ignore multiple shutdown requests. */
 static int shutting_down = SHUTDOWN_INVALID;
 
-static void __do_suspend(void)
+#ifndef CONFIG_HOTPLUG_CPU
+#define cpu_down(x) (-EOPNOTSUPP)
+#define cpu_up(x) (-EOPNOTSUPP)
+#endif
+
+static void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
+{
+    int r;
+    int gdt_pages;
+    r = HYPERVISOR_vcpu_pickle(vcpu, ctxt);
+    if (r != 0)
+       panic("pickling vcpu %d -> %d!\n", vcpu, r);
+
+    /* Translate from machine to physical addresses where necessary,
+       so that they can be translated to our new machine address space
+       after resume.  libxc is responsible for doing this to vcpu0,
+       but we do it to the others. */
+    gdt_pages = (ctxt->gdt_ents + 511) / 512;
+    ctxt->ctrlreg[3] = machine_to_phys(ctxt->ctrlreg[3]);
+    for (r = 0; r < gdt_pages; r++)
+       ctxt->gdt_frames[r] = mfn_to_pfn(ctxt->gdt_frames[r]);
+}
+
+void _restore_vcpu(int cpu);
+
+atomic_t vcpus_rebooting;
+
+static int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
+{
+    int r;
+    int gdt_pages = (ctxt->gdt_ents + 511) / 512;
+
+    /* This is kind of a hack, and implicitly relies on the fact that
+       the vcpu stops in a place where all of the call clobbered
+       registers are already dead. */
+    ctxt->user_regs.esp -= 4;
+    ((unsigned long *)ctxt->user_regs.esp)[0] = ctxt->user_regs.eip;
+    ctxt->user_regs.eip = (unsigned long)_restore_vcpu;
+
+    /* De-canonicalise.  libxc handles this for vcpu 0, but we need
+       to do it for the other vcpus. */
+    ctxt->ctrlreg[3] = phys_to_machine(ctxt->ctrlreg[3]);
+    for (r = 0; r < gdt_pages; r++)
+       ctxt->gdt_frames[r] = pfn_to_mfn(ctxt->gdt_frames[r]);
+
+    atomic_set(&vcpus_rebooting, 1);
+    r = HYPERVISOR_boot_vcpu(vcpu, ctxt);
+    if (r != 0) {
+       printk(KERN_EMERG "Failed to reboot vcpu %d (%d)\n", vcpu, r);
+       return -1;
+    }
+
+    /* Make sure we wait for the new vcpu to come up before trying to do
+       anything with it or starting the next one. */
+    while (atomic_read(&vcpus_rebooting))
+       barrier();
+
+    return 0;
+}
+
+static int __do_suspend(void *ignore)
 {
     int i, j;
     suspend_record_t *suspend_record;
+    static vcpu_guest_context_t suspended_cpu_records[NR_CPUS];
 
     /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
        /* XXX SMH: yes it would :-( */ 
-#ifdef CONFIG_XEN_BLKDEV_FRONTEND
-    extern void blkdev_suspend(void);
-    extern void blkdev_resume(void);
-#else
-#define blkdev_suspend() do{}while(0)
-#define blkdev_resume()  do{}while(0)
-#endif
 
 #ifdef CONFIG_XEN_NETDEV_FRONTEND
     extern void netif_suspend(void);
@@ -104,13 +160,63 @@
     extern unsigned long max_pfn;
     extern unsigned int *pfn_to_mfn_frame_list;
 
+    cpumask_t prev_online_cpus, prev_present_cpus;
+    int err = 0;
+
+    BUG_ON(smp_processor_id() != 0);
+    BUG_ON(in_interrupt());
+
+#if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
+    if (num_online_cpus() > 1) {
+       printk(KERN_WARNING "Can't suspend SMP guests without 
CONFIG_HOTPLUG_CPU\n");
+       return -EOPNOTSUPP;
+    }
+#endif
+
     suspend_record = (suspend_record_t *)__get_free_page(GFP_KERNEL);
     if ( suspend_record == NULL )
         goto out;
 
+    /* Take all of the other cpus offline.  We need to be careful not
+       to get preempted between the final test for num_online_cpus()
+       == 1 and disabling interrupts, since otherwise userspace could
+       bring another cpu online, and then we'd be stuffed.  At the
+       same time, cpu_down can reschedule, so we need to enable
+       preemption while doing that.  This kind of sucks, but should be
+       correct. */
+    /* (We don't need to worry about other cpus bringing stuff up,
+       since by the time num_online_cpus() == 1, there aren't any
+       other cpus) */
+    cpus_clear(prev_online_cpus);
+    preempt_disable();
+    while (num_online_cpus() > 1) {
+       preempt_enable();
+       for_each_online_cpu(i) {
+           if (i == 0)
+               continue;
+           err = cpu_down(i);
+           if (err != 0) {
+               printk(KERN_CRIT "Failed to take all CPUs down: %d.\n", err);
+               goto out_reenable_cpus;
+           }
+           cpu_set(i, prev_online_cpus);
+       }
+       preempt_disable();
+    }
+
     suspend_record->nr_pfns = max_pfn; /* final number of pfns */
 
     __cli();
+
+    preempt_enable();
+
+    cpus_clear(prev_present_cpus);
+    for_each_present_cpu(i) {
+       if (i == 0)
+           continue;
+       save_vcpu_context(i, &suspended_cpu_records[i]);
+       cpu_set(i, prev_present_cpus);
+    }
 
 #ifdef __i386__
     mm_pin_all();
@@ -119,8 +225,6 @@
 
     netif_suspend();
 
-    blkdev_suspend();
-
     time_suspend();
 
 #ifdef CONFIG_SMP
@@ -141,7 +245,9 @@
     memcpy(&suspend_record->resume_info, &xen_start_info,
            sizeof(xen_start_info));
 
-    HYPERVISOR_suspend(virt_to_machine(suspend_record) >> PAGE_SHIFT);
+    /* We'll stop somewhere inside this hypercall.  When it returns,
+       we'll start resuming after the restore. */
+    HYPERVISOR_suspend(virt_to_mfn(suspend_record));
 
     shutting_down = SHUTDOWN_INVALID; 
 
@@ -157,10 +263,10 @@
     for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
     {
         pfn_to_mfn_frame_list[j] = 
-            virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT;
+            virt_to_mfn(&phys_to_machine_mapping[i]);
     }
     HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list =
-        virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT;
+        virt_to_mfn(pfn_to_mfn_frame_list);
 
     gnttab_resume();
 
@@ -176,17 +282,30 @@
 
     time_resume();
 
-    blkdev_resume();
-
     netif_resume();
 
     usbif_resume();
 
+    for_each_cpu_mask(i, prev_present_cpus) {
+       restore_vcpu_context(i, &suspended_cpu_records[i]);
+    }
+
     __sti();
+
+ out_reenable_cpus:
+    for_each_cpu_mask(i, prev_online_cpus) {
+       j = cpu_up(i);
+       if (j != 0) {
+           printk(KERN_CRIT "Failed to bring cpu %d back up (%d).\n",
+                  i, j);
+           err = j;
+       }
+    }
 
  out:
     if ( suspend_record != NULL )
         free_page((unsigned long)suspend_record);
+    return err;
 }
 
 static int shutdown_process(void *__unused)
@@ -233,6 +352,18 @@
     return 0;
 }
 
+static struct task_struct *kthread_create_on_cpu(int (*f)(void *arg),
+                                                void *arg,
+                                                const char *name,
+                                                int cpu)
+{
+    struct task_struct *p;
+    p = kthread_create(f, arg, name);
+    kthread_bind(p, cpu);
+    wake_up_process(p);
+    return p;
+}
+
 static void __shutdown_handler(void *unused)
 {
     int err;
@@ -245,7 +376,7 @@
     }
     else
     {
-        __do_suspend();
+       kthread_create_on_cpu(__do_suspend, NULL, "suspender", 0);
     }
 }
 
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/process.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/process.c     Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/process.c     Fri Aug 19 
18:19:28 2005
@@ -453,8 +453,8 @@
 #define C(i) do {                                                      \
        if (unlikely(next->tls_array[i] != prev->tls_array[i])) {       \
                mcl->op      = __HYPERVISOR_update_descriptor;          \
-               mcl->args[0] = virt_to_machine(&get_cpu_gdt_table(cpu)  \
-                                              [GDT_ENTRY_TLS_MIN + i]); \
+               mcl->args[0] = virt_to_machine(                         \
+                       &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i]);\
                mcl->args[1] = next->tls_array[i];                      \
                mcl++;                                                  \
        }                                                               \
@@ -474,7 +474,7 @@
                iobmp_op.cmd                     =
                        PHYSDEVOP_SET_IOBITMAP;
                iobmp_op.u.set_iobitmap.bitmap   =
-                       (unsigned long)next->io_bitmap_ptr;
+                       (char *)next->io_bitmap_ptr;
                iobmp_op.u.set_iobitmap.nr_ports =
                        next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
                mcl->op      = __HYPERVISOR_physdev_op;
@@ -743,3 +743,9 @@
                sp -= get_random_int() % 8192;
        return sp & ~0xf;
 }
+
+#ifndef CONFIG_SMP
+void _restore_vcpu(void)
+{
+}
+#endif
diff -r 99914b54f7bf -r 81576d3d1ca8 
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       Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c       Fri Aug 19 
18:19:28 2005
@@ -795,7 +795,7 @@
                for ( i=0, j=0; i < end_pfn; i+=(PAGE_SIZE/sizeof(unsigned 
long)), j++ )
                {       
                        pfn_to_mfn_frame_list[j] = 
-                               virt_to_machine(&phys_to_machine_mapping[i]) >> 
PAGE_SHIFT;
+                               virt_to_mfn(&phys_to_machine_mapping[i]);
                }
 
        }
diff -r 99914b54f7bf -r 81576d3d1ca8 
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     Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c     Fri Aug 19 
18:19:28 2005
@@ -139,7 +139,7 @@
        for (va = gdt_descr->address, f = 0;
             va < gdt_descr->address + gdt_descr->size;
             va += PAGE_SIZE, f++) {
-               frames[f] = virt_to_machine(va) >> PAGE_SHIFT;
+               frames[f] = virt_to_mfn(va);
                make_page_readonly((void *)va);
        }
        if (HYPERVISOR_set_gdt(frames, gdt_descr->size /
@@ -280,19 +280,16 @@
        if (cpu) {
                memcpy(cpu_gdt_table[cpu], cpu_gdt_table[0], GDT_SIZE);
        }       
-#endif
 
        cpu_gdt_descr[cpu].size = GDT_SIZE;
        cpu_gdt_descr[cpu].address = (unsigned long)cpu_gdt_table[cpu];
 
-        cpu_gdt_init(&cpu_gdt_descr[cpu]);
-
-#ifndef CONFIG_XEN 
        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],
            GDT_ENTRY_TLS_ENTRIES * 8);
+
+    cpu_gdt_init(&cpu_gdt_descr[cpu]);
 #endif
        
        /*
diff -r 99914b54f7bf -r 81576d3d1ca8 
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     Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c     Fri Aug 19 
18:19:28 2005
@@ -780,7 +780,7 @@
                for (va = cpu_gdt_descr[cpu].address, f = 0;
                     va < cpu_gdt_descr[cpu].address + cpu_gdt_descr[cpu].size;
                     va += PAGE_SIZE, f++) {
-                       ctxt.gdt_frames[f] = virt_to_machine(va) >> PAGE_SHIFT;
+                       ctxt.gdt_frames[f] = virt_to_mfn(va);
                        make_page_readonly((void *)va);
                }
                ctxt.gdt_ents = GDT_ENTRIES;
@@ -795,7 +795,7 @@
        ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
        ctxt.syscall_callback_eip  = (unsigned long)system_call;
 
-       ctxt.ctrlreg[3] = (unsigned long)virt_to_machine(init_level4_pgt);
+       ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT;
 
        boot_error = HYPERVISOR_boot_vcpu(cpu, &ctxt);
 
@@ -1286,4 +1286,10 @@
        smp_intr_init();
        local_setup_timer_irq();
 }
-#endif
+
+void _restore_vcpu(void)
+{
+       /* XXX need to write this */
+}
+
+#endif
diff -r 99914b54f7bf -r 81576d3d1ca8 
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    Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c    Fri Aug 19 18:19:28 2005
@@ -742,7 +742,7 @@
                                set_fixmap(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE);
                        else
                                __set_fixmap(FIX_ISAMAP_BEGIN - i,
-                                            virt_to_machine(empty_zero_page),
+                                            virt_to_mfn(empty_zero_page) << 
PAGE_SHIFT,
                                             PAGE_KERNEL_RO);
        }
 #endif
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/blkback/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/Makefile Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/Makefile Fri Aug 19 18:19:28 2005
@@ -1,2 +1,2 @@
 
-obj-y  := blkback.o control.o interface.o vbd.o
+obj-y  := blkback.o xenbus.o interface.o vbd.o
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Fri Aug 19 
18:19:28 2005
@@ -104,7 +104,6 @@
 #endif
 
 static int do_block_io_op(blkif_t *blkif, int max_to_do);
-static void dispatch_probe(blkif_t *blkif, blkif_request_t *req);
 static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req);
 static void make_response(blkif_t *blkif, unsigned long id, 
                           unsigned short op, int st);
@@ -349,10 +348,6 @@
             dispatch_rw_block_io(blkif, req);
             break;
 
-        case BLKIF_OP_PROBE:
-            dispatch_probe(blkif, req);
-            break;
-
         default:
             DPRINTK("error: unknown block io operation [%d]\n",
                     req->operation);
@@ -363,66 +358,6 @@
 
     blk_ring->req_cons = i;
     return more_to_do;
-}
-
-static void dispatch_probe(blkif_t *blkif, blkif_request_t *req)
-{
-    int rsp = BLKIF_RSP_ERROR;
-    int pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
-
-    /* We expect one buffer only. */
-    if ( unlikely(req->nr_segments != 1) )
-        goto out;
-
-    /* Make sure the buffer is page-sized. */
-    if ( (blkif_first_sect(req->frame_and_sects[0]) != 0) ||
-         (blkif_last_sect(req->frame_and_sects[0]) != ((PAGE_SIZE/512)-1)) )
-        goto out;
-
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-    {
-        struct gnttab_map_grant_ref map;
-
-        map.host_addr = MMAP_VADDR(pending_idx, 0);
-        map.flags = GNTMAP_host_map;
-        map.ref = blkif_gref_from_fas(req->frame_and_sects[0]);
-        map.dom = blkif->domid;
-
-        if ( unlikely(HYPERVISOR_grant_table_op(
-                        GNTTABOP_map_grant_ref, &map, 1)))
-            BUG();
-
-        if ( map.handle < 0 )
-            goto out;
-
-        pending_handle(pending_idx, 0) = map.handle;
-    }
-#else /* else CONFIG_XEN_BLKDEV_GRANT */
-
-#ifdef CONFIG_XEN_BLKDEV_TAP_BE
-    /* Grab the real frontend out of the probe message. */
-    if (req->frame_and_sects[1] == BLKTAP_COOKIE) 
-        blkif->is_blktap = 1;
-#endif
-
-
-    if ( HYPERVISOR_update_va_mapping_otherdomain(
-        MMAP_VADDR(pending_idx, 0),
-        pfn_pte_ma(req->frame_and_sects[0] >> PAGE_SHIFT, PAGE_KERNEL),
-#ifdef CONFIG_XEN_BLKDEV_TAP_BE
-        0, (blkif->is_blktap ? ID_TO_DOM(req->id) : blkif->domid) ) )
-#else
-        0, blkif->domid) )
-#endif
-        goto out;
-#endif /* endif CONFIG_XEN_BLKDEV_GRANT */
-   
-    rsp = vbd_probe(blkif, (vdisk_t *)MMAP_VADDR(pending_idx, 0), 
-                    PAGE_SIZE / sizeof(vdisk_t));
-
- out:
-    fast_flush_area(pending_idx, 1);
-    make_response(blkif, req->id, req->operation, rsp);
 }
 
 static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
@@ -460,7 +395,7 @@
         goto bad_descriptor;
     }
 
-    preq.dev           = req->device;
+    preq.dev           = req->handle;
     preq.sector_number = req->sector_number;
     preq.nr_sects      = 0;
 
@@ -730,8 +665,8 @@
         0, SLAB_HWCACHE_ALIGN, NULL, NULL);
 #endif
 
-    blkif_ctrlif_init();
-    
+    blkif_xenbus_init();
+
 #ifdef CONFIG_XEN_BLKDEV_GRANT
     memset( pending_grant_handles,  BLKBACK_INVALID_HANDLE, MMAP_PAGES );
     printk(KERN_ALERT "Blkif backend is using grant tables.\n");
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Fri Aug 19 18:19:28 2005
@@ -13,7 +13,6 @@
 #include <asm/io.h>
 #include <asm/setup.h>
 #include <asm/pgalloc.h>
-#include <asm-xen/ctrl_if.h>
 #include <asm-xen/evtchn.h>
 #include <asm-xen/hypervisor.h>
 #include <asm-xen/xen-public/io/blkif.h>
@@ -47,6 +46,7 @@
     /* Physical parameters of the comms window. */
     unsigned long     shmem_frame;
     unsigned int      evtchn;
+    unsigned int      remote_evtchn;
     /* Comms information. */
     blkif_back_ring_t blk_ring;
     /* VBDs attached to this interface. */
@@ -71,7 +71,7 @@
     struct work_struct work;
 #ifdef CONFIG_XEN_BLKDEV_GRANT
     u16 shmem_handle;
-    memory_t shmem_vaddr;
+    unsigned long shmem_vaddr;
     grant_ref_t shmem_ref;
 #endif
 } blkif_t;
@@ -81,17 +81,29 @@
 void blkif_connect(blkif_be_connect_t *connect);
 int  blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id);
 void blkif_disconnect_complete(blkif_t *blkif);
-blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle);
+blkif_t *blkif_find(domid_t domid);
+void free_blkif(blkif_t *blkif);
+int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
+
 #define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
 #define blkif_put(_b)                             \
     do {                                          \
         if ( atomic_dec_and_test(&(_b)->refcnt) ) \
-            blkif_disconnect_complete(_b);        \
+            free_blkif(_b);                      \
     } while (0)
 
-void vbd_create(blkif_be_vbd_create_t *create); 
+struct vbd;
+void vbd_free(blkif_t *blkif, struct vbd *vbd);
+
+/* Creates inactive vbd. */
+struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, blkif_pdev_t 
pdevice, int readonly);
+int vbd_is_active(struct vbd *vbd);
+void vbd_activate(blkif_t *blkif, struct vbd *vbd);
+
+unsigned long vbd_size(struct vbd *vbd);
+unsigned int vbd_info(struct vbd *vbd);
+unsigned long vbd_secsize(struct vbd *vbd);
 void vbd_destroy(blkif_be_vbd_destroy_t *delete); 
-int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds);
 void destroy_all_vbds(blkif_t *blkif);
 
 struct phys_req {
@@ -104,9 +116,10 @@
 int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation); 
 
 void blkif_interface_init(void);
-void blkif_ctrlif_init(void);
 
 void blkif_deschedule(blkif_t *blkif);
+
+void blkif_xenbus_init(void);
 
 irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
 
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Fri Aug 19 
18:19:28 2005
@@ -7,24 +7,135 @@
  */
 
 #include "common.h"
+#include <asm-xen/ctrl_if.h>
+#include <asm-xen/evtchn.h>
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
 #endif
 
 #define BLKIF_HASHSZ 1024
-#define BLKIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(BLKIF_HASHSZ-1))
+#define BLKIF_HASH(_d) (((int)(_d))&(BLKIF_HASHSZ-1))
 
 static kmem_cache_t *blkif_cachep;
 static blkif_t      *blkif_hash[BLKIF_HASHSZ];
 
-blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle)
-{
-    blkif_t *blkif = blkif_hash[BLKIF_HASH(domid, handle)];
-    while ( (blkif != NULL) && 
-            ((blkif->domid != domid) || (blkif->handle != handle)) )
+blkif_t *blkif_find(domid_t domid)
+{
+    blkif_t *blkif = blkif_hash[BLKIF_HASH(domid)];
+
+    while (blkif) {
+       if (blkif->domid == domid) {
+           blkif_get(blkif);
+           return blkif;
+       }
         blkif = blkif->hash_next;
+    }
+
+    blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL);
+    if (!blkif)
+           return ERR_PTR(-ENOMEM);
+
+    memset(blkif, 0, sizeof(*blkif));
+    blkif->domid = domid;
+    blkif->status = DISCONNECTED;
+    spin_lock_init(&blkif->vbd_lock);
+    spin_lock_init(&blkif->blk_ring_lock);
+    atomic_set(&blkif->refcnt, 1);
+
+    blkif->hash_next = blkif_hash[BLKIF_HASH(domid)];
+    blkif_hash[BLKIF_HASH(domid)] = blkif;
     return blkif;
+}
+
+#ifndef CONFIG_XEN_BLKDEV_GRANT
+static int map_frontend_page(blkif_t *blkif, unsigned long localaddr,
+                            unsigned long shared_page)
+{
+    return direct_remap_area_pages(&init_mm, localaddr,
+                                  shared_page<<PAGE_SHIFT, PAGE_SIZE,
+                                  __pgprot(_KERNPG_TABLE), blkif->domid);
+}
+
+static void unmap_frontend_page(blkif_t *blkif)
+{
+}
+#else
+static int map_frontend_page(blkif_t *blkif, unsigned long localaddr,
+                            unsigned long shared_page)
+{
+    struct gnttab_map_grant_ref op;
+    op.host_addr = localaddr;
+    op.flags = GNTMAP_host_map;
+    op.ref = shared_page;
+    op.dom = blkif->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;
+    }
+
+    blkif->shmem_ref = shared_page;
+    blkif->shmem_handle = op.handle;
+    blkif->shmem_vaddr = localaddr;
+    return 0;
+}
+
+static void unmap_frontend_page(blkif_t *blkif)
+{
+    struct gnttab_unmap_grant_ref op;
+
+    op.host_addr = blkif->shmem_vaddr;
+    op.handle = blkif->shmem_handle;
+    op.dev_bus_addr = 0;
+    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
+}
+#endif /* CONFIG_XEN_BLKDEV_GRANT */
+
+int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
+{
+    struct vm_struct *vma;
+    blkif_sring_t *sring;
+    evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
+    int err;
+
+    BUG_ON(blkif->remote_evtchn);
+
+    if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL )
+       return -ENOMEM;
+
+    err = map_frontend_page(blkif, VMALLOC_VMADDR(vma->addr), shared_page);
+    if (err) {
+        vfree(vma->addr);
+       return err;
+    }
+
+    op.u.bind_interdomain.dom1 = DOMID_SELF;
+    op.u.bind_interdomain.dom2 = blkif->domid;
+    op.u.bind_interdomain.port1 = 0;
+    op.u.bind_interdomain.port2 = evtchn;
+    err = HYPERVISOR_event_channel_op(&op);
+    if (err) {
+       unmap_frontend_page(blkif);
+       vfree(vma->addr);
+       return err;
+    }
+
+    blkif->evtchn = op.u.bind_interdomain.port1;
+    blkif->remote_evtchn = evtchn;
+
+    sring = (blkif_sring_t *)vma->addr;
+    SHARED_RING_INIT(sring);
+    BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
+
+    bind_evtchn_to_irqhandler(blkif->evtchn, blkif_be_int, 0, "blkif-backend",
+                             blkif);
+    blkif->status        = CONNECTED;
+    blkif->shmem_frame   = shared_page;
+
+    return 0;
 }
 
 static void __blkif_disconnect_complete(void *arg)
@@ -32,21 +143,13 @@
     blkif_t              *blkif = (blkif_t *)arg;
     ctrl_msg_t            cmsg;
     blkif_be_disconnect_t disc;
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-    struct gnttab_unmap_grant_ref op;
-#endif
 
     /*
      * These can't be done in blkif_disconnect() because at that point there
      * may be outstanding requests at the disc whose asynchronous responses
      * must still be notified to the remote driver.
      */
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-    op.host_addr      = blkif->shmem_vaddr;
-    op.handle         = blkif->shmem_handle;
-    op.dev_bus_addr   = 0;
-    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
-#endif
+    unmap_frontend_page(blkif);
     vfree(blkif->blk_ring.sring);
 
     /* Construct the deferred response message. */
@@ -81,200 +184,35 @@
     schedule_work(&blkif->work);
 }
 
-void blkif_create(blkif_be_create_t *create)
-{
-    domid_t       domid  = create->domid;
-    unsigned int  handle = create->blkif_handle;
-    blkif_t     **pblkif, *blkif;
-
-    if ( (blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL)) == NULL )
+void free_blkif(blkif_t *blkif)
+{
+    blkif_t     **pblkif;
+    evtchn_op_t op = { .cmd = EVTCHNOP_close };
+
+    op.u.close.port = blkif->evtchn;
+    op.u.close.dom = DOMID_SELF;
+    HYPERVISOR_event_channel_op(&op);
+    op.u.close.port = blkif->remote_evtchn;
+    op.u.close.dom = blkif->domid;
+    HYPERVISOR_event_channel_op(&op);
+
+    if (blkif->evtchn)
+        unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
+
+    if (blkif->blk_ring.sring) {
+       unmap_frontend_page(blkif);
+       vfree(blkif->blk_ring.sring);
+    }
+
+    pblkif = &blkif_hash[BLKIF_HASH(blkif->domid)];
+    while ( *pblkif != blkif )
     {
-        DPRINTK("Could not create blkif: out of memory\n");
-        create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
-        return;
-    }
-
-    memset(blkif, 0, sizeof(*blkif));
-    blkif->domid  = domid;
-    blkif->handle = handle;
-    blkif->status = DISCONNECTED;
-    spin_lock_init(&blkif->vbd_lock);
-    spin_lock_init(&blkif->blk_ring_lock);
-    atomic_set(&blkif->refcnt, 0);
-
-    pblkif = &blkif_hash[BLKIF_HASH(domid, handle)];
-    while ( *pblkif != NULL )
-    {
-        if ( ((*pblkif)->domid == domid) && ((*pblkif)->handle == handle) )
-        {
-            DPRINTK("Could not create blkif: already exists\n");
-            create->status = BLKIF_BE_STATUS_INTERFACE_EXISTS;
-            kmem_cache_free(blkif_cachep, blkif);
-            return;
-        }
+       BUG_ON(!*pblkif);
         pblkif = &(*pblkif)->hash_next;
     }
-
-    blkif->hash_next = *pblkif;
-    *pblkif = blkif;
-
-    DPRINTK("Successfully created blkif\n");
-    create->status = BLKIF_BE_STATUS_OKAY;
-}
-
-void blkif_destroy(blkif_be_destroy_t *destroy)
-{
-    domid_t       domid  = destroy->domid;
-    unsigned int  handle = destroy->blkif_handle;
-    blkif_t     **pblkif, *blkif;
-
-    pblkif = &blkif_hash[BLKIF_HASH(domid, handle)];
-    while ( (blkif = *pblkif) != NULL )
-    {
-        if ( (blkif->domid == domid) && (blkif->handle == handle) )
-        {
-            if ( blkif->status != DISCONNECTED )
-                goto still_connected;
-            goto destroy;
-        }
-        pblkif = &blkif->hash_next;
-    }
-
-    destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
-    return;
-
- still_connected:
-    destroy->status = BLKIF_BE_STATUS_INTERFACE_CONNECTED;
-    return;
-
- destroy:
     *pblkif = blkif->hash_next;
     destroy_all_vbds(blkif);
     kmem_cache_free(blkif_cachep, blkif);
-    destroy->status = BLKIF_BE_STATUS_OKAY;
-}
-
-void blkif_connect(blkif_be_connect_t *connect)
-{
-    domid_t        domid  = connect->domid;
-    unsigned int   handle = connect->blkif_handle;
-    unsigned int   evtchn = connect->evtchn;
-    unsigned long  shmem_frame = connect->shmem_frame;
-    struct vm_struct *vma;
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-    int ref = connect->shmem_ref;
-#else
-    pgprot_t       prot;
-    int            error;
-#endif
-    blkif_t       *blkif;
-    blkif_sring_t *sring;
-
-    blkif = blkif_find_by_handle(domid, handle);
-    if ( unlikely(blkif == NULL) )
-    {
-        DPRINTK("blkif_connect attempted for non-existent blkif (%u,%u)\n", 
-                connect->domid, connect->blkif_handle); 
-        connect->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
-        return;
-    }
-
-    if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL )
-    {
-        connect->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
-        return;
-    }
-
-#ifndef CONFIG_XEN_BLKDEV_GRANT
-    prot = __pgprot(_KERNPG_TABLE);
-    error = direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(vma->addr),
-                                    shmem_frame<<PAGE_SHIFT, PAGE_SIZE,
-                                    prot, domid);
-    if ( error != 0 )
-    {
-        if ( error == -ENOMEM )
-            connect->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
-        else if ( error == -EFAULT )
-            connect->status = BLKIF_BE_STATUS_MAPPING_ERROR;
-        else
-            connect->status = BLKIF_BE_STATUS_ERROR;
-        vfree(vma->addr);
-        return;
-    }
-#else
-    { /* Map: Use the Grant table reference */
-        struct gnttab_map_grant_ref op;
-        op.host_addr      = VMALLOC_VMADDR(vma->addr);
-        op.flags          = GNTMAP_host_map;
-        op.ref            = ref;
-        op.dom            = domid;
-       
-        BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
-       
-        handle = op.handle;
-       
-        if (op.handle < 0) {
-            DPRINTK(" Grant table operation failure !\n");
-            connect->status = BLKIF_BE_STATUS_MAPPING_ERROR;
-            vfree(vma->addr);
-            return;
-        }
-
-        blkif->shmem_ref = ref;
-        blkif->shmem_handle = handle;
-        blkif->shmem_vaddr = VMALLOC_VMADDR(vma->addr);
-    }
-#endif
-
-    if ( blkif->status != DISCONNECTED )
-    {
-        connect->status = BLKIF_BE_STATUS_INTERFACE_CONNECTED;
-        vfree(vma->addr);
-        return;
-    }
-    sring = (blkif_sring_t *)vma->addr;
-    SHARED_RING_INIT(sring);
-    BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
-    
-    blkif->evtchn        = evtchn;
-    blkif->shmem_frame   = shmem_frame;
-    blkif->status        = CONNECTED;
-    blkif_get(blkif);
-
-    bind_evtchn_to_irqhandler(
-        blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
-
-    connect->status = BLKIF_BE_STATUS_OKAY;
-}
-
-int blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id)
-{
-    domid_t       domid  = disconnect->domid;
-    unsigned int  handle = disconnect->blkif_handle;
-    blkif_t      *blkif;
-
-    blkif = blkif_find_by_handle(domid, handle);
-    if ( unlikely(blkif == NULL) )
-    {
-        DPRINTK("blkif_disconnect attempted for non-existent blkif"
-                " (%u,%u)\n", disconnect->domid, disconnect->blkif_handle); 
-        disconnect->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
-        return 1; /* Caller will send response error message. */
-    }
-
-    if ( blkif->status == CONNECTED )
-    {
-        blkif->status = DISCONNECTING;
-        blkif->disconnect_rspid = rsp_id;
-        wmb(); /* Let other CPUs see the status change. */
-        unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
-        blkif_deschedule(blkif);
-        blkif_put(blkif);
-        return 0; /* Caller should not send response message. */
-    }
-
-    disconnect->status = BLKIF_BE_STATUS_OKAY;
-    return 1;
 }
 
 void __init blkif_interface_init(void)
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c    Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c    Fri Aug 19 18:19:28 2005
@@ -11,13 +11,16 @@
  */
 
 #include "common.h"
+#include <asm-xen/xenbus.h>
 
 struct vbd { 
-    blkif_vdev_t   vdevice;     /* what the domain refers to this vbd as */
+    blkif_vdev_t   handle;     /* what the domain refers to this vbd as */
     unsigned char  readonly;    /* Non-zero -> read-only */
     unsigned char  type;        /* VDISK_xxx */
     blkif_pdev_t   pdevice;     /* phys device that this vbd maps to */
     struct block_device *bdev;
+
+    int active;
     rb_node_t      rb;          /* for linking into R-B tree lookup struct */
 }; 
 
@@ -33,140 +36,128 @@
 #define bdev_hardsect_size(_b) 512
 #endif
 
-void vbd_create(blkif_be_vbd_create_t *create) 
+unsigned long vbd_size(struct vbd *vbd)
+{
+       return vbd_sz(vbd);
+}
+
+unsigned int vbd_info(struct vbd *vbd)
+{
+       return vbd->type | (vbd->readonly?VDISK_READONLY:0);
+}
+
+unsigned long vbd_secsize(struct vbd *vbd)
+{
+       return bdev_hardsect_size(vbd->bdev);
+}
+
+int vbd_is_active(struct vbd *vbd)
+{
+       return vbd->active;
+}
+
+struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t handle,
+                      blkif_pdev_t pdevice, int readonly)
 {
     struct vbd  *vbd; 
+
+    if ( unlikely((vbd = kmalloc(sizeof(struct vbd), GFP_KERNEL)) == NULL) )
+    {
+        DPRINTK("vbd_create: out of memory\n");
+       return ERR_PTR(-ENOMEM);
+    }
+
+    vbd->handle   = handle; 
+    vbd->readonly = readonly;
+    vbd->type     = 0;
+    vbd->active   = 0;
+
+    vbd->pdevice  = pdevice;
+
+    /* FIXME: Who frees vbd on failure? --RR */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+    vbd->bdev = open_by_devnum(
+        vbd_map_devnum(vbd->pdevice),
+        vbd->readonly ? FMODE_READ : FMODE_WRITE);
+    if ( IS_ERR(vbd->bdev) )
+    {
+        DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
+        return ERR_PTR(-ENOENT);
+    }
+
+    if ( (vbd->bdev->bd_disk == NULL) )
+    {
+        DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
+        bdev_put(vbd->bdev);
+        return ERR_PTR(-ENOENT);
+    }
+
+    if ( vbd->bdev->bd_disk->flags & GENHD_FL_CD )
+        vbd->type |= VDISK_CDROM;
+    if ( vbd->bdev->bd_disk->flags & GENHD_FL_REMOVABLE )
+        vbd->type |= VDISK_REMOVABLE;
+
+#else
+    if ( (blk_size[MAJOR(vbd->pdevice)] == NULL) || (vbd_sz(vbd) == 0) )
+    {
+        DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
+        return ERR_PTR(-ENOENT);
+    }
+#endif
+
+    DPRINTK("Successful creation of handle=%04x (dom=%u)\n",
+            handle, blkif->domid);
+    return vbd;
+}
+
+void vbd_activate(blkif_t *blkif, struct vbd *vbd)
+{
     rb_node_t  **rb_p, *rb_parent = NULL;
-    blkif_t     *blkif;
-    blkif_vdev_t vdevice = create->vdevice;
-
-    blkif = blkif_find_by_handle(create->domid, create->blkif_handle);
-    if ( unlikely(blkif == NULL) )
-    {
-        DPRINTK("vbd_create attempted for non-existent blkif (%u,%u)\n", 
-                create->domid, create->blkif_handle); 
-        create->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
-        return;
-    }
-
+    struct vbd *i;
+    BUG_ON(vbd_is_active(vbd));
+
+    /* Find where to put it. */
     rb_p = &blkif->vbd_rb.rb_node;
     while ( *rb_p != NULL )
     {
         rb_parent = *rb_p;
-        vbd = rb_entry(rb_parent, struct vbd, rb);
-        if ( vdevice < vbd->vdevice )
+        i = rb_entry(rb_parent, struct vbd, rb);
+        if ( vbd->handle < i->handle )
         {
             rb_p = &rb_parent->rb_left;
         }
-        else if ( vdevice > vbd->vdevice )
+        else if ( vbd->handle > i->handle )
         {
             rb_p = &rb_parent->rb_right;
         }
         else
         {
-            DPRINTK("vbd_create attempted for already existing vbd\n");
-            create->status = BLKIF_BE_STATUS_VBD_EXISTS;
-            return;
+           /* We never create two of same vbd, so not possible. */
+           BUG();
         }
     }
 
-    if ( unlikely((vbd = kmalloc(sizeof(struct vbd), GFP_KERNEL)) == NULL) )
-    {
-        DPRINTK("vbd_create: out of memory\n");
-        create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
-        return;
-    }
-
-    vbd->vdevice  = vdevice; 
-    vbd->readonly = create->readonly;
-    vbd->type     = 0;
-
-    /* Mask to 16-bit for compatibility with old tools */
-    vbd->pdevice  = create->pdevice & 0xffff;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-    vbd->bdev = open_by_devnum(
-        vbd_map_devnum(vbd->pdevice),
-        vbd->readonly ? FMODE_READ : FMODE_WRITE);
-    if ( IS_ERR(vbd->bdev) )
-    {
-        DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
-        create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
-        return;
-    }
-
-    if ( (vbd->bdev->bd_disk == NULL) )
-    {
-        DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
-        create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
-        bdev_put(vbd->bdev);
-        return;
-    }
-
-    if ( vbd->bdev->bd_disk->flags & GENHD_FL_CD )
-        vbd->type |= VDISK_CDROM;
-    if ( vbd->bdev->bd_disk->flags & GENHD_FL_REMOVABLE )
-        vbd->type |= VDISK_REMOVABLE;
-
-#else
-    if ( (blk_size[MAJOR(vbd->pdevice)] == NULL) || (vbd_sz(vbd) == 0) )
-    {
-        DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
-        create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
-        return;
-    }
-#endif
+    /* Now we're active. */
+    vbd->active = 1;
+    blkif_get(blkif);
 
     spin_lock(&blkif->vbd_lock);
     rb_link_node(&vbd->rb, rb_parent, rb_p);
     rb_insert_color(&vbd->rb, &blkif->vbd_rb);
     spin_unlock(&blkif->vbd_lock);
-
-    DPRINTK("Successful creation of vdev=%04x (dom=%u)\n",
-            vdevice, create->domid);
-    create->status = BLKIF_BE_STATUS_OKAY;
-}
-
-
-void vbd_destroy(blkif_be_vbd_destroy_t *destroy) 
-{
-    blkif_t           *blkif;
-    struct vbd        *vbd;
-    rb_node_t         *rb;
-    blkif_vdev_t       vdevice = destroy->vdevice;
-
-    blkif = blkif_find_by_handle(destroy->domid, destroy->blkif_handle);
-    if ( unlikely(blkif == NULL) )
-    {
-        DPRINTK("vbd_destroy attempted for non-existent blkif (%u,%u)\n", 
-                destroy->domid, destroy->blkif_handle); 
-        destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
-        return;
-    }
-
-    rb = blkif->vbd_rb.rb_node;
-    while ( rb != NULL )
-    {
-        vbd = rb_entry(rb, struct vbd, rb);
-        if ( vdevice < vbd->vdevice )
-            rb = rb->rb_left;
-        else if ( vdevice > vbd->vdevice )
-            rb = rb->rb_right;
-        else
-            goto found;
-    }
-
-    destroy->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
-    return;
-
- found:
-    spin_lock(&blkif->vbd_lock);
-    rb_erase(rb, &blkif->vbd_rb);
-    spin_unlock(&blkif->vbd_lock);
+}
+
+void vbd_free(blkif_t *blkif, struct vbd *vbd)
+{
+    if (vbd_is_active(vbd)) {
+       spin_lock(&blkif->vbd_lock);
+       rb_erase(&vbd->rb, &blkif->vbd_rb);
+       spin_unlock(&blkif->vbd_lock);
+       blkif_put(blkif);
+    }
     bdev_put(vbd->bdev);
     kfree(vbd);
 }
-
 
 void destroy_all_vbds(blkif_t *blkif)
 {
@@ -183,73 +174,11 @@
         bdev_put(vbd->bdev);
         kfree(vbd);
         spin_lock(&blkif->vbd_lock);
+        blkif_put(blkif);
     }
 
     spin_unlock(&blkif->vbd_lock);
 }
-
-
-static void vbd_probe_single(
-    blkif_t *blkif, vdisk_t *vbd_info, struct vbd *vbd)
-{
-    vbd_info->device      = vbd->vdevice; 
-    vbd_info->info        = vbd->type | (vbd->readonly ? VDISK_READONLY : 0);
-    vbd_info->capacity    = vbd_sz(vbd);
-    vbd_info->sector_size = bdev_hardsect_size(vbd->bdev);
-}
-
-
-int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds)
-{
-    int        rc = 0, nr_vbds = 0;
-    rb_node_t *rb;
-
-    spin_lock(&blkif->vbd_lock);
-
-    if ( (rb = blkif->vbd_rb.rb_node) == NULL )
-        goto out;
-
- new_subtree:
-    /* STEP 1. Find least node (it'll be left-most). */
-    while ( rb->rb_left != NULL )
-        rb = rb->rb_left;
-
-    for ( ; ; )
-    {
-        /* STEP 2. Dealt with left subtree. Now process current node. */
-        vbd_probe_single(blkif, &vbd_info[nr_vbds],
-                         rb_entry(rb, struct vbd, rb));
-        if ( ++nr_vbds == max_vbds )
-            goto out;
-
-        /* STEP 3. Process right subtree, if any. */
-        if ( rb->rb_right != NULL )
-        {
-            rb = rb->rb_right;
-            goto new_subtree;
-        }
-
-        /* STEP 4. Done both subtrees. Head back through ancesstors. */
-        for ( ; ; ) 
-        {
-            /* We're done when we get back to the root node. */
-            if ( rb->rb_parent == NULL )
-                goto out;
-            /* If we are left of parent, then parent is next to process. */
-            if ( rb->rb_parent->rb_left == rb )
-                break;
-            /* If we are right of parent, then we climb to grandparent. */
-            rb = rb->rb_parent;
-        }
-
-        rb = rb->rb_parent;
-    }
-
- out:
-    spin_unlock(&blkif->vbd_lock);
-    return (rc == 0) ? nr_vbds : rc;  
-}
-
 
 int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation)
 {
@@ -264,9 +193,9 @@
     while ( rb != NULL )
     {
         vbd = rb_entry(rb, struct vbd, rb);
-        if ( req->dev < vbd->vdevice )
+        if ( req->dev < vbd->handle )
             rb = rb->rb_left;
-        else if ( req->dev > vbd->vdevice )
+        else if ( req->dev > vbd->handle )
             rb = rb->rb_right;
         else
             goto found;
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Fri Aug 19 
18:19:28 2005
@@ -53,8 +53,8 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <scsi/scsi.h>
-#include <asm-xen/ctrl_if.h>
 #include <asm-xen/evtchn.h>
+#include <asm-xen/xenbus.h>
 #ifdef CONFIG_XEN_BLKDEV_GRANT
 #include <asm-xen/xen-public/grant_table.h>
 #include <asm-xen/gnttab.h>
@@ -65,22 +65,14 @@
 /* Control whether runtime update of vbds is enabled. */
 #define ENABLE_VBD_UPDATE 1
 
-#if ENABLE_VBD_UPDATE
-static void vbd_update(void);
-#else
-static void vbd_update(void){};
-#endif
-
 #define BLKIF_STATE_CLOSED       0
 #define BLKIF_STATE_DISCONNECTED 1
 #define BLKIF_STATE_CONNECTED    2
 
-static int blkif_handle = 0;
 static unsigned int blkif_state = BLKIF_STATE_CLOSED;
 static unsigned int blkif_evtchn = 0;
-
-static int blkif_control_rsp_valid;
-static blkif_response_t blkif_control_rsp;
+static unsigned int blkif_vbds = 0;
+static unsigned int blkif_vbds_connected = 0;
 
 static blkif_front_ring_t blk_ring;
 
@@ -92,6 +84,7 @@
 #define MAXIMUM_OUTSTANDING_BLOCK_REQS \
     (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
 #define GRANTREF_INVALID (1<<15)
+static int shmem_ref;
 #endif
 
 static struct blk_shadow {
@@ -105,7 +98,7 @@
 
 static void kick_pending_request_queues(void);
 
-int __init xlblk_init(void);
+static int __init xlblk_init(void);
 
 static void blkif_completion(struct blk_shadow *s);
 
@@ -179,19 +172,6 @@
 
 module_init(xlblk_init);
 
-#if ENABLE_VBD_UPDATE
-static void update_vbds_task(void *unused)
-{ 
-    xlvbd_update_vbds();
-}
-
-static void vbd_update(void)
-{
-    static DECLARE_WORK(update_tq, update_vbds_task, NULL);
-    schedule_work(&update_tq);
-}
-#endif /* ENABLE_VBD_UPDATE */
-
 static struct xlbd_disk_info *head_waiting = NULL;
 static void kick_pending_request_queues(void)
 {
@@ -221,16 +201,7 @@
 
 int blkif_release(struct inode *inode, struct file *filep)
 {
-    struct gendisk *gd = inode->i_bdev->bd_disk;
-    struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
-
-    /*
-     * When usage drops to zero it may allow more VBD updates to occur.
-     * Update of usage count is protected by a per-device semaphore.
-     */
-    if ( --di->mi->usage == 0 )
-        vbd_update();
-
+    /* FIXME: This is where we can actually free up majors, etc. --RR */
     return 0;
 }
 
@@ -301,7 +272,7 @@
     ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE :
         BLKIF_OP_READ;
     ring_req->sector_number = (blkif_sector_t)req->sector;
-    ring_req->device = di->xd_device;
+    ring_req->handle = di->handle;
 
     ring_req->nr_segments = 0;
     rq_for_each_bio(bio, req)
@@ -446,10 +417,6 @@
             end_that_request_last(req);
 
             break;
-        case BLKIF_OP_PROBE:
-            memcpy(&blkif_control_rsp, bret, sizeof(*bret));
-            blkif_control_rsp_valid = 1;
-            break;
         default:
             BUG();
         }
@@ -483,28 +450,6 @@
 #define blkif_io_lock io_request_lock
 
 
/*============================================================================*/
-#if ENABLE_VBD_UPDATE
-
-/*
- * blkif_update_int/update-vbds_task - handle VBD update events.
- *  Schedule a task for keventd to run, which will update the VBDs and perform 
- *  the corresponding updates to our view of VBD state.
- */
-static void update_vbds_task(void *unused)
-{ 
-    xlvbd_update_vbds();
-}
-
-static void vbd_update(void)
-{
-    static struct tq_struct update_tq;
-    update_tq.routine = update_vbds_task;
-    schedule_task(&update_tq);
-}
-
-#endif /* ENABLE_VBD_UPDATE */
-/*============================================================================*/
-
 static void kick_pending_request_queues(void)
 {
     /* We kick pending request queues if the ring is reasonably empty. */
@@ -757,7 +702,8 @@
                                char *          buffer,
                                unsigned long   sector_number,
                                unsigned short  nr_sectors,
-                               kdev_t          device)
+                               kdev_t          device,
+                              blkif_vdev_t    handle)
 {
     unsigned long       buffer_ma = virt_to_bus(buffer);
     unsigned long       xid;
@@ -871,7 +817,7 @@
     req->id            = xid;
     req->operation     = operation;
     req->sector_number = (blkif_sector_t)sector_number;
-    req->device        = device; 
+    req->handle        = handle; 
     req->nr_segments   = 1;
 #ifdef CONFIG_XEN_BLKDEV_GRANT
     /* install a grant reference. */
@@ -1047,108 +993,10 @@
 
 /*****************************  COMMON CODE  *******************************/
 
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-void blkif_control_probe_send(blkif_request_t *req, blkif_response_t *rsp,
-                              unsigned long address)
-{
-    int ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
-    ASSERT( ref != -ENOSPC );
-
-    gnttab_grant_foreign_access_ref( ref, rdomid, address >> PAGE_SHIFT, 0 );
-
-    req->frame_and_sects[0] = blkif_fas_from_gref(ref, 0, (PAGE_SIZE/512)-1);
-
-    blkif_control_send(req, rsp);
-}
-#endif
-
-void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp)
-{
-    unsigned long flags, id;
-    blkif_request_t *req_d;
-
- retry:
-    while ( RING_FULL(&blk_ring) )
-    {
-        set_current_state(TASK_INTERRUPTIBLE);
-        schedule_timeout(1);
-    }
-
-    spin_lock_irqsave(&blkif_io_lock, flags);
-    if ( RING_FULL(&blk_ring) )
-    {
-        spin_unlock_irqrestore(&blkif_io_lock, flags);
-        goto retry;
-    }
-
-    DISABLE_SCATTERGATHER();
-    req_d = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt);
-    *req_d = *req;    
-
-    id = GET_ID_FROM_FREELIST();
-    req_d->id = id;
-    blk_shadow[id].request = (unsigned long)req;
-
-    pickle_request(&blk_shadow[id], req);
-
-    blk_ring.req_prod_pvt++;
-    flush_requests();
-
-    spin_unlock_irqrestore(&blkif_io_lock, flags);
-
-    while ( !blkif_control_rsp_valid )
-    {
-        set_current_state(TASK_INTERRUPTIBLE);
-        schedule_timeout(1);
-    }
-
-    memcpy(rsp, &blkif_control_rsp, sizeof(*rsp));
-    blkif_control_rsp_valid = 0;
-}
-
-
-/* Send a driver status notification to the domain controller. */
-static void send_driver_status(int ok)
-{
-    ctrl_msg_t cmsg = {
-        .type    = CMSG_BLKIF_FE,
-        .subtype = CMSG_BLKIF_FE_DRIVER_STATUS,
-        .length  = sizeof(blkif_fe_driver_status_t),
-    };
-    blkif_fe_driver_status_t *msg = (void*)cmsg.msg;
-    
-    msg->status = (ok ? BLKIF_DRIVER_STATUS_UP : BLKIF_DRIVER_STATUS_DOWN);
-
-    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
-}
-
-/* Tell the controller to bring up the interface. */
-static void blkif_send_interface_connect(void)
-{
-    ctrl_msg_t cmsg = {
-        .type    = CMSG_BLKIF_FE,
-        .subtype = CMSG_BLKIF_FE_INTERFACE_CONNECT,
-        .length  = sizeof(blkif_fe_interface_connect_t),
-    };
-    blkif_fe_interface_connect_t *msg = (void*)cmsg.msg;
-    
-    msg->handle      = 0;
-    msg->shmem_frame = (virt_to_machine(blk_ring.sring) >> PAGE_SHIFT);
-    
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-    msg->shmem_ref   = gnttab_claim_grant_reference( &gref_head, gref_terminal 
);
-    ASSERT( msg->shmem_ref != -ENOSPC );
-    gnttab_grant_foreign_access_ref ( msg->shmem_ref , rdomid, 
msg->shmem_frame, 0 );
-#endif
-
-    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
-}
-
 static void blkif_free(void)
 {
     /* Prevent new requests being issued until we fix things up. */
     spin_lock_irq(&blkif_io_lock);
-    recovery = 1;
     blkif_state = BLKIF_STATE_DISCONNECTED;
     spin_unlock_irq(&blkif_io_lock);
 
@@ -1160,31 +1008,6 @@
     }
     unbind_evtchn_from_irqhandler(blkif_evtchn, NULL);
     blkif_evtchn = 0;
-}
-
-static void blkif_close(void)
-{
-}
-
-/* Move from CLOSED to DISCONNECTED state. */
-static void blkif_disconnect(void)
-{
-    blkif_sring_t *sring;
-    
-    if ( blk_ring.sring != NULL )
-        free_page((unsigned long)blk_ring.sring);
-    
-    sring = (blkif_sring_t *)__get_free_page(GFP_KERNEL);
-    SHARED_RING_INIT(sring);
-    FRONT_RING_INIT(&blk_ring, sring, PAGE_SIZE);
-    blkif_state  = BLKIF_STATE_DISCONNECTED;
-    blkif_send_interface_connect();
-}
-
-static void blkif_reset(void)
-{
-    blkif_free();
-    blkif_disconnect();
 }
 
 static void blkif_recover(void)
@@ -1257,11 +1080,14 @@
     blkif_state = BLKIF_STATE_CONNECTED;
 }
 
-static void blkif_connect(blkif_fe_interface_status_t *status)
+static void blkif_connect(u16 evtchn, domid_t domid)
 {
     int err = 0;
 
-    blkif_evtchn = status->evtchn;
+    blkif_evtchn = evtchn;
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+    rdomid       = domid;
+#endif
 
     err = bind_evtchn_to_irqhandler(
         blkif_evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", NULL);
@@ -1270,142 +1096,318 @@
         WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
         return;
     }
-
-    if ( recovery ) 
-    {
-        blkif_recover();
-    } 
-    else 
-    {
-        /* Transition to connected in case we need to do 
-         *  a partition probe on a whole disk. */
-        blkif_state = BLKIF_STATE_CONNECTED;
-        
-        /* Probe for discs attached to the interface. */
-        xlvbd_init();
-    }
-    
-    /* Kick pending requests. */
-    spin_lock_irq(&blkif_io_lock);
-    kick_pending_request_queues();
-    spin_unlock_irq(&blkif_io_lock);
-}
-
-static void unexpected(blkif_fe_interface_status_t *status)
-{
-    DPRINTK(" Unexpected blkif status %u in state %u\n", 
-            status->status, blkif_state);
-}
-
-static void blkif_status(blkif_fe_interface_status_t *status)
-{
+}
+
+
+static struct xenbus_device_id blkfront_ids[] = {
+       { "vbd" },
+       { "" }
+};
+
+struct blkfront_info
+{
+       /* We watch the backend */
+       struct xenbus_watch watch;
+       int vdevice;
+       u16 handle;
+       int connected;
+       struct xenbus_device *dev;
+       char *backend;
+};
+
+static void watch_for_status(struct xenbus_watch *watch, const char *node)
+{
+       struct blkfront_info *info;
+       unsigned int binfo;
+       unsigned long sectors, sector_size;
+       int err;
+
+       info = container_of(watch, struct blkfront_info, watch);
+       node += strlen(watch->node);
+
+       /* FIXME: clean up when error on the other end. */
+       if (info->connected)
+               return;
+
+       err = xenbus_gather(watch->node, 
+                           "sectors", "%lu", &sectors,
+                           "info", "%u", &binfo,
+                           "sector-size", "%lu", &sector_size,
+                           NULL);
+
+       if (err)
+               xenbus_dev_error(info->dev, err, "reading backend fields");
+       else {
+               xlvbd_add(sectors, info->vdevice, info->handle, binfo,
+                         sector_size);
+               info->connected = 1;
+
+               /* First to connect?  blkif is now connected. */
+               if (blkif_vbds_connected++ == 0)
+                       blkif_state = BLKIF_STATE_CONNECTED;
+
+               xenbus_dev_ok(info->dev);
+
+               /* Kick pending requests. */
+               spin_lock_irq(&blkif_io_lock);
+               kick_pending_request_queues();
+               spin_unlock_irq(&blkif_io_lock);
+       }
+}
+
+static int setup_blkring(struct xenbus_device *dev, unsigned int backend_id)
+{
+       blkif_sring_t *sring;
+       evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
+       int err;
+
+       sring = (void *)__get_free_page(GFP_KERNEL);
+       if (!sring) {
+               xenbus_dev_error(dev, -ENOMEM, "allocating shared ring");
+               return -ENOMEM;
+       }
+       SHARED_RING_INIT(sring);
+       FRONT_RING_INIT(&blk_ring, sring, PAGE_SIZE);
+
 #ifdef CONFIG_XEN_BLKDEV_GRANT
-    rdomid       = status->domid; /* need to set rdomid early */
-#endif
-
-    if ( status->handle != blkif_handle )
-    {
-        WPRINTK(" Invalid blkif: handle=%u\n", status->handle);
-        unexpected(status);
-        return;
-    }
-
-    switch ( status->status ) 
-    {
-    case BLKIF_INTERFACE_STATUS_CLOSED:
-        switch ( blkif_state )
-        {
-        case BLKIF_STATE_CLOSED:
-            unexpected(status);
-            break;
-        case BLKIF_STATE_DISCONNECTED:
-        case BLKIF_STATE_CONNECTED:
-            unexpected(status);
-            blkif_close();
-            break;
-        }
-        break;
-
-    case BLKIF_INTERFACE_STATUS_DISCONNECTED:
-        switch ( blkif_state )
-        {
-        case BLKIF_STATE_CLOSED:
-            blkif_disconnect();
-            break;
-        case BLKIF_STATE_DISCONNECTED:
-        case BLKIF_STATE_CONNECTED:
-            /* unexpected(status); */ /* occurs during suspend/resume */
-            blkif_reset();
-            break;
-        }
-        break;
-
-    case BLKIF_INTERFACE_STATUS_CONNECTED:
-        switch ( blkif_state )
-        {
-        case BLKIF_STATE_CLOSED:
-            unexpected(status);
-            blkif_disconnect();
-            blkif_connect(status);
-            break;
-        case BLKIF_STATE_DISCONNECTED:
-            blkif_connect(status);
-            break;
-        case BLKIF_STATE_CONNECTED:
-            unexpected(status);
-            blkif_connect(status);
-            break;
-        }
-        break;
-
-    case BLKIF_INTERFACE_STATUS_CHANGED:
-        switch ( blkif_state )
-        {
-        case BLKIF_STATE_CLOSED:
-        case BLKIF_STATE_DISCONNECTED:
-            unexpected(status);
-            break;
-        case BLKIF_STATE_CONNECTED:
-            vbd_update();
-            break;
-        }
-        break;
-
-    default:
-        WPRINTK(" Invalid blkif status: %d\n", status->status);
-        break;
-    }
-}
-
-
-static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
-{
-    switch ( msg->subtype )
-    {
-    case CMSG_BLKIF_FE_INTERFACE_STATUS:
-        blkif_status((blkif_fe_interface_status_t *)
-                     &msg->msg[0]);
-        break;
-    default:
-        msg->length = 0;
-        break;
-    }
-
-    ctrl_if_send_response(msg);
-}
-
-int wait_for_blkif(void)
+       shmem_ref = gnttab_claim_grant_reference(&gref_head,
+                                                gref_terminal);
+       ASSERT(shmem_ref != -ENOSPC);
+       gnttab_grant_foreign_access_ref(shmem_ref,
+                                       backend_id,
+                                       virt_to_mfn(blk_ring.sring),
+                                       0);
+#endif
+
+       op.u.alloc_unbound.dom = backend_id;
+       err = HYPERVISOR_event_channel_op(&op);
+       if (err) {
+               free_page((unsigned long)blk_ring.sring);
+               blk_ring.sring = 0;
+               xenbus_dev_error(dev, err, "allocating event channel");
+               return err;
+       }
+       blkif_connect(op.u.alloc_unbound.port, backend_id);
+       return 0;
+}
+
+/* Common code used when first setting up, and when resuming. */
+static int talk_to_backend(struct xenbus_device *dev,
+                          struct blkfront_info *info)
+{
+       char *backend;
+       const char *message;
+       int err, backend_id;
+
+       backend = xenbus_read(dev->nodename, "backend", NULL);
+       if (IS_ERR(backend)) {
+               err = PTR_ERR(backend);
+               if (err == -ENOENT)
+                       goto out;
+               xenbus_dev_error(dev, err, "reading %s/backend",
+                                dev->nodename);
+               goto out;
+       }
+       if (strlen(backend) == 0) {
+               err = -ENOENT;
+               goto free_backend;
+       }
+
+       /* FIXME: This driver can't handle backends on different
+        * domains.  Check and fail gracefully. */
+       err = xenbus_scanf(dev->nodename, "backend-id", "%i", &backend_id);
+       if (err == -ENOENT)
+               goto free_backend;
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "reading %s/backend-id",
+                                dev->nodename);
+               goto free_backend;
+       }
+
+       /* First device?  We create shared ring, alloc event channel. */
+       if (blkif_vbds == 0) {
+               err = setup_blkring(dev, backend_id);
+               if (err)
+                       goto free_backend;
+       }
+
+       err = xenbus_transaction_start(dev->nodename);
+       if (err) {
+               xenbus_dev_error(dev, err, "starting transaction");
+               goto destroy_blkring;
+       }
+
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+       err = xenbus_printf(dev->nodename, "grant-id","%u", shmem_ref);
+       if (err) {
+               message = "writing grant-id";
+               goto abort_transaction;
+       }
+#else
+       err = xenbus_printf(dev->nodename, "shared-frame", "%lu",
+                           virt_to_mfn(blk_ring.sring));
+       if (err) {
+               message = "writing shared-frame";
+               goto abort_transaction;
+       }
+#endif
+       err = xenbus_printf(dev->nodename,
+                           "event-channel", "%u", blkif_evtchn);
+       if (err) {
+               message = "writing event-channel";
+               goto abort_transaction;
+       }
+
+       info->watch.node = info->backend = 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_blkring;
+       }
+       return 0;
+
+abort_transaction:
+       xenbus_transaction_end(1);
+       /* Have to do this *outside* transaction.  */
+       xenbus_dev_error(dev, err, "%s", message);
+destroy_blkring:
+       if (blkif_vbds == 0)
+               blkif_free();
+free_backend:
+       kfree(backend);
+out:
+       printk("%s:%u = %i\n", __FILE__, __LINE__, err);
+       return err;
+}
+
+/* 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 blkfront_probe(struct xenbus_device *dev,
+                         const struct xenbus_device_id *id)
+{
+       int err;
+       struct blkfront_info *info;
+       int vdevice;
+
+       /* FIXME: Use dynamic device id if this is not set. */
+       err = xenbus_scanf(dev->nodename, "virtual-device", "%i", &vdevice);
+       if (err == -ENOENT)
+               return err;
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "reading virtual-device");
+               return err;
+       }
+
+       info = kmalloc(sizeof(*info), GFP_KERNEL);
+       if (!info) {
+               xenbus_dev_error(dev, err, "allocating info structure");
+               return err;
+       }
+       info->dev = dev;
+       info->vdevice = vdevice;
+       info->connected = 0;
+       /* Front end dir is a number, which is used as the id. */
+       info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
+       dev->data = info;
+
+       err = talk_to_backend(dev, info);
+       if (err) {
+               kfree(info);
+               return err;
+       }
+
+       /* Call once in case entries already there. */
+       watch_for_status(&info->watch, info->watch.node);
+       blkif_vbds++;
+       return 0;
+}
+
+static int blkfront_remove(struct xenbus_device *dev)
+{
+       struct blkfront_info *info = dev->data;
+
+       if (info->backend)
+               unregister_xenbus_watch(&info->watch);
+
+       if (info->connected) {
+               xlvbd_del(info->handle);
+               blkif_vbds_connected--;
+       }
+       kfree(info->backend);
+       kfree(info);
+
+       if (--blkif_vbds == 0)
+               blkif_free();
+
+       return 0;
+}
+
+static int blkfront_suspend(struct xenbus_device *dev)
+{
+       struct blkfront_info *info = dev->data;
+
+       unregister_xenbus_watch(&info->watch);
+       kfree(info->backend);
+       info->backend = NULL;
+
+       if (--blkif_vbds == 0) {
+               recovery = 1;
+               blkif_free();
+       }
+
+       return 0;
+}
+
+static int blkfront_resume(struct xenbus_device *dev)
+{
+       struct blkfront_info *info = dev->data;
+       int err;
+
+       /* FIXME: Check geometry hasn't changed here... */
+       err = talk_to_backend(dev, info);
+       if (!err) {
+               if (blkif_vbds++ == 0)
+                       blkif_recover();
+       }
+       return err;
+}
+
+static struct xenbus_driver blkfront = {
+       .name = "vbd",
+       .owner = THIS_MODULE,
+       .ids = blkfront_ids,
+       .probe = blkfront_probe,
+       .remove = blkfront_remove,
+       .resume = blkfront_resume,
+       .suspend = blkfront_suspend,
+};
+
+static void __init init_blk_xenbus(void)
+{
+       xenbus_register_device(&blkfront);
+}
+
+static int wait_for_blkif(void)
 {
     int err = 0;
     int i;
-    send_driver_status(1);
 
     /*
      * We should read 'nr_interfaces' from response message and wait
      * for notifications before proceeding. For now we assume that we
      * will be notified of exactly one interface.
      */
-    for ( i=0; (blkif_state != BLKIF_STATE_CONNECTED) && (i < 10*HZ); i++ )
+    for ( i=0; blkif_state != BLKIF_STATE_CONNECTED && (i < 10*HZ); i++ )
     {
         set_current_state(TASK_INTERRUPTIBLE);
         schedule_timeout(1);
@@ -1419,7 +1421,7 @@
     return err;
 }
 
-int __init xlblk_init(void)
+static int __init xlblk_init(void)
 {
     int i;
 
@@ -1443,27 +1445,11 @@
         blk_shadow[i].req.id = i+1;
     blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
 
-    (void)ctrl_if_register_receiver(CMSG_BLKIF_FE, blkif_ctrlif_rx,
-                                    CALLBACK_IN_BLOCKING_CONTEXT);
+    init_blk_xenbus();
 
     wait_for_blkif();
 
     return 0;
-}
-
-void blkdev_suspend(void)
-{
-}
-
-void blkdev_resume(void)
-{
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-    int i, j;
-    for ( i = 0; i < BLK_RING_SIZE; i++ )
-        for ( j = 0; j < BLKIF_MAX_SEGMENTS_PER_REQUEST; j++ )
-            blk_shadow[i].req.frame_and_sects[j] |= GRANTREF_INVALID;
-#endif
-    send_driver_status(1);
 }
 
 static void blkif_completion(struct blk_shadow *s)
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Fri Aug 19 18:19:28 2005
@@ -100,6 +100,7 @@
 
 struct xlbd_disk_info {
     int xd_device;
+    blkif_vdev_t handle;
     struct xlbd_major_info *mi;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     struct xlbd_disk_info  *next_waiting;
@@ -119,17 +120,10 @@
                        unsigned command, unsigned long argument);
 extern int blkif_check(dev_t dev);
 extern int blkif_revalidate(dev_t dev);
-extern void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp);
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-extern void blkif_control_probe_send(
-    blkif_request_t *req, blkif_response_t *rsp, unsigned long address);
-#endif
 extern void do_blkif_request (request_queue_t *rq); 
 
-extern void xlvbd_update_vbds(void);
-
 /* Virtual block-device subsystem. */
-extern int  xlvbd_init(void);
-extern void xlvbd_cleanup(void); 
-
+int xlvbd_add(blkif_sector_t capacity, int device, blkif_vdev_t handle,
+             u16 info, u16 sector_size);
+void xlvbd_del(blkif_vdev_t handle);
 #endif /* __XEN_DRIVERS_BLOCK_H__ */
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c   Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c   Fri Aug 19 18:19:28 2005
@@ -46,8 +46,9 @@
 struct lvdisk
 {
     blkif_sector_t capacity; /*  0: Size in terms of 512-byte sectors.   */
-    blkif_vdev_t   device;   /*  8: Device number (opaque 16 bit value). */
-    u16            info; 
+    blkif_vdev_t   handle;   /*  8: Device number (opaque 16 bit value). */
+    u16            info;
+    dev_t          dev;
     struct list_head list;
 };
 
@@ -85,7 +86,7 @@
 
 /* Information about our VBDs. */
 #define MAX_VBDS 64
-struct list_head vbds_list;
+static LIST_HEAD(vbds_list);
 
 #define MAJOR_XEN(dev) ((dev)>>8)
 #define MINOR_XEN(dev) ((dev) & 0xff)
@@ -116,49 +117,6 @@
 {
     list_del(&disk->list);
     kfree(disk);
-}
-
-static vdisk_t *xlvbd_probe(int *ret)
-{
-    blkif_response_t rsp;
-    blkif_request_t req;
-    vdisk_t *disk_info = NULL;
-    unsigned long buf;
-    int nr;
-
-    buf = __get_free_page(GFP_KERNEL);
-    if ((void *)buf == NULL)
-        goto out;
-
-    memset(&req, 0, sizeof(req));
-    req.operation = BLKIF_OP_PROBE;
-    req.nr_segments = 1;
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-    blkif_control_probe_send(&req, &rsp,
-                             (unsigned long)(virt_to_machine(buf)));
-#else
-    req.frame_and_sects[0] = blkif_fas(virt_to_machine(buf), 0, 
(PAGE_SIZE/512)-1);
-
-    blkif_control_send(&req, &rsp);
-#endif
-    if ( rsp.status <= 0 ) {
-        WPRINTK("Could not probe disks (%d)\n", rsp.status);
-        goto out;
-    }
-    nr = rsp.status;
-    if ( nr > MAX_VBDS )
-        nr = MAX_VBDS;
-
-    disk_info = kmalloc(nr * sizeof(vdisk_t), GFP_KERNEL);
-    if (disk_info != NULL)
-        memcpy(disk_info, (void *) buf, nr * sizeof(vdisk_t));
-
-    if (ret != NULL)
-        *ret = nr;
-
-out:
-    free_page(buf);
-    return disk_info;
 }
 
 static struct xlbd_major_info *xlbd_alloc_major_info(
@@ -189,6 +147,7 @@
         break;
     }
     
+    printk("Registering block device major %i\n", ptr->major);
     if (register_blkdev(ptr->major, ptr->type->devname)) {
         WPRINTK("can't get major %d with name %s\n",
                 ptr->major, ptr->type->devname);
@@ -231,7 +190,7 @@
             xlbd_alloc_major_info(major, minor, index));
 }
 
-static int xlvbd_init_blk_queue(struct gendisk *gd, vdisk_t *disk)
+static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
 {
     request_queue_t *rq;
 
@@ -242,7 +201,7 @@
     elevator_init(rq, "noop");
 
     /* Hard sector size and max sectors impersonate the equiv. hardware. */
-    blk_queue_hardsect_size(rq, disk->sector_size);
+    blk_queue_hardsect_size(rq, sector_size);
     blk_queue_max_sectors(rq, 512);
 
     /* Each segment in a request is up to an aligned page in size. */
@@ -261,8 +220,9 @@
     return 0;
 }
 
-struct gendisk *xlvbd_alloc_gendisk(
-    struct xlbd_major_info *mi, int minor, vdisk_t *disk)
+static struct gendisk *xlvbd_alloc_gendisk(
+    struct xlbd_major_info *mi, int minor, blkif_sector_t capacity,
+    int device, blkif_vdev_t handle, u16 info, u16 sector_size)
 {
     struct gendisk *gd;
     struct xlbd_disk_info *di;
@@ -273,7 +233,8 @@
         return NULL;
     memset(di, 0, sizeof(*di));
     di->mi = mi;
-    di->xd_device = disk->device;
+    di->xd_device = device;
+    di->handle = handle;
 
     if ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)
         nr_minors = 1 << mi->type->partn_shift;
@@ -296,22 +257,22 @@
     gd->first_minor = minor;
     gd->fops = &xlvbd_block_fops;
     gd->private_data = di;
-    set_capacity(gd, disk->capacity);
-
-    if (xlvbd_init_blk_queue(gd, disk)) {
+    set_capacity(gd, capacity);
+
+    if (xlvbd_init_blk_queue(gd, sector_size)) {
         del_gendisk(gd);
         goto out;
     }
 
     di->rq = gd->queue;
 
-    if (disk->info & VDISK_READONLY)
+    if (info & VDISK_READONLY)
         set_disk_ro(gd, 1);
 
-    if (disk->info & VDISK_REMOVABLE)
+    if (info & VDISK_REMOVABLE)
         gd->flags |= GENHD_FL_REMOVABLE;
 
-    if (disk->info & VDISK_CDROM)
+    if (info & VDISK_CDROM)
         gd->flags |= GENHD_FL_CD;
 
     add_disk(gd);
@@ -323,38 +284,36 @@
     return NULL;
 }
 
-static int xlvbd_device_add(struct list_head *list, vdisk_t *disk)
+int xlvbd_add(blkif_sector_t capacity, int device, blkif_vdev_t handle,
+             u16 info, u16 sector_size)
 {
     struct lvdisk *new;
-    int minor;
-    dev_t device;
     struct block_device *bd;
     struct gendisk *gd;
     struct xlbd_major_info *mi;
 
-    mi = xlbd_get_major_info(disk->device);
+    mi = xlbd_get_major_info(device);
     if (mi == NULL)
         return -EPERM;
 
     new = xlvbd_device_alloc();
     if (new == NULL)
-        return -1;
-    new->capacity = disk->capacity;
-    new->device = disk->device;
-    new->info = disk->info;
-    
-    minor = MINOR_XEN(disk->device);
-    device = MKDEV(mi->major, minor);
-    
-    bd = bdget(device);
+        return -ENOMEM;
+    new->capacity = capacity;
+    new->info = info;
+    new->handle = handle;
+    new->dev = MKDEV(MAJOR_XEN(device), MINOR_XEN(device));
+
+    bd = bdget(new->dev);
     if (bd == NULL)
         goto out;
     
-    gd = xlvbd_alloc_gendisk(mi, minor, disk);
+    gd = xlvbd_alloc_gendisk(mi, MINOR_XEN(device), capacity, device, handle,
+                            info, sector_size);
     if (gd == NULL)
         goto out_bd;
 
-    list_add(&new->list, list);
+    list_add(&new->list, &vbds_list);
 out_bd:
     bdput(bd);
 out:
@@ -363,27 +322,26 @@
 
 static int xlvbd_device_del(struct lvdisk *disk)
 {
-    dev_t device;
     struct block_device *bd;
     struct gendisk *gd;
     struct xlbd_disk_info *di;
     int ret = 0, unused;
     request_queue_t *rq;
 
-    device = MKDEV(MAJOR_XEN(disk->device), MINOR_XEN(disk->device));
-
-    bd = bdget(device);
+    bd = bdget(disk->dev);
     if (bd == NULL)
         return -1;
 
-    gd = get_gendisk(device, &unused);
+    gd = get_gendisk(disk->dev, &unused);
     di = gd->private_data;
 
+#if 0 /* This is wrong: hda and hdb share same major, for example. */
     if (di->mi->usage != 0) {
-        WPRINTK("disk removal failed: used [dev=%x]\n", device);
+        WPRINTK("disk removal failed: used [dev=%x]\n", disk->dev);
         ret = -1;
         goto out;
     }
+#endif
 
     rq = gd->queue;
     del_gendisk(gd);
@@ -391,110 +349,19 @@
     blk_cleanup_queue(rq);
 
     xlvbd_device_free(disk);
-out:
     bdput(bd);
     return ret;
 }
 
-static int xlvbd_device_update(struct lvdisk *ldisk, vdisk_t *disk)
-{
-    dev_t device;
-    struct block_device *bd;
-    struct gendisk *gd;
-    int unused;
-
-    if ((ldisk->capacity == disk->capacity) && (ldisk->info == disk->info))
-        return 0;    
-
-    device = MKDEV(MAJOR_XEN(ldisk->device), MINOR_XEN(ldisk->device));
-
-    bd = bdget(device);
-    if (bd == NULL)
-        return -1;
-
-    gd = get_gendisk(device, &unused);
-    set_capacity(gd, disk->capacity);    
-    ldisk->capacity = disk->capacity;
-
-    bdput(bd);
-
-    return 0;
-}
-
-void xlvbd_refresh(void)
-{
-    vdisk_t *newdisks;
-    struct list_head *tmp, *tmp2;
-    struct lvdisk *disk;
-    int i, nr;
-
-    newdisks = xlvbd_probe(&nr);
-    if (newdisks == NULL) {
-        WPRINTK("failed to probe\n");
-        return;
-    }
-    
-    i = 0;
-    list_for_each_safe(tmp, tmp2, &vbds_list) {
-        disk = list_entry(tmp, struct lvdisk, list);
-        
-        for (i = 0; i < nr; i++) {
-            if ( !newdisks[i].device )
-                continue;
-            if ( disk->device == newdisks[i].device ) {
-                xlvbd_device_update(disk, &newdisks[i]);
-                newdisks[i].device = 0;
-                break;
-            }
-        }
-        if (i == nr) {
-            xlvbd_device_del(disk);
-            newdisks[i].device = 0;
-        }
-    }
-    for (i = 0; i < nr; i++)
-        if ( newdisks[i].device )
-            xlvbd_device_add(&vbds_list, &newdisks[i]);
-    kfree(newdisks);
-}
-
-/*
- * xlvbd_update_vbds - reprobes the VBD status and performs updates driver
- * state. The VBDs need to be updated in this way when the domain is
- * initialised and also each time we receive an XLBLK_UPDATE event.
- */
-void xlvbd_update_vbds(void)
-{
-    xlvbd_refresh();
-}
-
-/*
- * Set up all the linux device goop for the virtual block devices
- * (vbd's) that we know about. Note that although from the backend
- * driver's p.o.v. VBDs are addressed simply an opaque 16-bit device
- * number, the domain creation tools conventionally allocate these
- * numbers to correspond to those used by 'real' linux -- this is just
- * for convenience as it means e.g. that the same /etc/fstab can be
- * used when booting with or without Xen.
- */
-int xlvbd_init(void)
-{
-    int i, nr;
-    vdisk_t *disks;
-
-    INIT_LIST_HEAD(&vbds_list);
-
-    memset(major_info, 0, sizeof(major_info));
-    
-    disks = xlvbd_probe(&nr);
-    if (disks == NULL) {
-        WPRINTK("failed to probe\n");
-        return -1;
-    }
-
-    for (i = 0; i < nr; i++)
-        xlvbd_device_add(&vbds_list, &disks[i]);
-
-    kfree(disks);
-    return 0;
-}
+void xlvbd_del(blkif_vdev_t handle)
+{
+       struct lvdisk *i;
+
+       list_for_each_entry(i, &vbds_list, list) {
+               if (i->handle == handle) {
+                       xlvbd_device_del(i);
+                       return;
+               }
+       }
+       BUG();
+}
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.h
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.h  Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.h  Fri Aug 19 18:19:28 2005
@@ -87,7 +87,7 @@
     struct work_struct work;
 #ifdef CONFIG_XEN_BLKDEV_GRANT
     u16 shmem_handle;
-    memory_t shmem_vaddr;
+    unsigned long shmem_vaddr;
     grant_ref_t shmem_ref;
 #endif
 } blkif_t;
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/blktap/blktap_controlmsg.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap_controlmsg.c       Thu Aug 
18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap_controlmsg.c       Fri Aug 
19 18:19:28 2005
@@ -320,7 +320,7 @@
     };
     blkif_fe_interface_connect_t *msg = (void*)cmsg.msg;
     msg->handle      = 0;
-    msg->shmem_frame = virt_to_machine(blktap_be_ring.sring) >> PAGE_SHIFT;
+    msg->shmem_frame = virt_to_mfn(blktap_be_ring.sring);
     
     ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
 }
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Fri Aug 19 18:19:28 2005
@@ -49,13 +49,13 @@
     unsigned long    tx_shmem_frame;
 #ifdef CONFIG_XEN_NETDEV_GRANT_TX
     u16              tx_shmem_handle;
-    memory_t         tx_shmem_vaddr; 
+    unsigned long    tx_shmem_vaddr; 
     grant_ref_t      tx_shmem_ref; 
 #endif
     unsigned long    rx_shmem_frame;
 #ifdef CONFIG_XEN_NETDEV_GRANT_RX
     u16              rx_shmem_handle;
-    memory_t         rx_shmem_vaddr; 
+    unsigned long    rx_shmem_vaddr; 
     grant_ref_t      rx_shmem_ref; 
 #endif
     unsigned int     evtchn;
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Fri Aug 19 
18:19:28 2005
@@ -43,7 +43,7 @@
 static int  make_rx_response(netif_t *netif, 
                              u16      id, 
                              s8       st,
-                             memory_t addr,
+                             unsigned long addr,
                              u16      size,
                              u16      csum_valid);
 
@@ -251,7 +251,7 @@
 #else
     struct mmuext_op *mmuext;
 #endif
-    unsigned long vdata, mdata, new_mfn;
+    unsigned long vdata, old_mfn, new_mfn;
     struct sk_buff_head rxq;
     struct sk_buff *skb;
     u16 notify_list[NETIF_RX_RING_SIZE];
@@ -271,7 +271,7 @@
     {
         netif   = netdev_priv(skb->dev);
         vdata   = (unsigned long)skb->data;
-        mdata   = virt_to_machine(vdata);
+        old_mfn = virt_to_mfn(vdata);
 
         /* Memory squeeze? Back off for an arbitrary while. */
         if ( (new_mfn = alloc_mfn()) == 0 )
@@ -293,7 +293,7 @@
         mcl++;
 
 #ifdef CONFIG_XEN_NETDEV_GRANT_RX
-        gop->mfn = mdata >> PAGE_SHIFT;
+        gop->mfn = old_mfn;
         gop->domid = netif->domid;
         gop->handle = netif->rx->ring[
         MASK_NETIF_RX_IDX(netif->rx_resp_prod_copy)].req.gref;
@@ -308,7 +308,7 @@
         mcl++;
 
         mmuext->cmd = MMUEXT_REASSIGN_PAGE;
-        mmuext->mfn = mdata >> PAGE_SHIFT;
+        mmuext->mfn = old_mfn;
         mmuext++;
 #endif
         mmu->ptr = (new_mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
@@ -318,7 +318,7 @@
         __skb_queue_tail(&rxq, skb);
 
 #ifdef DEBUG_GRANT
-        dump_packet('a', mdata, vdata);
+        dump_packet('a', old_mfn, vdata);
 #endif
         /* Filled the batch queue? */
         if ( (mcl - rx_mcl) == ARRAY_SIZE(rx_mcl) )
@@ -345,10 +345,8 @@
 
     mcl = rx_mcl;
 #ifdef CONFIG_XEN_NETDEV_GRANT_RX
-    if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_donate,
-                                           grant_rx_op, gop - grant_rx_op))) {
-        BUG();
-    }
+    BUG_ON(HYPERVISOR_grant_table_op(
+        GNTTABOP_donate, grant_rx_op, gop - grant_rx_op));
     gop = grant_rx_op;
 #else
     mmuext = rx_mmuext;
@@ -361,10 +359,9 @@
         /* Rederive the machine addresses. */
         new_mfn = mcl[0].args[1] >> PAGE_SHIFT;
 #ifdef CONFIG_XEN_NETDEV_GRANT_RX
-        mdata = (unsigned long)skb->data & ~PAGE_MASK;
-#else
-        mdata   = ((mmuext[0].mfn << PAGE_SHIFT) |
-                   ((unsigned long)skb->data & ~PAGE_MASK));
+        old_mfn = 0; /* XXX Fix this so we can free_mfn() on error! */
+#else
+        old_mfn = mmuext[0].mfn;
 #endif
         atomic_set(&(skb_shinfo(skb)->dataref), 1);
         skb_shinfo(skb)->nr_frags = 0;
@@ -379,18 +376,20 @@
         /* Check the reassignment error code. */
         status = NETIF_RSP_OKAY;
 #ifdef CONFIG_XEN_NETDEV_GRANT_RX
-        BUG_ON(gop->status != 0);
+        BUG_ON(gop->status != 0); /* XXX */
 #else
         if ( unlikely(mcl[1].result != 0) )
         {
             DPRINTK("Failed MMU update transferring to DOM%u\n", netif->domid);
-            free_mfn(mdata >> PAGE_SHIFT);
+            free_mfn(old_mfn);
             status = NETIF_RSP_ERROR;
         }
 #endif
         evtchn = netif->evtchn;
         id = netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id;
-        if ( make_rx_response(netif, id, status, mdata,
+        if ( make_rx_response(netif, id, status,
+                              (old_mfn << PAGE_SHIFT) | /* XXX */
+                              ((unsigned long)skb->data & ~PAGE_MASK),
                               size, skb->proto_csum_valid) &&
              (rx_notify[evtchn] == 0) )
         {
@@ -888,7 +887,7 @@
 static int make_rx_response(netif_t *netif, 
                             u16      id, 
                             s8       st,
-                            memory_t addr,
+                            unsigned long addr,
                             u16      size,
                             u16      csum_valid)
 {
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Fri Aug 19 
18:19:28 2005
@@ -448,11 +448,10 @@
         }
         grant_rx_ref[id] = ref;
         gnttab_grant_foreign_transfer_ref(ref, rdomid,
-                                          virt_to_machine(
-                                              skb->head) >> PAGE_SHIFT);
+                                          virt_to_mfn(skb->head));
         np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.gref = ref;
 #endif
-        rx_pfn_array[i] = virt_to_machine(skb->head) >> PAGE_SHIFT;
+        rx_pfn_array[i] = virt_to_mfn(skb->head);
 
        /* Remove this page from pseudo phys map before passing back to Xen. */
        phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] 
@@ -543,13 +542,14 @@
         printk(KERN_ALERT "#### netfront can't claim tx grant reference\n");
         BUG();
     }
-    mfn = virt_to_machine(skb->data) >> PAGE_SHIFT;
+    mfn = virt_to_mfn(skb->data);
     gnttab_grant_foreign_access_ref(ref, rdomid, mfn, GNTMAP_readonly);
-    tx->addr = (ref << PAGE_SHIFT) | ((unsigned long)skb->data & ~PAGE_MASK);
+    tx->addr = ref << PAGE_SHIFT;
     grant_tx_ref[id] = ref;
 #else
-    tx->addr = virt_to_machine(skb->data);
-#endif
+    tx->addr = virt_to_mfn(skb->data) << PAGE_SHIFT;
+#endif
+    tx->addr |= (unsigned long)skb->data & ~PAGE_MASK;
     tx->size = skb->len;
     tx->csum_blank = (skb->ip_summed == CHECKSUM_HW);
 
@@ -720,7 +720,7 @@
     while ((skb = __skb_dequeue(&rxq)) != NULL) {
 #ifdef GRANT_DEBUG
         printk(KERN_ALERT "#### rx_poll     dequeue vdata=%p mfn=%lu\n",
-               skb->data, virt_to_machine(skb->data)>>PAGE_SHIFT);
+               skb->data, virt_to_mfn(skb->data));
         dump_packet('d', skb->data, (unsigned long)skb->data);
 #endif
         /*
@@ -854,18 +854,23 @@
      * interface has been down.
      */
     for (requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++) {
-            if ((unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET) {
-                struct sk_buff *skb = np->tx_skbs[i];
-                
-                tx = &np->tx->ring[requeue_idx++].req;
-                
-                tx->id   = i;
-                tx->addr = virt_to_machine(skb->data);
-                tx->size = skb->len;
-                
-                np->stats.tx_bytes += skb->len;
-                np->stats.tx_packets++;
-            }
+        if ((unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET) {
+            struct sk_buff *skb = np->tx_skbs[i];
+
+            tx = &np->tx->ring[requeue_idx++].req;
+
+            tx->id   = i;
+#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+            tx->addr = 0; /*(ref << PAGE_SHIFT) |*/
+#else
+            tx->addr = virt_to_mfn(skb->data) << PAGE_SHIFT;
+#endif
+            tx->addr |= (unsigned long)skb->data & ~PAGE_MASK;
+            tx->size = skb->len;
+
+            np->stats.tx_bytes += skb->len;
+            np->stats.tx_packets++;
+        }
     }
     wmb();
     np->tx->req_prod = requeue_idx;
@@ -922,7 +927,7 @@
     netif_fe_interface_connect_t *msg = (void*)cmsg.msg;
 
     msg->handle = np->handle;
-    msg->tx_shmem_frame = (virt_to_machine(np->tx) >> PAGE_SHIFT);
+    msg->tx_shmem_frame = virt_to_mfn(np->tx);
 #ifdef CONFIG_XEN_NETDEV_GRANT_TX
     msg->tx_shmem_ref   = (u32)gnttab_claim_grant_reference(&gref_tx_head, 
                                                             gref_tx_terminal);
@@ -934,7 +939,7 @@
                                      msg->tx_shmem_frame, 0);
 #endif
 
-    msg->rx_shmem_frame = (virt_to_machine(np->rx) >> PAGE_SHIFT);
+    msg->rx_shmem_frame = virt_to_mfn(np->rx);
 #ifdef CONFIG_XEN_NETDEV_GRANT_RX
     msg->rx_shmem_ref   = (u32)gnttab_claim_grant_reference(&gref_rx_head, 
                                                             gref_rx_terminal);
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/usbback/usbback.c
--- a/linux-2.6-xen-sparse/drivers/xen/usbback/usbback.c        Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/usbback/usbback.c        Fri Aug 19 
18:19:28 2005
@@ -657,8 +657,8 @@
         phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] =
             FOREIGN_FRAME((buffer_mach + offset) >> PAGE_SHIFT);
 
-        ASSERT(virt_to_machine(MMAP_VADDR(pending_idx, i))
-               == buffer_mach + i << PAGE_SHIFT);
+        ASSERT(virt_to_mfn(MMAP_VADDR(pending_idx, i))
+               == ((buffer_mach >> PAGE_SHIFT) + i));
     }
 
     if ( req->pipe_type == 0 && req->num_iso > 0 ) /* Maybe schedule ISO... */
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/usbfront/usbfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/usbfront/usbfront.c      Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/usbfront/usbfront.c      Fri Aug 19 
18:19:28 2005
@@ -195,7 +195,7 @@
         }
 
         urb_priv->schedule = schedule;
-       req->iso_schedule = virt_to_machine(schedule);
+       req->iso_schedule = virt_to_mfn(schedule) << PAGE_SHIFT;
 
         return 0;
 }
@@ -212,7 +212,7 @@
 #if DEBUG
         printk(KERN_DEBUG
                "usbif = %p, req_prod = %d (@ 0x%lx), resp_prod = %d, resp_cons 
= %d\n",
-               usbif, usbif->req_prod, virt_to_machine(&usbif->req_prod),
+               usbif, usbif->req_prod, virt_to_mfn(&usbif->req_prod),
                usbif->resp_prod, xhci->usb_resp_cons);
 #endif
         
@@ -232,7 +232,7 @@
         req->operation       = USBIF_OP_IO;
         req->port            = 0; /* We don't care what the port is. */
         req->id              = (unsigned long) urb->hcpriv;
-        req->transfer_buffer = virt_to_machine(urb->transfer_buffer);
+        req->transfer_buffer = virt_to_mfn(urb->transfer_buffer) << PAGE_SHIFT;
        req->devnum          = usb_pipedevice(urb->pipe);
         req->direction       = usb_pipein(urb->pipe);
        req->speed           = usb_pipeslow(urb->pipe);
@@ -280,7 +280,7 @@
        printk(KERN_DEBUG
                "queuing probe: req_prod = %d (@ 0x%lx), resp_prod = %d, "
                "resp_cons = %d\n", usbif->req_prod,
-               virt_to_machine(&usbif->req_prod),
+               virt_to_mfn(&usbif->req_prod),
               usbif->resp_prod, xhci->usb_resp_cons);
 #endif
  
@@ -1555,7 +1555,7 @@
         cmsg.type      = CMSG_USBIF_FE;
         cmsg.subtype   = CMSG_USBIF_FE_INTERFACE_CONNECT;
         cmsg.length    = sizeof(usbif_fe_interface_connect_t);
-        up.shmem_frame = virt_to_machine(sring) >> PAGE_SHIFT;
+        up.shmem_frame = virt_to_mfn(sring);
         memcpy(cmsg.msg, &up, sizeof(up));
         
         /* Tell the controller to bring up the interface. */
@@ -1599,7 +1599,7 @@
 
        DPRINTK(KERN_INFO __FILE__
                 ": USB XHCI: SHM at %p (0x%lx), EVTCHN %d\n",
-                xhci->usb_ring.sring, virt_to_machine(xhci->usbif),
+                xhci->usb_ring.sring, virt_to_mfn(xhci->usbif),
                 xhci->evtchn);
 
         xhci->state = USBIF_STATE_CONNECTED;
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Fri Aug 19 
18:19:28 2005
@@ -48,13 +48,12 @@
 
 static inline struct ringbuf_head *outbuf(void)
 {
-       return machine_to_virt(xen_start_info.store_mfn << PAGE_SHIFT);
+       return mfn_to_virt(xen_start_info.store_mfn);
 }
 
 static inline struct ringbuf_head *inbuf(void)
 {
-       return machine_to_virt(xen_start_info.store_mfn << PAGE_SHIFT)
-               + PAGE_SIZE/2;
+       return mfn_to_virt(xen_start_info.store_mfn) + PAGE_SIZE/2;
 }
 
 static irqreturn_t wake_waiting(int irq, void *unused, struct pt_regs *regs)
@@ -219,8 +218,7 @@
        }
 
        /* FIXME zero out page -- domain builder should probably do this*/
-       memset(machine_to_virt(xen_start_info.store_mfn << PAGE_SHIFT),
-              0, PAGE_SIZE);
+       memset(mfn_to_virt(xen_start_info.store_mfn), 0, PAGE_SIZE);
 
        return 0;
 }
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Fri Aug 19 
18:19:28 2005
@@ -48,15 +48,7 @@
 match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev)
 {
        for (; !streq(arr->devicetype, ""); arr++) {
-               if (!streq(arr->devicetype, dev->devicetype))
-                       continue;
-
-               /* If they don't care what subtype, it's a match. */
-               if (streq(arr->subtype, ""))
-                       return arr;
-
-               /* If they care, device must have (same) subtype. */
-               if (dev->subtype && streq(arr->subtype, dev->subtype))
+               if (streq(arr->devicetype, dev->devicetype))
                        return arr;
        }
        return NULL;
@@ -72,10 +64,102 @@
        return match_device(drv->ids, to_xenbus_device(_dev)) != NULL;
 }
 
+struct xen_bus_type
+{
+       char *root;
+       unsigned int levels;
+       int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename);
+       int (*probe)(const char *type, const char *dir);
+       struct bus_type bus;
+       struct device dev;
+};
+
+/* device/<type>/<id> => <type>-<id> */
+static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
+{
+       nodename = strchr(nodename, '/');
+       if (!nodename || strlen(nodename + 1) >= BUS_ID_SIZE) {
+               printk(KERN_WARNING "XENBUS: bad frontend %s\n", nodename);
+               return -EINVAL;
+       }
+
+       strlcpy(bus_id, nodename + 1, BUS_ID_SIZE);
+       if (!strchr(bus_id, '/')) {
+               printk(KERN_WARNING "XENBUS: bus_id %s no slash\n", bus_id);
+               return -EINVAL;
+       }
+       *strchr(bus_id, '/') = '-';
+       return 0;
+}
+
 /* Bus type for frontend drivers. */
-static struct bus_type xenbus_type = {
-       .name  = "xenbus",
-       .match = xenbus_match,
+static int xenbus_probe_frontend(const char *type, const char *name);
+static struct xen_bus_type xenbus_frontend = {
+       .root = "device",
+       .levels = 2,            /* device/type/<id> */
+       .get_bus_id = frontend_bus_id,
+       .probe = xenbus_probe_frontend,
+       .bus = {
+               .name  = "xen",
+               .match = xenbus_match,
+       },
+       .dev = {
+               .bus_id = "xen",
+       },
+};
+
+/* backend/<type>/<fe-uuid>/<id> => <type>-<fe-domid>-<id> */
+static int backend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
+{
+       int domid, err;
+       const char *devid, *type, *frontend;
+       unsigned int typelen;
+
+       type = strchr(nodename, '/');
+       if (!type)
+               return -EINVAL;
+       type++;
+       typelen = strcspn(type, "/");
+       if (!typelen || type[typelen] != '/')
+               return -EINVAL;
+
+       devid = strrchr(nodename, '/') + 1;
+
+       err = xenbus_gather(nodename, "frontend-id", "%i", &domid,
+                           "frontend", NULL, &frontend,
+                           NULL);
+       if (err)
+               return err;
+       if (strlen(frontend) == 0)
+               err = -ERANGE;
+
+       if (!err && !xenbus_exists(frontend, ""))
+               err = -ENOENT;
+
+       if (err) {
+               kfree(frontend);
+               return err;
+       }
+
+       if (snprintf(bus_id, BUS_ID_SIZE,
+                    "%.*s-%i-%s", typelen, type, domid, devid) >= BUS_ID_SIZE)
+               return -ENOSPC;
+       return 0;
+}
+
+static int xenbus_probe_backend(const char *type, const char *uuid);
+static struct xen_bus_type xenbus_backend = {
+       .root = "backend",
+       .levels = 3,            /* backend/type/<frontend>/<id> */
+       .get_bus_id = backend_bus_id,
+       .probe = xenbus_probe_backend,
+       .bus = {
+               .name  = "xen-backend",
+               .match = xenbus_match,
+       },
+       .dev = {
+               .bus_id = "xen-backend",
+       },
 };
 
 static int xenbus_dev_probe(struct device *_dev)
@@ -104,12 +188,13 @@
        return drv->remove(dev);
 }
 
-int xenbus_register_driver(struct xenbus_driver *drv)
+static int xenbus_register_driver(struct xenbus_driver *drv,
+                                 struct xen_bus_type *bus)
 {
        int err;
 
        drv->driver.name = drv->name;
-       drv->driver.bus = &xenbus_type;
+       drv->driver.bus = &bus->bus;
        drv->driver.owner = drv->owner;
        drv->driver.probe = xenbus_dev_probe;
        drv->driver.remove = xenbus_dev_remove;
@@ -120,6 +205,16 @@
        return err;
 }
 
+int xenbus_register_device(struct xenbus_driver *drv)
+{
+       return xenbus_register_driver(drv, &xenbus_frontend);
+}
+
+int xenbus_register_backend(struct xenbus_driver *drv)
+{
+       return xenbus_register_driver(drv, &xenbus_backend);
+}
+
 void xenbus_unregister_driver(struct xenbus_driver *drv)
 {
        down(&xenbus_lock);
@@ -130,52 +225,98 @@
 struct xb_find_info
 {
        struct xenbus_device *dev;
-       const char *busid;
+       const char *nodename;
 };
 
 static int cmp_dev(struct device *dev, void *data)
 {
+       struct xenbus_device *xendev = to_xenbus_device(dev);
        struct xb_find_info *info = data;
 
-       if (streq(dev->bus_id, info->busid)) {
-               info->dev = container_of(get_device(dev),
-                                        struct xenbus_device, dev);
+       if (streq(xendev->nodename, info->nodename)) {
+               info->dev = xendev;
+               get_device(dev);
                return 1;
        }
        return 0;
 }
 
-/* FIXME: device_find is fixed in 2.6.13-rc2 according to Greg KH --RR */
-struct xenbus_device *xenbus_device_find(const char *busid)
-{
-       struct xb_find_info info = { .dev = NULL, .busid = busid };
-
-       bus_for_each_dev(&xenbus_type, NULL, &info, cmp_dev);
+struct xenbus_device *xenbus_device_find(const char *nodename,
+                                        struct bus_type *bus)
+{
+       struct xb_find_info info = { .dev = NULL, .nodename = nodename };
+
+       bus_for_each_dev(bus, NULL, &info, cmp_dev);
        return info.dev;
 }
 
+static int cleanup_dev(struct device *dev, void *data)
+{
+       struct xenbus_device *xendev = to_xenbus_device(dev);
+       struct xb_find_info *info = data;
+       int len = strlen(info->nodename);
+
+       if (!strncmp(xendev->nodename, info->nodename, len)) {
+               info->dev = xendev;
+               get_device(dev);
+               return 1;
+       }
+       return 0;
+}
+
+static void xenbus_cleanup_devices(const char *path, struct bus_type *bus)
+{
+       struct xb_find_info info = { .nodename = path };
+
+       do {
+               info.dev = NULL;
+               bus_for_each_dev(bus, NULL, &info, cleanup_dev);
+               if (info.dev) {
+                       device_unregister(&info.dev->dev);
+                       put_device(&info.dev->dev);
+               }
+       } while (info.dev);
+}
 
 static void xenbus_release_device(struct device *dev)
 {
        if (dev) {
                struct xenbus_device *xendev = to_xenbus_device(dev);
 
-               kfree(xendev->subtype);
                kfree(xendev);
        }
 }
-/* devices/<typename>/<name> */
-static int xenbus_probe_device(const char *dirpath, const char *devicetype,
-                              const char *name)
+
+/* Simplified asprintf. */
+static char *kasprintf(const char *fmt, ...)
+{
+       va_list ap;
+       unsigned int len;
+       char *p, dummy[1];
+
+       va_start(ap, fmt);
+       /* FIXME: vsnprintf has a bug, NULL should work */
+       len = vsnprintf(dummy, 0, fmt, ap);
+       va_end(ap);
+
+       p = kmalloc(len + 1, GFP_KERNEL);
+       if (!p)
+               return NULL;
+       va_start(ap, fmt);
+       vsprintf(p, fmt, ap);
+       va_end(ap);
+       return p;
+}
+
+static int xenbus_probe_node(struct xen_bus_type *bus,
+                            const char *type,
+                            const char *nodename)
 {
        int err;
        struct xenbus_device *xendev;
        unsigned int stringlen;
 
-       /* Nodename: /device/<typename>/<name>/ */
-       stringlen = strlen(dirpath) + strlen(devicetype) + strlen(name) + 3;
-       /* Typename */
-       stringlen += strlen(devicetype) + 1;
+       stringlen = strlen(nodename) + 1 + strlen(type) + 1;
        xendev = kmalloc(sizeof(*xendev) + stringlen, GFP_KERNEL);
        if (!xendev)
                return -ENOMEM;
@@ -183,38 +324,103 @@
 
        /* Copy the strings into the extra space. */
        xendev->nodename = (char *)(xendev + 1);
-       sprintf(xendev->nodename, "%s/%s/%s", dirpath, devicetype, name);
+       strcpy(xendev->nodename, nodename);
        xendev->devicetype = xendev->nodename + strlen(xendev->nodename) + 1;
-       strcpy(xendev->devicetype, devicetype);
-
-       /* FIXME: look for "subtype" field. */
-       snprintf(xendev->dev.bus_id, BUS_ID_SIZE, "%s-%s", devicetype, name);
-       xendev->dev.bus = &xenbus_type;
+       strcpy(xendev->devicetype, type);
+
+       xendev->dev.parent = &bus->dev;
+       xendev->dev.bus = &bus->bus;
        xendev->dev.release = xenbus_release_device;
+
+       err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename);
+       if (err) {
+               kfree(xendev);
+               return err;
+       }
 
        /* Register with generic device framework. */
        err = device_register(&xendev->dev);
        if (err) {
-               printk("XENBUS: Registering device %s: error %i\n",
-                      xendev->dev.bus_id, err);
+               printk("XENBUS: Registering %s device %s: error %i\n",
+                      bus->bus.name, xendev->dev.bus_id, err);
                kfree(xendev);
        }
        return err;
 }
 
-static int xenbus_probe_device_type(const char *dirpath, const char *typename)
+/* device/<typename>/<name> */
+static int xenbus_probe_frontend(const char *type, const char *name)
+{
+       char *nodename;
+       int err;
+
+       nodename = kasprintf("%s/%s/%s", xenbus_frontend.root, type, name);
+       if (!nodename)
+               return -ENOMEM;
+       
+       err = xenbus_probe_node(&xenbus_frontend, type, nodename);
+       kfree(nodename);
+       return err;
+}
+
+/* backend/<typename>/<frontend-uuid>/<name> */
+static int xenbus_probe_backend_unit(const char *dir,
+                                    const char *type,
+                                    const char *name)
+{
+       char *nodename;
+       int err;
+
+       nodename = kasprintf("%s/%s", dir, name);
+       if (!nodename)
+               return -ENOMEM;
+
+       err = xenbus_probe_node(&xenbus_backend, type, nodename);
+       kfree(nodename);
+       return err;
+}
+
+/* backend/<typename>/<frontend-uuid> */
+static int xenbus_probe_backend(const char *type, const char *uuid)
+{
+       char *nodename;
+       int err = 0;
+       char **dir;
+       unsigned int i, dir_n = 0;
+
+       nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, uuid);
+       if (!nodename)
+               return -ENOMEM;
+
+       dir = xenbus_directory(nodename, "", &dir_n);
+       if (IS_ERR(dir)) {
+               kfree(nodename);
+               return PTR_ERR(dir);
+       }
+
+       for (i = 0; i < dir_n; i++) {
+               err = xenbus_probe_backend_unit(nodename, type, dir[i]);
+               if (err)
+                       break;
+       }
+       kfree(dir);
+       kfree(nodename);
+       return err;
+}
+
+static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type)
 {
        int err = 0;
        char **dir;
        unsigned int dir_n = 0;
        int i;
 
-       dir = xenbus_directory(dirpath, typename, &dir_n);
+       dir = xenbus_directory(bus->root, type, &dir_n);
        if (IS_ERR(dir))
                return PTR_ERR(dir);
 
        for (i = 0; i < dir_n; i++) {
-               err = xenbus_probe_device(dirpath, typename, dir[i]);
+               err = bus->probe(type, dir[i]);
                if (err)
                        break;
        }
@@ -222,18 +428,18 @@
        return err;
 }
 
-static int xenbus_probe_devices(const char *path)
+static int xenbus_probe_devices(struct xen_bus_type *bus)
 {
        int err = 0;
        char **dir;
        unsigned int i, dir_n;
 
-       dir = xenbus_directory(path, "", &dir_n);
+       dir = xenbus_directory(bus->root, "", &dir_n);
        if (IS_ERR(dir))
                return PTR_ERR(dir);
 
        for (i = 0; i < dir_n; i++) {
-               err = xenbus_probe_device_type(path, dir[i]);
+               err = xenbus_probe_device_type(bus, dir[i]);
                if (err)
                        break;
        }
@@ -251,58 +457,117 @@
        return ret;
 }
 
-static void dev_changed(struct xenbus_watch *watch, const char *node)
-{
-       char busid[BUS_ID_SIZE];
-       int exists;
+static int strsep_len(const char *str, char c, unsigned int len)
+{
+       unsigned int i;
+
+       for (i = 0; str[i]; i++)
+               if (str[i] == c) {
+                       if (len == 0)
+                               return i;
+                       len--;
+               }
+       return (len == 0) ? i : -ERANGE;
+}
+
+static void dev_changed(const char *node, struct xen_bus_type *bus)
+{
+       int exists, rootlen;
        struct xenbus_device *dev;
-       char *p;
-
-       /* Node is of form device/<type>/<identifier>[/...] */
-       if (char_count(node, '/') != 2)
+       char type[BUS_ID_SIZE];
+       const char *p, *root;
+
+       if (char_count(node, '/') < 2)
+               return;
+
+       exists = xenbus_exists(node, "");
+       if (!exists) {
+               xenbus_cleanup_devices(node, &bus->bus);
                return;
-
-       /* Created or deleted? */
-       exists = xenbus_exists(node, "");
-
+       }
+
+       /* backend/<type>/... or device/<type>/... */
        p = strchr(node, '/') + 1;
-       if (strlen(p) + 1 > BUS_ID_SIZE) {
-               printk("Device for node %s is too big!\n", node);
+       snprintf(type, BUS_ID_SIZE, "%.*s", strcspn(p, "/"), p);
+       type[BUS_ID_SIZE-1] = '\0';
+
+       rootlen = strsep_len(node, '/', bus->levels);
+       if (rootlen < 0)
                return;
-       }
-       /* Bus ID is name with / changed to - */
-       strcpy(busid, p);
-       *strchr(busid, '/') = '-';
-
-       dev = xenbus_device_find(busid);
-       printk("xenbus: device %s %s\n", busid, dev ? "exists" : "new");
-       if (dev && !exists) {
-               printk("xenbus: Unregistering device %s\n", busid);
-               /* FIXME: free? */
-               device_unregister(&dev->dev);
-       } else if (!dev && exists) {
-               printk("xenbus: Adding device %s\n", busid);
-               /* Hack bus id back into two strings. */
-               *strrchr(busid, '-') = '\0';
-               xenbus_probe_device("device", busid, busid+strlen(busid)+1);
-       } else
-               printk("xenbus: strange, %s already %s\n", busid,
-                      exists ? "exists" : "gone");
-       if (dev)
+       root = kasprintf("%.*s", rootlen, node);
+       if (!root)
+               return;
+
+       dev = xenbus_device_find(root, &bus->bus);
+       if (!dev)
+               xenbus_probe_node(bus, type, root);
+       else
                put_device(&dev->dev);
+
+       kfree(root);
+}
+
+static void frontend_changed(struct xenbus_watch *watch, const char *node)
+{
+       dev_changed(node, &xenbus_frontend);
+}
+
+static void backend_changed(struct xenbus_watch *watch, const char *node)
+{
+       dev_changed(node, &xenbus_backend);
 }
 
 /* We watch for devices appearing and vanishing. */
-static struct xenbus_watch dev_watch = {
-       /* FIXME: Ideally we'd only watch for changes 2 levels deep... */
+static struct xenbus_watch fe_watch = {
        .node = "device",
-       .callback = dev_changed,
+       .callback = frontend_changed,
 };
+
+static struct xenbus_watch be_watch = {
+       .node = "backend",
+       .callback = backend_changed,
+};
+
+static int suspend_dev(struct device *dev, void *data)
+{
+       int err = 0;
+       struct xenbus_driver *drv;
+       struct xenbus_device *xdev;
+
+       if (dev->driver == NULL)
+               return 0;
+       drv = to_xenbus_driver(dev->driver);
+       xdev = container_of(dev, struct xenbus_device, dev);
+       if (drv->suspend)
+               err = drv->suspend(xdev);
+       if (err)
+               printk("xenbus: suspend %s failed: %i\n", dev->bus_id, err);
+       return 0;
+}
+
+static int resume_dev(struct device *dev, void *data)
+{
+       int err = 0;
+       struct xenbus_driver *drv;
+       struct xenbus_device *xdev;
+
+       if (dev->driver == NULL)
+               return 0;
+       drv = to_xenbus_driver(dev->driver);
+       xdev = container_of(dev, struct xenbus_device, dev);
+       if (drv->resume)
+               err = drv->resume(xdev);
+       if (err)
+               printk("xenbus: resume %s failed: %i\n", dev->bus_id, err);
+       return 0;
+}
 
 void xenbus_suspend(void)
 {
        /* We keep lock, so no comms can happen as page moves. */
        down(&xenbus_lock);
+       bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
+       bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev);
        xb_suspend_comms();
 }
 
@@ -310,6 +575,8 @@
 {
        xb_init_comms();
        reregister_xenbus_watches();
+       bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
+       bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev);
        up(&xenbus_lock);
 }
 
@@ -354,30 +621,23 @@
        }
 
        down(&xenbus_lock);
-       err = notifier_call_chain(&xenstore_chain, 0, 0);
+       /* Enumerate devices in xenstore. */
+       xenbus_probe_devices(&xenbus_frontend);
+       xenbus_probe_devices(&xenbus_backend);
+       /* Watch for changes. */
+       register_xenbus_watch(&fe_watch);
+       register_xenbus_watch(&be_watch);
        up(&xenbus_lock);
-
-       if (err == NOTIFY_BAD) {
-               printk("%s: calling xenstore notify chain failed\n",
-                      __FUNCTION__);
-               return -EINVAL;
-       }
-
-       err = 0;
-
-       down(&xenbus_lock);
-       /* Enumerate devices in xenstore. */
-       xenbus_probe_devices("device");
-       /* Watch for changes. */
-       register_xenbus_watch(&dev_watch);
-       up(&xenbus_lock);
        return 0;
 }
 
 static int __init xenbus_probe_init(void)
 {
-       bus_register(&xenbus_type);
-
+       bus_register(&xenbus_frontend.bus);
+       bus_register(&xenbus_backend.bus);
+       device_register(&xenbus_frontend.dev);
+       device_register(&xenbus_backend.dev);
+       
        if (!xen_start_info.store_evtchn)
                return 0;
 
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Fri Aug 19 
18:19:28 2005
@@ -187,6 +187,7 @@
        static char buffer[4096];
 
        BUG_ON(down_trylock(&xenbus_lock) == 0);
+       /* XXX FIXME: might not be correct if name == "" */
        BUG_ON(strlen(dir) + strlen("/") + strlen(name) + 1 > sizeof(buffer));
 
        strcpy(buffer, dir);
@@ -399,9 +400,12 @@
                        ret = PTR_ERR(p);
                        break;
                }
-               if (sscanf(p, fmt, result) == 0)
-                       ret = -EINVAL;
-               kfree(p);
+               if (fmt) {
+                       if (sscanf(p, fmt, result) == 0)
+                               ret = -EINVAL;
+                       kfree(p);
+               } else
+                       *(char **)result = p;
        }
        va_end(ap);
        return ret;
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/desc.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/desc.h      Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/desc.h      Fri Aug 19 
18:19:28 2005
@@ -93,7 +93,7 @@
 
 static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
 {
-#define C(i) 
HYPERVISOR_update_descriptor(virt_to_machine(&get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN
 + i]), ((u32 *)&t->tls_array[i])[0], ((u32 *)&t->tls_array[i])[1])
+#define C(i) 
HYPERVISOR_update_descriptor(virt_to_machine(&get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN
 + i]), *(u64 *)&t->tls_array[i])
        C(0); C(1); C(2);
 #undef C
 }
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/fixmap.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/fixmap.h    Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/fixmap.h    Fri Aug 19 
18:19:28 2005
@@ -102,8 +102,8 @@
        __end_of_fixed_addresses
 };
 
-extern void __set_fixmap (enum fixed_addresses idx,
-                                       unsigned long phys, pgprot_t flags);
+extern void __set_fixmap(
+       enum fixed_addresses idx, maddr_t phys, pgprot_t flags);
 
 #define set_fixmap(idx, phys) \
                __set_fixmap(idx, phys, PAGE_KERNEL)
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Fri Aug 19 
18:19:28 2005
@@ -163,7 +163,7 @@
         TRAP_INSTR
         : "=a" (ret), "=b" (ign)
        : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield)
-       : "memory" );
+       : "memory", "ecx" );
 
     return ret;
 }
@@ -178,7 +178,7 @@
         TRAP_INSTR
         : "=a" (ret), "=b" (ign1)
        : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block)
-       : "memory" );
+       : "memory", "ecx" );
 
     return ret;
 }
@@ -194,7 +194,7 @@
         : "=a" (ret), "=b" (ign1)
        : "0" (__HYPERVISOR_sched_op),
          "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
-        : "memory" );
+        : "memory", "ecx" );
 
     return ret;
 }
@@ -210,7 +210,7 @@
         : "=a" (ret), "=b" (ign1)
        : "0" (__HYPERVISOR_sched_op),
          "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
-        : "memory" );
+        : "memory", "ecx" );
 
     return ret;
 }
@@ -228,7 +228,7 @@
         : "=a" (ret), "=b" (ign1), "=S" (ign2)
        : "0" (__HYPERVISOR_sched_op),
         "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), 
-        "S" (srec) : "memory");
+        "S" (srec) : "memory", "ecx");
 
     return ret;
 }
@@ -244,7 +244,7 @@
         : "=a" (ret), "=b" (ign1)
        : "0" (__HYPERVISOR_sched_op),
          "1" (SCHEDOP_shutdown | (SHUTDOWN_crash << SCHEDOP_reasonshift))
-        : "memory" );
+        : "memory", "ecx" );
 
     return ret;
 }
@@ -316,16 +316,17 @@
 
 static inline int
 HYPERVISOR_update_descriptor(
-    unsigned long ma, unsigned long word1, unsigned long word2)
-{
-    int ret;
-    unsigned long ign1, ign2, ign3;
-
-    __asm__ __volatile__ (
-        TRAP_INSTR
-        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
-       : "0" (__HYPERVISOR_update_descriptor), "1" (ma), "2" (word1),
-         "3" (word2)
+    u64 ma, u64 desc)
+{
+    int ret;
+    unsigned long ign1, ign2, ign3, ign4;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
+       : "0" (__HYPERVISOR_update_descriptor),
+         "1" ((unsigned long)ma), "2" ((unsigned long)(ma>>32)),
+         "3" ((unsigned long)desc), "4" ((unsigned long)(desc>>32))
        : "memory" );
 
     return ret;
@@ -529,12 +530,15 @@
 {
     int ret;
     unsigned long ign1;
+    /* Yes, I really do want to clobber edx here: when we resume a
+       vcpu after unpickling a multi-processor domain, it returns
+       here, but clobbers all of the call clobbered registers. */
     __asm__ __volatile__ (
         TRAP_INSTR
         : "=a" (ret), "=b" (ign1)
        : "0" (__HYPERVISOR_sched_op),
          "1" (SCHEDOP_vcpu_down | (vcpu << SCHEDOP_vcpushift))
-        : "memory" );
+        : "memory", "ecx", "edx" );
 
     return ret;
 }
@@ -550,8 +554,26 @@
         : "=a" (ret), "=b" (ign1)
        : "0" (__HYPERVISOR_sched_op),
          "1" (SCHEDOP_vcpu_up | (vcpu << SCHEDOP_vcpushift))
+        : "memory", "ecx" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_vcpu_pickle(
+    int vcpu, vcpu_guest_context_t *ctxt)
+{
+    int ret;
+    unsigned long ign1, ign2;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2)
+       : "0" (__HYPERVISOR_sched_op),
+         "1" (SCHEDOP_vcpu_pickle | (vcpu << SCHEDOP_vcpushift)),
+         "2" (ctxt)
         : "memory" );
 
     return ret;
 }
+
 #endif /* __HYPERCALL_H__ */
diff -r 99914b54f7bf -r 81576d3d1ca8 
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      Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h      Fri Aug 19 
18:19:28 2005
@@ -63,20 +63,25 @@
 extern unsigned int *phys_to_machine_mapping;
 #define pfn_to_mfn(_pfn) ((unsigned long)(phys_to_machine_mapping[(_pfn)]))
 #define mfn_to_pfn(_mfn) ((unsigned long)(machine_to_phys_mapping[(_mfn)]))
+
+/* Definitions for machine and pseudophysical addresses. */
 #ifdef CONFIG_X86_PAE
-typedef unsigned long long physaddr_t;
-#else
-typedef unsigned long physaddr_t;
-#endif
-static inline physaddr_t phys_to_machine(physaddr_t phys)
-{
-       physaddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
+typedef unsigned long long paddr_t;
+typedef unsigned long long maddr_t;
+#else
+typedef unsigned long paddr_t;
+typedef unsigned long maddr_t;
+#endif
+
+static inline maddr_t phys_to_machine(paddr_t phys)
+{
+       maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
        machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
        return machine;
 }
-static inline physaddr_t machine_to_phys(physaddr_t machine)
-{
-       physaddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
+static inline paddr_t machine_to_phys(maddr_t machine)
+{
+       paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
        phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
        return phys;
 }
@@ -233,8 +238,10 @@
                 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
 /* VIRT <-> MACHINE conversion */
-#define virt_to_machine(_a)    (phys_to_machine(__pa(_a)))
-#define machine_to_virt(_m)    (__va(machine_to_phys(_m)))
+#define virt_to_machine(v)     (phys_to_machine(__pa(v)))
+#define machine_to_virt(m)     (__va(machine_to_phys(m)))
+#define virt_to_mfn(v)         (pfn_to_mfn(__pa(v) >> PAGE_SHIFT))
+#define mfn_to_virt(m)         (__va(mfn_to_pfn(m) << PAGE_SHIFT))
 
 #endif /* __KERNEL__ */
 
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h   Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h   Fri Aug 19 
18:19:28 2005
@@ -32,7 +32,7 @@
  */
 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
 extern unsigned long empty_zero_page[1024];
-extern pgd_t swapper_pg_dir[1024];
+extern pgd_t *swapper_pg_dir;
 extern kmem_cache_t *pgd_cache;
 extern kmem_cache_t *pmd_cache;
 extern spinlock_t pgd_lock;
@@ -450,7 +450,7 @@
 #define arbitrary_virt_to_machine(__va)                                        
\
 ({                                                                     \
        pte_t *__pte = virt_to_ptep(__va);                              \
-       unsigned long __pa = (*(unsigned long *)__pte) & PAGE_MASK;     \
+       maddr_t __pa = (maddr_t)pte_mfn(*__pte) << PAGE_SHIFT;          \
        __pa | ((unsigned long)(__va) & (PAGE_SIZE-1));                 \
 })
 
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h       Thu Aug 
18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h       Fri Aug 
19 18:19:28 2005
@@ -502,4 +502,21 @@
     return ret;
 }
 
+static inline int
+HYPERVISOR_vcpu_pickle(
+    int vcpu, vcpu_guest_context_t *ctxt)
+{
+    int ret;
+    unsigned long ign1, ign2;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2)
+       : "0" (__HYPERVISOR_sched_op),
+         "1" (SCHEDOP_vcpu_pickle | (vcpu << SCHEDOP_vcpushift)),
+         "2" (ctxt)
+        : __syscall_clobber );
+
+    return ret;
+}
+
 #endif /* __HYPERCALL_H__ */
diff -r 99914b54f7bf -r 81576d3d1ca8 
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    Thu Aug 18 
18:40:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h    Fri Aug 19 
18:19:28 2005
@@ -65,16 +65,21 @@
 extern u32 *phys_to_machine_mapping;
 #define pfn_to_mfn(_pfn) ((unsigned long) phys_to_machine_mapping[(unsigned 
int)(_pfn)])
 #define mfn_to_pfn(_mfn) ((unsigned long) machine_to_phys_mapping[(unsigned 
int)(_mfn)])
-static inline unsigned long phys_to_machine(unsigned long phys)
-{
-       unsigned long machine = pfn_to_mfn(phys >> PAGE_SHIFT);
+
+/* Definitions for machine and pseudophysical addresses. */
+typedef unsigned long paddr_t;
+typedef unsigned long maddr_t;
+
+static inline maddr_t phys_to_machine(paddr_t phys)
+{
+       maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
        machine = (machine << PAGE_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);
+static inline paddr_t machine_to_phys(maddr_t machine)
+{
+       paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
        phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
        return phys;
 }
@@ -211,8 +216,10 @@
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
 
 /* VIRT <-> MACHINE conversion */
-#define virt_to_machine(_a)    (phys_to_machine(__pa(_a)))
-#define machine_to_virt(_m)    (__va(machine_to_phys(_m)))
+#define virt_to_machine(v)     (phys_to_machine(__pa(v)))
+#define machine_to_virt(m)     (__va(machine_to_phys(m)))
+#define virt_to_mfn(v)         (pfn_to_mfn(__pa(v) >> PAGE_SHIFT))
+#define mfn_to_virt(m)         (__va(mfn_to_pfn(m) << PAGE_SHIFT))
 
 #define VM_DATA_DEFAULT_FLAGS \
        (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/include/asm-xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Fri Aug 19 18:19:28 2005
@@ -37,7 +37,6 @@
 /* A xenbus device. */
 struct xenbus_device {
        char *devicetype;
-       char *subtype;
        char *nodename;
        struct device dev;
        int has_error;
@@ -53,7 +52,6 @@
 {
        /* .../device/<device_type>/<identifier> */
        char devicetype[32];    /* General class of device. */
-       char subtype[32];       /* Contents of "subtype" for this device */
 };
 
 /* A xenbus driver. */
@@ -61,9 +59,11 @@
        char *name;
        struct module *owner;
        const struct xenbus_device_id *ids;
-       int  (*probe)    (struct xenbus_device * dev,
-                         const struct xenbus_device_id * id);
-       int  (*remove)   (struct xenbus_device * dev);
+       int (*probe)(struct xenbus_device *dev,
+                    const struct xenbus_device_id *id);
+       int (*remove)(struct xenbus_device *dev);
+       int (*suspend)(struct xenbus_device *dev);
+       int (*resume)(struct xenbus_device *dev);
        struct device_driver driver;
 };
 
@@ -72,7 +72,8 @@
        return container_of(drv, struct xenbus_driver, driver);
 }
 
-int xenbus_register_driver(struct xenbus_driver *drv);
+int xenbus_register_device(struct xenbus_driver *drv);
+int xenbus_register_backend(struct xenbus_driver *drv);
 void xenbus_unregister_driver(struct xenbus_driver *drv);
 
 /* Caller must hold this lock to call these functions: it's also held
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/debugger/libxendebug/xendebug.c
--- a/tools/debugger/libxendebug/xendebug.c     Thu Aug 18 18:40:02 2005
+++ b/tools/debugger/libxendebug/xendebug.c     Fri Aug 19 18:19:28 2005
@@ -40,7 +40,7 @@
 typedef struct bwcpoint                           /* break/watch/catch point */
 {
     struct list_head list;
-    memory_t address;
+    unsigned long address;
     u32 domain;
     u8 old_value;                             /* old value for software bkpt */
 } bwcpoint_t, *bwcpoint_p;
@@ -311,7 +311,7 @@
 /* access to one page */
 static int
 xendebug_memory_page (domain_context_p ctxt, int xc_handle, u32 vcpu,
-                      int protection, memory_t address, int length, u8 *buffer)
+                      int protection, unsigned long address, int length, u8 
*buffer)
 {
     vcpu_guest_context_t *vcpu_ctxt = &ctxt->context[vcpu];
     unsigned long pde, page;
@@ -407,7 +407,7 @@
 /* divide a memory operation into accesses to individual pages */
 static int
 xendebug_memory_op (domain_context_p ctxt, int xc_handle, u32 vcpu,
-                    int protection, memory_t address, int length, u8 *buffer)
+                    int protection, unsigned long address, int length, u8 
*buffer)
 {
     int      remain;              /* number of bytes to touch past this page */
     int      bytes   = 0;
@@ -431,7 +431,7 @@
 xendebug_read_memory(int xc_handle,
                      u32 domid,
                      u32 vcpu,
-                     memory_t address,
+                     unsigned long address,
                      u32 length,
                      u8 *data)
 {
@@ -451,7 +451,7 @@
 xendebug_write_memory(int xc_handle,
                       u32 domid,
                       u32 vcpu,
-                      memory_t address,
+                      unsigned long address,
                       u32 length,
                       u8 *data)
 {
@@ -471,7 +471,7 @@
 xendebug_insert_memory_breakpoint(int xc_handle,
                                   u32 domid,
                                   u32 vcpu,
-                                  memory_t address,
+                                  unsigned long address,
                                   u32 length)
 {
     bwcpoint_p bkpt;
@@ -517,7 +517,7 @@
 xendebug_remove_memory_breakpoint(int xc_handle,
                                   u32 domid,
                                   u32 vcpu,
-                                  memory_t address,
+                                  unsigned long address,
                                   u32 length)
 {
     bwcpoint_p bkpt = NULL;
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/debugger/libxendebug/xendebug.h
--- a/tools/debugger/libxendebug/xendebug.h     Thu Aug 18 18:40:02 2005
+++ b/tools/debugger/libxendebug/xendebug.h     Fri Aug 19 18:19:28 2005
@@ -45,7 +45,7 @@
 int xendebug_read_memory(int xc_handle,
                         u32 domid,
                         u32 vcpu,
-                        memory_t address,
+                        unsigned long address,
                         u32 length,
                         u8 *data);
 
@@ -53,7 +53,7 @@
 int xendebug_write_memory(int xc_handle,
                          u32 domid,
                          u32 vcpu,
-                         memory_t address,
+                         unsigned long address,
                          u32 length,
                          u8 *data);
 
@@ -61,13 +61,13 @@
 int xendebug_insert_memory_breakpoint(int xc_handle,
                                      u32 domid,
                                      u32 vcpu,
-                                     memory_t address,
+                                     unsigned long address,
                                      u32 length);
 
 int xendebug_remove_memory_breakpoint(int xc_handle,
                                      u32 domid,
                                      u32 vcpu,
-                                     memory_t address,
+                                     unsigned long address,
                                      u32 length);
 
 int xendebug_query_domain_stop(int xc_handle,
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/debugger/pdb/linux-2.6-module/debug.c
--- a/tools/debugger/pdb/linux-2.6-module/debug.c       Thu Aug 18 18:40:02 2005
+++ b/tools/debugger/pdb/linux-2.6-module/debug.c       Fri Aug 19 18:19:28 2005
@@ -26,7 +26,7 @@
 typedef struct bwcpoint                           /* break/watch/catch point */
 {
     struct list_head list;
-    memory_t address;
+    unsigned long address;
     int length;
 
     u8  type;                                                     /* BWC_??? */
@@ -109,7 +109,7 @@
 }
 
 bwcpoint_p
-pdb_search_watchpoint (u32 process, memory_t address)
+pdb_search_watchpoint (u32 process, unsigned long address)
 {
     bwcpoint_p bwc_watch = (bwcpoint_p) 0;
     bwcpoint_p bwc_entry = (bwcpoint_p) 0;
@@ -364,7 +364,7 @@
 
 int
 pdb_insert_memory_breakpoint (struct task_struct *target, 
-                              memory_t address, u32 length)
+                              unsigned long address, u32 length)
 {
     int rc = 0;
     bwcpoint_p bkpt;
@@ -399,7 +399,7 @@
 
 int
 pdb_remove_memory_breakpoint (struct task_struct *target,
-                              memory_t address, u32 length)
+                              unsigned long address, u32 length)
 {
     int rc = 0;
     bwcpoint_p bkpt = NULL;
@@ -760,7 +760,7 @@
 {
     pdb_response_t resp;
     bwcpoint_p bkpt = NULL;
-    memory_t address = regs->eip - 1;
+    unsigned long address = regs->eip - 1;
 
     struct list_head *entry;
     list_for_each(entry, &bwcpoint_list)
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/debugger/pdb/linux-2.6-module/module.c
--- a/tools/debugger/pdb/linux-2.6-module/module.c      Thu Aug 18 18:40:02 2005
+++ b/tools/debugger/pdb/linux-2.6-module/module.c      Fri Aug 19 18:19:28 2005
@@ -199,7 +199,7 @@
 }
 
 static void
-pdb_send_connection_status(int status, memory_t ring)
+pdb_send_connection_status(int status, unsigned long ring)
 {
     ctrl_msg_t cmsg = 
     {
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/debugger/pdb/linux-2.6-module/pdb_debug.h
--- a/tools/debugger/pdb/linux-2.6-module/pdb_debug.h   Thu Aug 18 18:40:02 2005
+++ b/tools/debugger/pdb/linux-2.6-module/pdb_debug.h   Fri Aug 19 18:19:28 2005
@@ -18,9 +18,9 @@
 int pdb_step (struct task_struct *target);
 
 int pdb_insert_memory_breakpoint (struct task_struct *target, 
-                                  memory_t address, u32 length);
+                                  unsigned long address, u32 length);
 int pdb_remove_memory_breakpoint (struct task_struct *target,
-                                  memory_t address, u32 length);
+                                  unsigned long address, u32 length);
 int pdb_insert_watchpoint (struct task_struct *target,
                            pdb_op_watchpt_p watchpt);
 int pdb_remove_watchpoint (struct task_struct *target,
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/debugger/pdb/pdb_caml_domain.c
--- a/tools/debugger/pdb/pdb_caml_domain.c      Thu Aug 18 18:40:02 2005
+++ b/tools/debugger/pdb/pdb_caml_domain.c      Fri Aug 19 18:19:28 2005
@@ -203,7 +203,7 @@
     context_t ctx;
     int loop;
     char *buffer;
-    memory_t my_address = Int32_val(address);
+    unsigned long my_address = Int32_val(address);
     u32 my_length = Int_val(length);
 
     printf ("(pdb) read memory\n");
@@ -259,7 +259,7 @@
     context_t ctx;
 
     char buffer[4096];  /* a big buffer */
-    memory_t  my_address;
+    unsigned long  my_address;
     u32 length = 0;
 
     printf ("(pdb) write memory\n");
@@ -279,7 +279,7 @@
     }
     buffer[length++] = Int_val(Field(node, 0));
 
-    my_address = (memory_t) Int32_val(address);
+    my_address = (unsigned long) Int32_val(address);
 
     if ( xendebug_write_memory(xc_handle, ctx.domain, ctx.vcpu,
                                my_address, length, buffer) )
@@ -344,7 +344,7 @@
     CAMLparam3(context, address, length);
 
     context_t ctx;
-    memory_t my_address = (memory_t) Int32_val(address);
+    unsigned long my_address = (unsigned long) Int32_val(address);
     int my_length = Int_val(length);
 
     decode_context(&ctx, context);
@@ -373,7 +373,7 @@
 
     context_t ctx;
 
-    memory_t my_address = (memory_t) Int32_val(address);
+    unsigned long my_address = (unsigned long) Int32_val(address);
     int my_length = Int_val(length);
 
     printf ("(pdb) remove memory breakpoint 0x%lx %d\n",
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/debugger/pdb/pdb_caml_process.c
--- a/tools/debugger/pdb/pdb_caml_process.c     Thu Aug 18 18:40:02 2005
+++ b/tools/debugger/pdb/pdb_caml_process.c     Fri Aug 19 18:19:28 2005
@@ -495,7 +495,7 @@
 
     req.operation = PDB_OPCODE_SET_BKPT;
     req.process = ctx.process;
-    req.u.bkpt.address = (memory_t) Int32_val(address);
+    req.u.bkpt.address = (unsigned long) Int32_val(address);
     req.u.bkpt.length  =  Int_val(length);
 
     send_request(ctx.ring, ctx.evtchn, &req);
@@ -518,7 +518,7 @@
 
     req.operation = PDB_OPCODE_CLR_BKPT;
     req.process = ctx.process;
-    req.u.bkpt.address = (memory_t) Int32_val(address);
+    req.u.bkpt.address = (unsigned long) Int32_val(address);
     req.u.bkpt.length  =  Int_val(length);
 
     send_request(ctx.ring, ctx.evtchn, &req);
@@ -542,7 +542,7 @@
     req.operation = PDB_OPCODE_SET_WATCHPT;
     req.process = ctx.process;
     req.u.watchpt.type    =  Int_val(kind);
-    req.u.watchpt.address = (memory_t) Int32_val(address);
+    req.u.watchpt.address = (unsigned long) Int32_val(address);
     req.u.watchpt.length  =  Int_val(length);
 
     send_request(ctx.ring, ctx.evtchn, &req);
@@ -566,7 +566,7 @@
     req.operation = PDB_OPCODE_CLR_WATCHPT;
     req.process = ctx.process;
     req.u.watchpt.type    =  Int_val(kind);
-    req.u.watchpt.address = (memory_t) Int32_val(address);
+    req.u.watchpt.address = (unsigned long) Int32_val(address);
     req.u.watchpt.length  =  Int_val(length);
 
     send_request(ctx.ring, ctx.evtchn, &req);
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/debugger/pdb/pdb_caml_xcs.c
--- a/tools/debugger/pdb/pdb_caml_xcs.c Thu Aug 18 18:40:02 2005
+++ b/tools/debugger/pdb/pdb_caml_xcs.c Fri Aug 19 18:19:28 2005
@@ -50,7 +50,7 @@
 {
     CAMLparam2(domain, ring);
     int my_domain = Int_val(domain);
-    memory_t my_ring = Int32_val(ring);
+    unsigned long my_ring = Int32_val(ring);
 
     pdb_front_ring_t *front_ring;
     pdb_sring_t *sring;
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/libxc/xc.h
--- a/tools/libxc/xc.h  Thu Aug 18 18:40:02 2005
+++ b/tools/libxc/xc.h  Fri Aug 19 18:19:28 2005
@@ -515,25 +515,25 @@
  */
 int xc_grant_interface_close(int xc_handle);
 
-int xc_gnttab_map_grant_ref(int         xc_handle,
-                            memory_t    host_virt_addr,
-                            u32         dom,
-                            u16         ref,
-                            u16         flags,
-                            s16        *handle,
-                            memory_t   *dev_bus_addr);
-
-int xc_gnttab_unmap_grant_ref(int       xc_handle,
-                              memory_t  host_virt_addr,
-                              memory_t  dev_bus_addr,
-                              u16       handle,
-                              s16      *status);
+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,
-                          memory_t **frame_list);
+                          unsigned long **frame_list);
 
 /* Grant debug builds only: */
 int xc_gnttab_dump_table(int        xc_handle,
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/libxc/xc_gnttab.c
--- a/tools/libxc/xc_gnttab.c   Thu Aug 18 18:40:02 2005
+++ b/tools/libxc/xc_gnttab.c   Fri Aug 19 18:19:28 2005
@@ -40,12 +40,12 @@
 
 
 int xc_gnttab_map_grant_ref(int         xc_handle,
-                            memory_t    host_virt_addr,
+                            u64    host_virt_addr,
                             u32         dom,
                             u16         ref,
                             u16         flags,
                             s16        *handle,
-                            memory_t   *dev_bus_addr)
+                            u64   *dev_bus_addr)
 {
     struct gnttab_map_grant_ref op;
     int rc;
@@ -67,8 +67,8 @@
 
 
 int xc_gnttab_unmap_grant_ref(int       xc_handle,
-                              memory_t  host_virt_addr,
-                              memory_t  dev_bus_addr,
+                              u64  host_virt_addr,
+                              u64  dev_bus_addr,
                               u16       handle,
                               s16      *status)
 {
@@ -92,7 +92,7 @@
                           u32        dom,
                           u16        nr_frames,
                           s16       *status,
-                          memory_t **frame_list)
+                          unsigned long **frame_list)
 {
     struct gnttab_setup_table op;
     int rc, i;
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/python/xen/lowlevel/xu/xu.c
--- a/tools/python/xen/lowlevel/xu/xu.c Thu Aug 18 18:40:02 2005
+++ b/tools/python/xen/lowlevel/xu/xu.c Fri Aug 19 18:19:28 2005
@@ -844,7 +844,7 @@
     case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT):
         P2C(blkif_be_connect_t, domid,        u32);
         P2C(blkif_be_connect_t, blkif_handle, u32);
-        P2C(blkif_be_connect_t, shmem_frame,  memory_t);
+        P2C(blkif_be_connect_t, shmem_frame,  unsigned long);
         P2C(blkif_be_connect_t, shmem_ref,    u32);
         P2C(blkif_be_connect_t, evtchn,       u16);
         break;
@@ -906,9 +906,9 @@
     case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CONNECT):
         P2C(netif_be_connect_t, domid,          u32);
         P2C(netif_be_connect_t, netif_handle,   u32);
-        P2C(netif_be_connect_t, tx_shmem_frame, memory_t);
+        P2C(netif_be_connect_t, tx_shmem_frame, unsigned long);
         P2C(netif_be_connect_t, tx_shmem_ref,   u32); 
-        P2C(netif_be_connect_t, rx_shmem_frame, memory_t);
+        P2C(netif_be_connect_t, rx_shmem_frame, unsigned long);
         P2C(netif_be_connect_t, rx_shmem_ref,   u32); 
         P2C(netif_be_connect_t, evtchn,         u16); 
         break;
@@ -942,7 +942,7 @@
         P2C(usbif_fe_driver_status_changed_t, status, u32);
         break;
     case TYPE(CMSG_USBIF_FE, CMSG_USBIF_FE_INTERFACE_CONNECT):
-        P2C(usbif_fe_interface_connect_t, shmem_frame, memory_t);
+        P2C(usbif_fe_interface_connect_t, shmem_frame, unsigned long);
         break;
     case TYPE(CMSG_USBIF_FE, CMSG_USBIF_FE_INTERFACE_DISCONNECT):
         break;
@@ -956,7 +956,7 @@
         break;
     case TYPE(CMSG_USBIF_BE, CMSG_USBIF_BE_CONNECT):
         P2C(usbif_be_connect_t, domid, domid_t);
-        P2C(usbif_be_connect_t, shmem_frame, memory_t);
+        P2C(usbif_be_connect_t, shmem_frame, unsigned long);
         P2C(usbif_be_connect_t, evtchn, u32);
         P2C(usbif_be_connect_t, bandwidth, u32);
         P2C(usbif_be_connect_t, status, u32);
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Thu Aug 18 18:40:02 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Fri Aug 19 18:19:28 2005
@@ -36,8 +36,10 @@
 from xen.xend.server import SrvDaemon; xend = SrvDaemon.instance()
 from xen.xend.server import messages
 from xen.xend.server.channel import EventChannel, channelFactory
+from xen.util.blkif import blkdev_name_to_number, expand_dev_name
 
 from xen.xend import sxp
+from xen.xend import Blkctl
 from xen.xend.PrettyPrint import prettyprintstring
 from xen.xend.XendBootloader import bootloader
 from xen.xend.XendLogging import log
@@ -380,6 +382,39 @@
         return ctrl
 
     def createDevice(self, type, devconfig, change=False):
+        if type == 'vbd':
+
+            backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0'))
+
+            devnum = blkdev_name_to_number(sxp.child_value(devconfig, 'dev'))
+
+            # 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))
+            
+            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'))
+
+            backdb['frontend'] = db.getPath()
+            (type, params) = string.split(sxp.child_value(devconfig, 'uname'), 
':', 1)
+            node = Blkctl.block('bind', type, params)
+            backdb['frontend-id'] = "%i" % self.id
+            backdb['physical-device'] = "%li" % blkdev_name_to_number(node)
+            backdb.saveDB(save=True)
+
+            # Ok, super gross, this really doesn't belong in the frontend db...
+            db['type'] = type
+            db['node'] = node
+            db['params'] = params
+            db.saveDB(save=True)
+            
+            return
         ctrl = self.findDeviceController(type)
         return ctrl.createDevice(devconfig, recreate=self.recreate,
                                  change=change)
@@ -671,6 +706,16 @@
         for ctrl in self.getDeviceControllers():
             if ctrl.isDestroyed(): continue
             ctrl.destroyController(reboot=reboot)
+        ddb = self.db.addChild("/device")
+        for type in ddb.keys():
+            if type == 'vbd':
+                typedb = ddb.addChild(type)
+                for dev in typedb.keys():
+                    devdb = typedb.addChild(str(dev))
+                    Blkctl.block('unbind', devdb['type'].getData(),
+                                 devdb['node'].getData())
+                    typedb[dev].delete()
+                typedb.saveDB(save=True)
 
     def show(self):
         """Print virtual machine info.
@@ -926,6 +971,7 @@
         at creation time, for example when it uses NFS root.
 
         """
+        return
         blkif = self.getDeviceController("vbd", error=False)
         if not blkif:
             blkif = self.createDeviceController("vbd")
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/python/xen/xend/server/event.py
--- a/tools/python/xen/xend/server/event.py     Thu Aug 18 18:40:02 2005
+++ b/tools/python/xen/xend/server/event.py     Fri Aug 19 18:19:28 2005
@@ -50,7 +50,7 @@
     def dataReceived(self, data):
         try:
             self.parser.input(data)
-            if self.parser.ready():
+            while(self.parser.ready()):
                 val = self.parser.get_val()
                 res = self.dispatch(val)
                 self.send_result(res)
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/python/xen/xend/server/relocate.py
--- a/tools/python/xen/xend/server/relocate.py  Thu Aug 18 18:40:02 2005
+++ b/tools/python/xen/xend/server/relocate.py  Fri Aug 19 18:19:28 2005
@@ -42,7 +42,7 @@
     def dataReceived(self, data):
         try:
             self.parser.input(data)
-            if self.parser.ready():
+            while(self.parser.ready()):
                 val = self.parser.get_val()
                 res = self.dispatch(val)
                 self.send_result(res)
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/security/Makefile
--- a/tools/security/Makefile   Thu Aug 18 18:40:02 2005
+++ b/tools/security/Makefile   Fri Aug 19 18:19:28 2005
@@ -2,27 +2,71 @@
 include $(XEN_ROOT)/tools/Rules.mk
 
 SRCS     = secpol_tool.c
-CFLAGS   += -static
 CFLAGS   += -Wall
 CFLAGS   += -Werror
 CFLAGS   += -O3
 CFLAGS   += -fno-strict-aliasing
-CFLAGS   += -I.
+CFLAGS   += -I. -I/usr/include/libxml2
+CFLAGS_XML2BIN += $(shell xml2-config --cflags --libs )
+#if above does not work, try  -L/usr/lib -lxml2 -lz -lpthread -lm
+XML2VERSION = $(shell xml2-config --version )
+VALIDATE_SCHEMA=$(shell if [[ $(XML2VERSION) < 2.6.20 ]]; then echo ""; else 
echo "-DVALIDATE_SCHEMA"; fi; )
 
+ifeq ($(ACM_USE_SECURITY_POLICY),ACM_NULL_POLICY)
+POLICY=null
+endif
+ifeq ($(ACM_USE_SECURITY_POLICY),ACM_CHINESE_WALL_POLICY)
+POLICY=chwall
+endif
+ifeq ($(ACM_USE_SECURITY_POLICY),ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
+POLICY=ste
+endif
+ifeq 
($(ACM_USE_SECURITY_POLICY),ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY)
+POLICY=chwall_ste
+endif
+POLICYFILE=./policies/$(POLICY)/$(POLICY).bin
+
+ifneq ($(ACM_USE_SECURITY_POLICY), ACM_NULL_POLICY)
 all: build
+
+install:all
+
+default:all
+else
+all:
+
+install:
+
+default:
+endif
+
 build: mk-symlinks
        $(MAKE) secpol_tool
+       $(MAKE) secpol_xml2bin
+       chmod 700 ./setlabel.sh
+       chmod 700 ./updategrub.sh
 
-default: all
-
-install: all
-
-secpol_tool : secpol_tool.c
+secpol_tool : secpol_tool.c secpol_compat.h
        $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
 
+secpol_xml2bin : secpol_xml2bin.c secpol_xml2bin.h secpol_compat.h
+       $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_XML2BIN) $(VALIDATE_SCHEMA) -o $@ 
$<
+
 clean:
-       rm -rf secpol_tool xen
+       rm -rf secpol_tool secpol_xml2bin xen
 
+policy_clean:
+       rm -rf policies/*/*.bin policies/*/*.map
+
+mrproper: clean policy_clean
+
+
+$(POLICYFILE) : build
+       @./secpol_xml2bin $(POLICY) > /dev/null
+
+boot_install: $(POLICYFILE)
+       @cp $(POLICYFILE) /boot
+       @./updategrub.sh $(POLICY) $(PWD)/$(XEN_ROOT)
 
 LINUX_ROOT := $(XEN_ROOT)/linux-2.6-xen-sparse
 mk-symlinks:
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/security/secpol_tool.c
--- a/tools/security/secpol_tool.c      Thu Aug 18 18:40:02 2005
+++ b/tools/security/secpol_tool.c      Fri Aug 19 18:19:28 2005
@@ -31,18 +31,8 @@
 #include <stdlib.h>
 #include <sys/ioctl.h>
 #include <string.h>
-#include <stdint.h>
 #include <netinet/in.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 "secpol_compat.h"
 #include <xen/acm.h>
 #include <xen/acm_ops.h>
 #include <xen/linux/privcmd.h>
@@ -270,171 +260,6 @@
     }
 }
 
-/*************************** set policy ****************************/
-
-int acm_domain_set_chwallpolicy(void *bufstart, int buflen)
-{
-#define CWALL_MAX_SSIDREFS             6
-#define CWALL_MAX_TYPES             10
-#define CWALL_MAX_CONFLICTSETS         2
-
-    struct acm_chwall_policy_buffer *chwall_bin_pol =
-        (struct acm_chwall_policy_buffer *) bufstart;
-    domaintype_t *ssidrefs, *conflicts;
-    int ret = 0;
-    int j;
-
-    chwall_bin_pol->chwall_max_types = htonl(CWALL_MAX_TYPES);
-    chwall_bin_pol->chwall_max_ssidrefs = htonl(CWALL_MAX_SSIDREFS);
-    chwall_bin_pol->policy_code = htonl(ACM_CHINESE_WALL_POLICY);
-    chwall_bin_pol->policy_version = htonl(ACM_CHWALL_VERSION);
-    chwall_bin_pol->chwall_ssid_offset =
-        htonl(sizeof(struct acm_chwall_policy_buffer));
-    chwall_bin_pol->chwall_max_conflictsets =
-        htonl(CWALL_MAX_CONFLICTSETS);
-    chwall_bin_pol->chwall_conflict_sets_offset =
-        htonl(ntohl(chwall_bin_pol->chwall_ssid_offset) +
-              sizeof(domaintype_t) * CWALL_MAX_SSIDREFS * CWALL_MAX_TYPES);
-    chwall_bin_pol->chwall_running_types_offset = 0;    /* not set */
-    chwall_bin_pol->chwall_conflict_aggregate_offset = 0;       /* not set */
-    ret += sizeof(struct acm_chwall_policy_buffer);
-    /* now push example ssids into the buffer (max_ssidrefs x max_types 
entries) */
-    /* check buffer size */
-    if ((buflen - ret) <
-        (CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t)))
-        return -1;              /* not enough space */
-
-    ssidrefs = (domaintype_t *) (bufstart +
-                          ntohl(chwall_bin_pol->chwall_ssid_offset));
-    memset(ssidrefs, 0,
-           CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t));
-
-    /* now set type j-1 for ssidref i+1 */
-    for (j = 0; j <= CWALL_MAX_SSIDREFS; j++)
-        if ((0 < j) && (j <= CWALL_MAX_TYPES))
-            ssidrefs[j * CWALL_MAX_TYPES + j - 1] = htons(1);
-
-    ret += CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t);
-    if ((buflen - ret) <
-        (CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES * sizeof(domaintype_t)))
-        return -1;              /* not enough space */
-
-    /* now the chinese wall policy conflict sets */
-    conflicts = (domaintype_t *) (bufstart +
-                                  ntohl(chwall_bin_pol->
-                                        chwall_conflict_sets_offset));
-    memset((void *) conflicts, 0,
-           CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES *
-           sizeof(domaintype_t));
-    /* just 1 conflict set [0]={2,3}, [1]={1,5,6} */
-    if (CWALL_MAX_TYPES > 3)
-    {
-        conflicts[2] = htons(1);
-        conflicts[3] = htons(1);        /* {2,3} */
-        conflicts[CWALL_MAX_TYPES + 1] = htons(1);
-        conflicts[CWALL_MAX_TYPES + 5] = htons(1);
-        conflicts[CWALL_MAX_TYPES + 6] = htons(1);      /* {0,5,6} */
-    }
-    ret += sizeof(domaintype_t) * CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES;
-    return ret;
-}
-
-int acm_domain_set_stepolicy(void *bufstart, int buflen)
-{
-#define STE_MAX_SSIDREFS        6
-#define STE_MAX_TYPES                  5
-
-    struct acm_ste_policy_buffer *ste_bin_pol =
-        (struct acm_ste_policy_buffer *) bufstart;
-    domaintype_t *ssidrefs;
-    int j, ret = 0;
-
-    ste_bin_pol->ste_max_types = htonl(STE_MAX_TYPES);
-    ste_bin_pol->ste_max_ssidrefs = htonl(STE_MAX_SSIDREFS);
-    ste_bin_pol->policy_code = htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
-    ste_bin_pol->policy_version = htonl(ACM_STE_VERSION);
-    ste_bin_pol->ste_ssid_offset =
-        htonl(sizeof(struct acm_ste_policy_buffer));
-    ret += sizeof(struct acm_ste_policy_buffer);
-    /* check buffer size */
-    if ((buflen - ret) <
-        (STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t)))
-        return -1;              /* not enough space */
-
-    ssidrefs =
-        (domaintype_t *) (bufstart + ntohl(ste_bin_pol->ste_ssid_offset));
-    memset(ssidrefs, 0,
-           STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t));
-    /* all types 1 for ssidref 1 */
-    for (j = 0; j < STE_MAX_TYPES; j++)
-        ssidrefs[1 * STE_MAX_TYPES + j] = htons(1);
-    /* now set type j-1 for ssidref j */
-    for (j = 0; j < STE_MAX_SSIDREFS; j++)
-        if ((0 < j) && (j <= STE_MAX_TYPES))
-            ssidrefs[j * STE_MAX_TYPES + j - 1] = htons(1);
-    ret += STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t);
-    return ret;
-}
-
-#define MAX_PUSH_BUFFER        16384
-u8 push_buffer[MAX_PUSH_BUFFER];
-
-int acm_domain_setpolicy(int xc_handle)
-{
-    int ret;
-    struct acm_policy_buffer *bin_pol;
-    acm_op_t op;
-
-    /* future: read policy from file and set it */
-    bin_pol = (struct acm_policy_buffer *) push_buffer;
-    bin_pol->policy_version = htonl(ACM_POLICY_VERSION);
-    bin_pol->magic = htonl(ACM_MAGIC);
-    bin_pol->primary_policy_code = htonl(ACM_CHINESE_WALL_POLICY);
-    bin_pol->secondary_policy_code =
-        htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
-
-    bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
-    bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len));
-    ret =
-        acm_domain_set_chwallpolicy(push_buffer +
-                                    ntohl(bin_pol->primary_buffer_offset),
-                                    MAX_PUSH_BUFFER -
-                                    ntohl(bin_pol->primary_buffer_offset));
-    if (ret < 0)
-    {
-        printf("ERROR creating chwallpolicy buffer.\n");
-        return -1;
-    }
-    bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
-    bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
-    ret = acm_domain_set_stepolicy(push_buffer +
-                                 ntohl(bin_pol->secondary_buffer_offset),
-                                 MAX_PUSH_BUFFER -
-                                 ntohl(bin_pol->secondary_buffer_offset));
-    if (ret < 0)
-    {
-        printf("ERROR creating chwallpolicy buffer.\n");
-        return -1;
-    }
-    bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
-
-    /* dump it and then push it down into xen/acm */
-    acm_dump_policy_buffer(push_buffer, ntohl(bin_pol->len));
-
-    op.cmd = ACM_SETPOLICY;
-    op.interface_version = ACM_INTERFACE_VERSION;
-    op.u.setpolicy.pushcache = (void *) push_buffer;
-    op.u.setpolicy.pushcache_size = ntohl(bin_pol->len);
-    ret = do_acm_op(xc_handle, &op);
-
-    if (ret)
-        printf("ERROR setting policy. Use 'xm dmesg' to see details.\n");
-    else
-        printf("Successfully changed policy.\n");
-
-    return ret;
-}
-
 /******************************* get policy ******************************/
 
 #define PULL_CACHE_SIZE                8192
@@ -602,7 +427,6 @@
 void usage(char *progname)
 {
     printf("Use: %s \n"
-           "\t setpolicy\n"
            "\t getpolicy\n"
            "\t dumpstats\n"
            "\t loadpolicy <binary policy file>\n", progname);
@@ -623,12 +447,7 @@
         exit(-1);
     }
 
-    if (!strcmp(argv[1], "setpolicy"))
-    {
-        if (argc != 2)
-            usage(argv[0]);
-        ret = acm_domain_setpolicy(acm_cmd_fd);
-    } else if (!strcmp(argv[1], "getpolicy")) {
+    if (!strcmp(argv[1], "getpolicy")) {
         if (argc != 2)
             usage(argv[0]);
         ret = acm_domain_getpolicy(acm_cmd_fd);
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/xentrace/xentrace.c
--- a/tools/xentrace/xentrace.c Thu Aug 18 18:40:02 2005
+++ b/tools/xentrace/xentrace.c Fri Aug 19 18:19:28 2005
@@ -95,13 +95,13 @@
 
 /**
  * get_tbufs - get pointer to and size of the trace buffers
- * @mach_addr: location to store machine address if the trace buffers to
- * @size:      location to store the size of a trace buffer to
+ * @mfn:  location to store mfn of the trace buffers to
+ * @size: location to store the size of a trace buffer to
  *
  * Gets the machine address of the trace pointer area and the size of the
  * per CPU buffers.
  */
-void get_tbufs(unsigned long *mach_addr, unsigned long *size)
+void get_tbufs(unsigned long *mfn, unsigned long *size)
 {
     int ret;
     dom0_op_t op;                        /* dom0 op we'll build             */
@@ -121,19 +121,19 @@
         exit(EXIT_FAILURE);
     }
 
-    *mach_addr = op.u.tbufcontrol.mach_addr;
-    *size      = op.u.tbufcontrol.size;
+    *mfn  = op.u.tbufcontrol.buffer_mfn;
+    *size = op.u.tbufcontrol.size;
 }
 
 /**
  * map_tbufs - memory map Xen trace buffers into user space
- * @tbufs:     machine address of the trace buffers
+ * @tbufs_mfn: mfn of the trace buffers
  * @num:       number of trace buffers to map
  * @size:      size of each trace buffer
  *
  * Maps the Xen trace buffers them into process address space.
  */
-struct t_buf *map_tbufs(unsigned long tbufs_mach, unsigned int num,
+struct t_buf *map_tbufs(unsigned long tbufs_mfn, unsigned int num,
                         unsigned long size)
 {
     int xc_handle;                  /* file descriptor for /proc/xen/privcmd */
@@ -149,7 +149,7 @@
 
     tbufs_mapped = xc_map_foreign_range(xc_handle, 0 /* Dom 0 ID */,
                                         size * num, PROT_READ,
-                                        tbufs_mach >> PAGE_SHIFT);
+                                        tbufs_mfn);
 
     xc_interface_close(xc_handle);
 
@@ -231,7 +231,7 @@
 
 /**
  * init_rec_ptrs - initialises data area pointers to locations in user space
- * @tbufs_mach:    machine base address of the trace buffer area
+ * @tbufs_mfn:     base mfn of the trace buffer area
  * @tbufs_mapped:  user virtual address of base of trace buffer area
  * @meta:          array of user-space pointers to struct t_buf's of metadata
  * @num:           number of trace buffers
@@ -240,7 +240,7 @@
  * mapped in user space.  Note that the trace buffer metadata contains machine
  * pointers - the array returned allows more convenient access to them.
  */
-struct t_rec **init_rec_ptrs(unsigned long tbufs_mach,
+struct t_rec **init_rec_ptrs(unsigned long tbufs_mfn,
                              struct t_buf *tbufs_mapped,
                              struct t_buf **meta,
                              unsigned int num)
@@ -256,7 +256,7 @@
     }
 
     for ( i = 0; i < num; i++ )
-        data[i] = (struct t_rec *)(meta[i]->rec_addr - tbufs_mach
+        data[i] = (struct t_rec *)(meta[i]->rec_addr - 
(tbufs_mfn<<XC_PAGE_SHIFT) /* XXX */
                                    + (unsigned long)tbufs_mapped);
 
     return data;
@@ -330,7 +330,7 @@
     struct t_rec **data;         /* pointers to the trace buffer data areas
                                   * where they are mapped into user space.   */
     unsigned long *cons;         /* store tail indexes for the trace buffers */
-    unsigned long tbufs_mach;    /* machine address of the tbufs             */
+    unsigned long tbufs_mfn;     /* mfn of the tbufs                         */
     unsigned int  num;           /* number of trace buffers / logical CPUS   */
     unsigned long size;          /* size of a single trace buffer            */
 
@@ -340,14 +340,14 @@
     num = get_num_cpus();
 
     /* setup access to trace buffers */
-    get_tbufs(&tbufs_mach, &size);
-    tbufs_mapped = map_tbufs(tbufs_mach, num, size);
+    get_tbufs(&tbufs_mfn, &size);
+    tbufs_mapped = map_tbufs(tbufs_mfn, num, size);
 
     size_in_recs = (size - sizeof(struct t_buf)) / sizeof(struct t_rec);
 
     /* build arrays of convenience ptrs */
     meta  = init_bufs_ptrs (tbufs_mapped, num, size);
-    data  = init_rec_ptrs  (tbufs_mach, tbufs_mapped, meta, num);
+    data  = init_rec_ptrs  (tbufs_mfn, tbufs_mapped, meta, num);
     cons  = init_tail_idxs (meta, num);
 
     /* now, scan buffers for events */
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/Rules.mk
--- a/xen/Rules.mk      Thu Aug 18 18:40:02 2005
+++ b/xen/Rules.mk      Fri Aug 19 18:19:28 2005
@@ -10,14 +10,6 @@
 optimize    ?= y
 domu_debug  ?= n
 crash_debug ?= n
-
-# ACM_USE_SECURITY_POLICY is set to security policy of Xen
-# Supported models are:
-#      ACM_NULL_POLICY (ACM will not be built with this policy)
-#      ACM_CHINESE_WALL_POLICY
-#      ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY
-#      ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY
-ACM_USE_SECURITY_POLICY ?= ACM_NULL_POLICY
 
 include $(BASEDIR)/../Config.mk
 
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Thu Aug 18 18:40:02 2005
+++ b/xen/arch/x86/domain.c     Fri Aug 19 18:19:28 2005
@@ -217,8 +217,16 @@
     return xmalloc(struct vcpu);
 }
 
+/* We assume that vcpu 0 is always the last one to be freed in a
+   domain i.e. if v->vcpu_id == 0, the domain should be
+   single-processor. */
 void arch_free_vcpu_struct(struct vcpu *v)
 {
+    struct vcpu *p;
+    for_each_vcpu(v->domain, p) {
+        if (p->next_in_list == v)
+            p->next_in_list = v->next_in_list;
+    }
     xfree(v);
 }
 
@@ -403,7 +411,7 @@
     {
         if ( ((c->user_regs.cs & 3) == 0) ||
              ((c->user_regs.ss & 3) == 0) )
-                return -EINVAL;
+            return -EINVAL;
     }
 
     clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
@@ -457,7 +465,7 @@
         if ( !(c->flags & VGCF_VMX_GUEST) )
 #endif
             if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d, 
-                  PGT_base_page_table) )
+                                    PGT_base_page_table) )
                 return -EINVAL;
     }
 
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Thu Aug 18 18:40:02 2005
+++ b/xen/arch/x86/domain_build.c       Fri Aug 19 18:19:28 2005
@@ -22,16 +22,28 @@
 #include <asm/i387.h>
 #include <asm/shadow.h>
 
-/* opt_dom0_mem: memory allocated to domain 0. */
-static unsigned int opt_dom0_mem;
+static long dom0_nrpages;
+
+/*
+ * dom0_mem:
+ *  If +ve:
+ *   * The specified amount of memory is allocated to domain 0.
+ *  If -ve:
+ *   * All of memory is allocated to domain 0, minus the specified amount.
+ *  If not specified: 
+ *   * All of memory is allocated to domain 0, minus 1/16th which is reserved
+ *     for uses such as DMA buffers (the reservation is clamped to 128MB).
+ */
 static void parse_dom0_mem(char *s)
 {
-    unsigned long long bytes = parse_size_and_unit(s);
-    /* If no unit is specified we default to kB units, not bytes. */
-    if ( isdigit(s[strlen(s)-1]) )
-        opt_dom0_mem = (unsigned int)bytes;
-    else
-        opt_dom0_mem = (unsigned int)(bytes >> 10);
+    unsigned long long bytes;
+    char *t = s;
+    if ( *s == '-' )
+        t++;
+    bytes = parse_size_and_unit(t);
+    dom0_nrpages = bytes >> PAGE_SHIFT;
+    if ( *s == '-' )
+        dom0_nrpages = -dom0_nrpages;
 }
 custom_param("dom0_mem", parse_dom0_mem);
 
@@ -137,12 +149,30 @@
 
     printk("*** LOADING DOMAIN 0 ***\n");
 
-    /* By default DOM0 is allocated all available memory. */
     d->max_pages = ~0U;
-    if ( (nr_pages = opt_dom0_mem >> (PAGE_SHIFT - 10)) == 0 )
+
+    /*
+     * If domain 0 allocation isn't specified, reserve 1/16th of available
+     * memory for things like DMA buffers. This reservation is clamped to 
+     * a maximum of 128MB.
+     */
+    if ( dom0_nrpages == 0 )
+    {
+        dom0_nrpages = avail_domheap_pages() +
+            ((initrd_len + PAGE_SIZE - 1) >> PAGE_SHIFT) +
+            ((image_len  + PAGE_SIZE - 1) >> PAGE_SHIFT);
+        dom0_nrpages = min(dom0_nrpages / 16, 128L << (20 - PAGE_SHIFT));
+        dom0_nrpages = -dom0_nrpages;
+    }
+
+    /* Negative memory specification means "all memory - specified amount". */
+    if ( dom0_nrpages < 0 )
         nr_pages = avail_domheap_pages() +
             ((initrd_len + PAGE_SIZE - 1) >> PAGE_SHIFT) +
-            ((image_len  + PAGE_SIZE - 1) >> PAGE_SHIFT);
+            ((image_len  + PAGE_SIZE - 1) >> PAGE_SHIFT) +
+            dom0_nrpages;
+    else
+        nr_pages = dom0_nrpages;
 
     if ( (rc = parseelfimage(&dsi)) != 0 )
         return rc;
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Thu Aug 18 18:40:02 2005
+++ b/xen/arch/x86/mm.c Fri Aug 19 18:19:28 2005
@@ -2633,14 +2633,16 @@
 
     if ( entries > FIRST_RESERVED_GDT_ENTRY )
         return -EINVAL;
-    
+
     shadow_sync_all(d);
 
     /* Check the pages in the new GDT. */
-    for ( i = 0; i < nr_pages; i++ )
-        if ( ((pfn = frames[i]) >= max_page) ||
-             !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) )
+    for ( i = 0; i < nr_pages; i++ ) {
+        pfn = frames[i];
+        if ((pfn >= max_page) ||
+            !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) )
             goto fail;
+    }
 
     /* Tear down the old GDT. */
     destroy_gdt(v);
@@ -2687,22 +2689,24 @@
 }
 
 
-long do_update_descriptor(unsigned long pa, u64 desc)
+long do_update_descriptor(u64 pa, u64 desc)
 {
     struct domain *dom = current->domain;
     unsigned long gpfn = pa >> PAGE_SHIFT;
     unsigned long mfn;
-    unsigned int  offset = (pa & ~PAGE_MASK) / sizeof(struct desc_struct);
+    unsigned int  offset;
     struct desc_struct *gdt_pent, d;
     struct pfn_info *page;
     long ret = -EINVAL;
 
+    offset = ((unsigned int)pa & ~PAGE_MASK) / sizeof(struct desc_struct);
+
     *(u64 *)&d = desc;
 
     LOCK_BIGLOCK(dom);
 
     if ( !VALID_MFN(mfn = __gpfn_to_mfn(dom, gpfn)) ||
-         ((pa % sizeof(struct desc_struct)) != 0) ||
+         (((unsigned int)pa % sizeof(struct desc_struct)) != 0) ||
          (mfn >= max_page) ||
          !check_descriptor(&d) )
     {
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Thu Aug 18 18:40:02 2005
+++ b/xen/arch/x86/physdev.c    Fri Aug 19 18:19:28 2005
@@ -106,7 +106,7 @@
              (op.u.set_iobitmap.nr_ports > 65536) )
             break;
         ret = 0;
-        current->arch.iobmp       = (u8 *)op.u.set_iobitmap.bitmap;
+        current->arch.iobmp       = op.u.set_iobitmap.bitmap;
         current->arch.iobmp_limit = op.u.set_iobitmap.nr_ports;
         break;
     default:
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/common/event_channel.c
--- a/xen/common/event_channel.c        Thu Aug 18 18:40:02 2005
+++ b/xen/common/event_channel.c        Fri Aug 19 18:19:28 2005
@@ -588,7 +588,6 @@
     long           rc = 0;
 
     if ( (vcpu >= MAX_VIRT_CPUS) || (d->vcpu[vcpu] == NULL) ) {
-        printf("vcpu %d bad.\n", vcpu);
         return -EINVAL;
     }
 
@@ -596,7 +595,6 @@
 
     if ( !port_is_valid(d, port) )
     {
-        printf("port %d bad.\n", port);
         rc = -EINVAL;
         goto out;
     }
@@ -610,7 +608,6 @@
         chn->notify_vcpu_id = vcpu;
         break;
     default:
-        printf("evtchn type %d can't be rebound.\n", chn->state);
         rc = -EINVAL;
         break;
     }
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/common/lib.c
--- a/xen/common/lib.c  Thu Aug 18 18:40:02 2005
+++ b/xen/common/lib.c  Fri Aug 19 18:19:28 2005
@@ -450,8 +450,10 @@
                ret <<= 10;
        case 'M': case 'm':
                ret <<= 10;
-       case 'K': case 'k':
+       case 'K': case 'k': default:
                ret <<= 10;
+       case 'B': case 'b':
+               break;
        }
 
        return ret;
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/common/schedule.c
--- a/xen/common/schedule.c     Thu Aug 18 18:40:02 2005
+++ b/xen/common/schedule.c     Fri Aug 19 18:19:28 2005
@@ -38,6 +38,8 @@
 #include <xen/mm.h>
 #include <public/sched_ctl.h>
 
+extern void arch_getdomaininfo_ctxt(struct vcpu *,
+                                    struct vcpu_guest_context *);
 /* opt_sched: scheduler - default to SEDF */
 static char opt_sched[10] = "sedf";
 string_param("sched", opt_sched);
@@ -82,7 +84,8 @@
     int i;
 
     SCHED_OP(free_task, d);
-    for (i = 0; i < MAX_VIRT_CPUS; i++)
+    /* vcpu 0 has to be the last one destructed. */
+    for (i = MAX_VIRT_CPUS-1; i >= 0; i--)
         if ( d->vcpu[i] )
             arch_free_vcpu_struct(d->vcpu[i]);
 
@@ -295,10 +298,36 @@
     return 0;
 }
 
+static long do_vcpu_pickle(int vcpu, unsigned long arg)
+{
+    struct vcpu *v;
+    vcpu_guest_context_t *c;
+    int ret = 0;
+
+    if (vcpu >= MAX_VIRT_CPUS)
+        return -EINVAL;
+    v = current->domain->vcpu[vcpu];
+    if (!v)
+        return -ESRCH;
+    /* Don't pickle vcpus which are currently running */
+    if (!test_bit(_VCPUF_down, &v->vcpu_flags)) {
+        return -EBUSY;
+    }
+    c = xmalloc(vcpu_guest_context_t);
+    if (!c)
+        return -ENOMEM;
+    arch_getdomaininfo_ctxt(v, c);
+    if (copy_to_user((vcpu_guest_context_t *)arg,
+                     (const vcpu_guest_context_t *)c, sizeof(*c)))
+        ret = -EFAULT;
+    xfree(c);
+    return ret;
+}
+
 /*
  * Demultiplex scheduler-related hypercalls.
  */
-long do_sched_op(unsigned long op)
+long do_sched_op(unsigned long op, unsigned long arg)
 {
     long ret = 0;
 
@@ -332,6 +361,11 @@
     case SCHEDOP_vcpu_up:
     {
         ret = do_vcpu_up((int)(op >> SCHEDOP_vcpushift));
+        break;
+    }
+    case SCHEDOP_vcpu_pickle:
+    {
+        ret = do_vcpu_pickle((int)(op >> SCHEDOP_vcpushift), arg);
         break;
     }
 
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/common/trace.c
--- a/xen/common/trace.c        Thu Aug 18 18:40:02 2005
+++ b/xen/common/trace.c        Fri Aug 19 18:19:28 2005
@@ -113,10 +113,10 @@
     switch ( tbc->op)
     {
     case DOM0_TBUF_GET_INFO:
-        tbc->cpu_mask  = tb_cpu_mask;
-        tbc->evt_mask  = tb_event_mask;
-        tbc->mach_addr = __pa(t_bufs[0]);
-        tbc->size      = opt_tbuf_size * PAGE_SIZE;
+        tbc->cpu_mask   = tb_cpu_mask;
+        tbc->evt_mask   = tb_event_mask;
+        tbc->buffer_mfn = __pa(t_bufs[0]) >> PAGE_SHIFT;
+        tbc->size       = opt_tbuf_size * PAGE_SIZE;
         break;
     case DOM0_TBUF_SET_CPU_MASK:
         tb_cpu_mask = tbc->cpu_mask;
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h    Thu Aug 18 18:40:02 2005
+++ b/xen/include/public/arch-ia64.h    Fri Aug 19 18:19:28 2005
@@ -12,9 +12,6 @@
 #define MAX_VIRT_CPUS 1
 
 #ifndef __ASSEMBLY__
-
-/* NB. Both the following are 64 bits each. */
-typedef unsigned long memory_t;   /* Full-sized pointer/address/memory-size. */
 
 #define MAX_NR_SECTION  32  // at most 32 memory holes
 typedef struct {
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/include/public/arch-x86_32.h
--- a/xen/include/public/arch-x86_32.h  Thu Aug 18 18:40:02 2005
+++ b/xen/include/public/arch-x86_32.h  Fri Aug 19 18:19:28 2005
@@ -63,9 +63,6 @@
 
 #ifndef __ASSEMBLY__
 
-/* NB. Both the following are 32 bits each. */
-typedef unsigned long memory_t;   /* Full-sized pointer/address/memory-size. */
-
 /*
  * Send an array of these to HYPERVISOR_set_trap_table()
  */
@@ -74,10 +71,10 @@
 #define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl))
 #define TI_SET_IF(_ti,_if)   ((_ti)->flags |= ((!!(_if))<<2))
 typedef struct trap_info {
-    u8       vector;  /* exception vector                              */
-    u8       flags;   /* 0-3: privilege level; 4: clear event enable?  */
-    u16      cs;      /* code selector                                 */
-    memory_t address; /* code address                                  */
+    u8       vector;       /* exception vector                              */
+    u8       flags;        /* 0-3: privilege level; 4: clear event enable?  */
+    u16      cs;           /* code selector                                 */
+    unsigned long address; /* code offset                                   */
 } trap_info_t;
 
 typedef struct cpu_user_regs {
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/include/public/arch-x86_64.h
--- a/xen/include/public/arch-x86_64.h  Thu Aug 18 18:40:02 2005
+++ b/xen/include/public/arch-x86_64.h  Fri Aug 19 18:19:28 2005
@@ -103,9 +103,6 @@
     /* Bottom of switch_to_user stack frame. */
 };
 
-/* NB. Both the following are 64 bits each. */
-typedef unsigned long memory_t;   /* Full-sized pointer/address/memory-size. */
-
 /*
  * Send an array of these to HYPERVISOR_set_trap_table().
  * N.B. As in x86/32 mode, the privilege level specifies which modes may enter
@@ -121,10 +118,10 @@
 #define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl))
 #define TI_SET_IF(_ti,_if)   ((_ti)->flags |= ((!!(_if))<<2))
 typedef struct trap_info {
-    u8       vector;  /* exception vector                              */
-    u8       flags;   /* 0-3: privilege level; 4: clear event enable?  */
-    u16      cs;      /* code selector                                 */
-    memory_t address; /* code address                                  */
+    u8       vector;       /* exception vector                              */
+    u8       flags;        /* 0-3: privilege level; 4: clear event enable?  */
+    u16      cs;           /* code selector                                 */
+    unsigned long address; /* code offset                                   */
 } trap_info_t;
 
 typedef struct cpu_user_regs {
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h     Thu Aug 18 18:40:02 2005
+++ b/xen/include/public/dom0_ops.h     Fri Aug 19 18:19:28 2005
@@ -19,7 +19,7 @@
  * This makes sure that old versions of dom0 tools will stop working in a
  * well-defined way (rather than crashing the machine, for instance).
  */
-#define DOM0_INTERFACE_VERSION   0xAAAA100E
+#define DOM0_INTERFACE_VERSION   0xAAAA100F
 
 /************************************************************************/
 
@@ -27,10 +27,10 @@
 typedef struct {
     /* IN variables. */
     domid_t       domain;
-    memory_t      max_pfns;
+    unsigned long max_pfns;
     void         *buffer;
     /* OUT variables. */
-    memory_t      num_pfns;
+    unsigned long num_pfns;
 } dom0_getmemlist_t;
 
 #define DOM0_SCHEDCTL          6
@@ -83,9 +83,9 @@
 #define DOMFLAGS_SHUTDOWNMASK 255 /* DOMFLAGS_SHUTDOWN guest-supplied code.  */
 #define DOMFLAGS_SHUTDOWNSHIFT 16
     u32      flags;
-    memory_t tot_pages;
-    memory_t max_pages;
-    memory_t shared_info_frame;       /* MFN of shared_info struct */
+    unsigned long tot_pages;
+    unsigned long max_pages;
+    unsigned long shared_info_frame;       /* MFN of shared_info struct */
     u64      cpu_time;
     u32      n_vcpu;
     s32      vcpu_to_cpu[MAX_VIRT_CPUS];  /* current mapping   */
@@ -155,7 +155,7 @@
 
 typedef struct {
     /* IN variables. */
-    memory_t pfn;          /* Machine page frame number to query.       */
+    unsigned long pfn;     /* Machine page frame number to query.       */
     domid_t domain;        /* To which domain does the frame belong?    */
     /* OUT variables. */
     /* Is the page PINNED to a type? */
@@ -197,7 +197,7 @@
     unsigned long cpu_mask;
     u32           evt_mask;
     /* OUT variables */
-    memory_t mach_addr;
+    unsigned long buffer_mfn;
     u32      size;
 } dom0_tbufcontrol_t;
 
@@ -211,8 +211,8 @@
     u32      sockets_per_node;
     u32      nr_nodes;
     u32      cpu_khz;
-    memory_t total_pages;
-    memory_t free_pages;
+    unsigned long total_pages;
+    unsigned long free_pages;
 } dom0_physinfo_t;
 
 /*
@@ -252,7 +252,7 @@
     u32            op;
     unsigned long *dirty_bitmap; /* pointer to locked buffer */
     /* IN/OUT variables. */
-    memory_t       pages;        /* size of buffer, updated with actual size */
+    unsigned long  pages;        /* size of buffer, updated with actual size */
     /* OUT variables. */
     dom0_shadow_control_stats_t stats;
 } dom0_shadow_control_t;
@@ -260,15 +260,15 @@
 #define DOM0_SETDOMAINMAXMEM   28
 typedef struct {
     /* IN variables. */
-    domid_t     domain;
-    memory_t    max_memkb;
+    domid_t       domain;
+    unsigned long max_memkb;
 } dom0_setdomainmaxmem_t;
 
 #define DOM0_GETPAGEFRAMEINFO2 29   /* batched interface */
 typedef struct {
     /* IN variables. */
-    domid_t  domain;
-    memory_t num;
+    domid_t        domain;
+    unsigned long  num;
     /* IN/OUT variables. */
     unsigned long *array;
 } dom0_getpageframeinfo2_t;
@@ -283,12 +283,12 @@
 #define DOM0_ADD_MEMTYPE         31
 typedef struct {
     /* IN variables. */
-    memory_t pfn;
-    memory_t nr_pfns;
-    u32      type;
-    /* OUT variables. */
-    u32      handle;
-    u32      reg;
+    unsigned long pfn;
+    unsigned long nr_pfns;
+    u32           type;
+    /* OUT variables. */
+    u32           handle;
+    u32           reg;
 } dom0_add_memtype_t;
 
 /*
@@ -311,8 +311,8 @@
     /* IN variables. */
     u32      reg;
     /* OUT variables. */
-    memory_t pfn;
-    memory_t nr_pfns;
+    unsigned long pfn;
+    unsigned long nr_pfns;
     u32      type;
 } dom0_read_memtype_t;
 
@@ -361,10 +361,10 @@
 typedef struct {
     /* IN variables. */
     domid_t               first_domain;
-    memory_t              max_domains;
+    unsigned int          max_domains;
     dom0_getdomaininfo_t *buffer;
     /* OUT variables. */
-    memory_t              num_domains;
+    unsigned int          num_domains;
 } dom0_getdomaininfolist_t;
 
 #define DOM0_PLATFORM_QUIRK      39  
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h  Thu Aug 18 18:40:02 2005
+++ b/xen/include/public/grant_table.h  Fri Aug 19 18:19:28 2005
@@ -153,13 +153,13 @@
 #define GNTTABOP_map_grant_ref        0
 typedef struct gnttab_map_grant_ref {
     /* IN parameters. */
-    memory_t    host_addr;
+    u64         host_addr;
     domid_t     dom;
     grant_ref_t ref;
     u16         flags;                /* GNTMAP_* */
     /* OUT parameters. */
     s16         handle;               /* +ve: handle; -ve: GNTST_* */
-    memory_t    dev_bus_addr;
+    u64         dev_bus_addr;
 } gnttab_map_grant_ref_t;
 
 /*
@@ -176,8 +176,8 @@
 #define GNTTABOP_unmap_grant_ref      1
 typedef struct gnttab_unmap_grant_ref {
     /* IN parameters. */
-    memory_t    host_addr;
-    memory_t    dev_bus_addr;
+    u64         host_addr;
+    u64         dev_bus_addr;
     u16         handle;
     /* OUT parameters. */
     s16         status;               /* GNTST_* */
@@ -223,7 +223,7 @@
  */
 #define GNTTABOP_donate                4
 typedef struct {
-    memory_t    mfn;                 /*  0 */
+    unsigned long mfn;               /*  0 */
     domid_t     domid;               /*  4 */
     u16         handle;               /*  8 */
     s16         status;               /*  10: GNTST_* */
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/include/public/io/blkif.h
--- a/xen/include/public/io/blkif.h     Thu Aug 18 18:40:02 2005
+++ b/xen/include/public/io/blkif.h     Fri Aug 19 18:19:28 2005
@@ -18,7 +18,6 @@
 
 #define BLKIF_OP_READ      0
 #define BLKIF_OP_WRITE     1
-#define BLKIF_OP_PROBE     2
 
 /* NB. Ring size must be small enough for sizeof(blkif_ring_t) <= PAGE_SIZE. */
 #define BLKIF_RING_SIZE        64
@@ -33,7 +32,7 @@
 typedef struct blkif_request {
     u8             operation;    /* BLKIF_OP_???                         */
     u8             nr_segments;  /* number of segments                   */
-    blkif_vdev_t   device;       /* only for read/write requests         */
+    blkif_vdev_t   handle;       /* only for read/write requests         */
     unsigned long  id;           /* private guest value, echoed in resp  */
     blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
     /* @f_a_s[4:0]=last_sect ; @f_a_s[9:5]=first_sect                        */
@@ -71,31 +70,8 @@
 
 DEFINE_RING_TYPES(blkif, blkif_request_t, blkif_response_t);
 
-/*
- * BLKIF_OP_PROBE:
- * The request format for a probe request is constrained as follows:
- *  @operation   == BLKIF_OP_PROBE
- *  @nr_segments == size of probe buffer in pages
- *  @device      == unused (zero)
- *  @id          == any value (echoed in response message)
- *  @sector_num  == unused (zero)
- *  @frame_and_sects == list of page-sized buffers.
- *                       (i.e., @first_sect == 0, @last_sect == 7).
- * 
- * The response is a list of vdisk_t elements copied into the out-of-band
- * probe buffer. On success the response status field contains the number
- * of vdisk_t elements.
- */
-
 #define VDISK_CDROM        0x1
 #define VDISK_REMOVABLE    0x2
 #define VDISK_READONLY     0x4
 
-typedef struct vdisk {
-    blkif_sector_t capacity;     /* Size in terms of 512-byte sectors.   */
-    blkif_vdev_t   device;       /* Device number (opaque 16 bit value). */
-    u16            info;         /* Device type and flags (VDISK_*).     */
-    u16            sector_size;  /* Minimum alignment for requests.      */
-} vdisk_t; /* 16 bytes */
-
 #endif /* __XEN_PUBLIC_IO_BLKIF_H__ */
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/include/public/io/domain_controller.h
--- a/xen/include/public/io/domain_controller.h Thu Aug 18 18:40:02 2005
+++ b/xen/include/public/io/domain_controller.h Fri Aug 19 18:19:28 2005
@@ -139,7 +139,7 @@
  */
 typedef struct blkif_fe_interface_connect {
     u32      handle;
-    memory_t shmem_frame;
+    unsigned long shmem_frame;
     int      shmem_ref;
 } blkif_fe_interface_connect_t;
 
@@ -249,7 +249,7 @@
     /* IN */
     domid_t    domid;         /* Domain attached to new interface.   */
     u32        blkif_handle;  /* Domain-specific interface handle.   */
-    memory_t   shmem_frame;   /* Page cont. shared comms window.     */
+    unsigned long shmem_frame;/* Page cont. shared comms window.     */
     int        shmem_ref;     /* Grant table reference.              */
     u32        evtchn;        /* Event channel for notifications.    */
     /* OUT */
@@ -364,11 +364,11 @@
  *  STATUS_CONNECTED message.
  */
 typedef struct netif_fe_interface_connect {
-    u32        handle;
-    memory_t   tx_shmem_frame; 
-    int        tx_shmem_ref;
-    memory_t   rx_shmem_frame;
-    int        rx_shmem_ref;
+    u32           handle;
+    unsigned long tx_shmem_frame; 
+    int           tx_shmem_ref;
+    unsigned long rx_shmem_frame;
+    int           rx_shmem_ref;
 } netif_fe_interface_connect_t;
 
 /*
@@ -486,13 +486,13 @@
  */
 typedef struct netif_be_connect { 
     /* IN */
-    domid_t    domid;          /* Domain attached to new interface.   */
-    u32        netif_handle;   /* Domain-specific interface handle.   */
-    memory_t   tx_shmem_frame; /* Page cont. tx shared comms window.  */
-    int        tx_shmem_ref;   /* Grant reference for above           */
-    memory_t   rx_shmem_frame; /* Page cont. rx shared comms window.  */
-    int        rx_shmem_ref;   /* Grant reference for above           */
-    u16        evtchn;         /* Event channel for notifications.    */
+    domid_t    domid;            /* Domain attached to new interface.   */
+    u32        netif_handle;     /* Domain-specific interface handle.   */
+    unsigned long tx_shmem_frame;/* Page cont. tx shared comms window.  */
+    int        tx_shmem_ref;     /* Grant reference for above           */
+    unsigned long rx_shmem_frame;/* Page cont. rx shared comms window.  */
+    int        rx_shmem_ref;     /* Grant reference for above           */
+    u16        evtchn;           /* Event channel for notifications.    */
     /* OUT */
     u32        status;
 } netif_be_connect_t;
@@ -577,7 +577,7 @@
  *  STATUS_CONNECTED message.
  */
 typedef struct usbif_fe_interface_connect {
-    memory_t shmem_frame;
+    unsigned long shmem_frame;
 } usbif_fe_interface_connect_t;
 
 /*
@@ -660,7 +660,7 @@
 typedef struct usbif_be_connect { 
     /* IN */
     domid_t    domid;         /* Domain attached to new interface.   */
-    memory_t   shmem_frame;   /* Page cont. shared comms window.     */
+    unsigned long shmem_frame;/* Page cont. shared comms window.     */
     u32        evtchn;        /* Event channel for notifications.    */
     u32        bandwidth;     /* Bandwidth allocated for isoch / int - us
                                * per 1ms frame (ie between 0 and 900 or 800
@@ -780,7 +780,7 @@
 #define PDB_CONNECTION_STATUS_UP   1
 #define PDB_CONNECTION_STATUS_DOWN 2
     u32      status;
-    memory_t ring;       /* status: UP */
+    unsigned long ring;  /* status: UP */
     u32      evtchn;     /* status: UP */
 } pdb_connection_t, *pdb_connection_p;
 
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/include/public/io/netif.h
--- a/xen/include/public/io/netif.h     Thu Aug 18 18:40:02 2005
+++ b/xen/include/public/io/netif.h     Fri Aug 19 18:19:28 2005
@@ -10,7 +10,7 @@
 #define __XEN_PUBLIC_IO_NETIF_H__
 
 typedef struct netif_tx_request {
-    memory_t addr;   /* Machine address of packet.  */
+    unsigned long addr;   /* Machine address of packet.  */
     u16      csum_blank:1; /* Proto csum field blank?   */
     u16      id:15;  /* Echoed in response message. */
     u16      size;   /* Packet size in bytes.       */
@@ -32,7 +32,7 @@
 #ifdef CONFIG_XEN_NETDEV_GRANT_TX
     u32      addr;   /*  0: Offset in page of start of received packet  */
 #else
-    memory_t addr;   /* Machine address of packet.              */
+    unsigned long addr; /* Machine address of packet.              */
 #endif
     u16      csum_valid:1; /* Protocol checksum is validated?       */
     u16      id:15;
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/include/public/physdev.h
--- a/xen/include/public/physdev.h      Thu Aug 18 18:40:02 2005
+++ b/xen/include/public/physdev.h      Fri Aug 19 18:19:28 2005
@@ -27,8 +27,8 @@
 
 typedef struct physdevop_set_iobitmap {
     /* IN */
-    memory_t bitmap;
-    u32      nr_ports;
+    char *bitmap;
+    u32   nr_ports;
 } physdevop_set_iobitmap_t;
 
 typedef struct physdevop_apic {
diff -r 99914b54f7bf -r 81576d3d1ca8 xen/include/public/xen.h
--- a/xen/include/public/xen.h  Thu Aug 18 18:40:02 2005
+++ b/xen/include/public/xen.h  Fri Aug 19 18:19:28 2005
@@ -171,9 +171,9 @@
     unsigned int cmd;
     union {
         /* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR, REASSIGN_PAGE */
-        memory_t mfn;
+        unsigned long mfn;
         /* INVLPG_LOCAL, INVLPG_ALL, SET_LDT */
-        memory_t linear_addr;
+        unsigned long linear_addr;
     };
     union {
         /* SET_LDT */
@@ -203,6 +203,7 @@
 #define SCHEDOP_shutdown        2   /* Stop executing this domain.        */
 #define SCHEDOP_vcpu_down       3   /* make target VCPU not-runnable.     */
 #define SCHEDOP_vcpu_up         4   /* make target VCPU runnable.         */
+#define SCHEDOP_vcpu_pickle     5   /* save a vcpu's context to memory.   */
 #define SCHEDOP_cmdmask       255   /* 8-bit command. */
 #define SCHEDOP_reasonshift     8   /* 8-bit reason code. (SCHEDOP_shutdown) */
 #define SCHEDOP_vcpushift       8   /* 8-bit VCPU target. (SCHEDOP_up|down) */
@@ -437,18 +438,18 @@
 #define MAX_GUEST_CMDLINE 1024
 typedef struct start_info {
     /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME.    */
-    memory_t nr_pages;        /* Total pages allocated to this domain.    */
-    memory_t shared_info;     /* MACHINE address of shared info struct.   */
+    unsigned long nr_pages;   /* Total pages allocated to this domain.    */
+    unsigned long shared_info;/* MACHINE address of shared info struct.   */
     u32      flags;           /* SIF_xxx flags.                           */
     u16      domain_controller_evtchn;
     /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME).     */
-    memory_t pt_base;         /* VIRTUAL address of page directory.       */
-    memory_t nr_pt_frames;    /* Number of bootstrap p.t. frames.         */
-    memory_t mfn_list;        /* VIRTUAL address of page-frame list.      */
-    memory_t mod_start;       /* VIRTUAL address of pre-loaded module.    */
-    memory_t mod_len;         /* Size (bytes) of pre-loaded module.       */
+    unsigned long pt_base;    /* VIRTUAL address of page directory.       */
+    unsigned long nr_pt_frames;/* Number of bootstrap p.t. frames.        */
+    unsigned long mfn_list;   /* VIRTUAL address of page-frame list.      */
+    unsigned long mod_start;  /* VIRTUAL address of pre-loaded module.    */
+    unsigned long mod_len;    /* Size (bytes) of pre-loaded module.       */
     s8 cmd_line[MAX_GUEST_CMDLINE];
-    memory_t store_mfn;       /* MACHINE page number of shared page.      */
+    unsigned long store_mfn;  /* MACHINE page number of shared page.      */
     u16      store_evtchn;    /* Event channel for store communication.   */
 } start_info_t;
 
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/arch/xen/i386/kernel/init_task.c
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/init_task.c     Fri Aug 19 
18:19:28 2005
@@ -0,0 +1,49 @@
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/init_task.h>
+#include <linux/fs.h>
+#include <linux/mqueue.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/desc.h>
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+
+#define swapper_pg_dir ((pgd_t *)NULL)
+struct mm_struct init_mm = INIT_MM(init_mm);
+#undef swapper_pg_dir
+
+EXPORT_SYMBOL(init_mm);
+
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is THREAD_SIZE aligned due to the
+ * way process stacks are handled. This is done by having a special
+ * "init_task" linker map entry..
+ */
+union thread_union init_thread_union 
+       __attribute__((__section__(".data.init_task"))) =
+               { INIT_THREAD_INFO(init_task) };
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
+
+EXPORT_SYMBOL(init_task);
+
+/*
+ * per-CPU TSS segments. Threads are completely 'soft' on Linux,
+ * no more per-task TSS's.
+ */ 
+DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_maxaligned_in_smp = 
INIT_TSS;
+
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Aug 19 18:19:28 2005
@@ -0,0 +1,308 @@
+/*  Xenbus code for blkif 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 */
+       blkif_t *blkif;
+       struct vbd *vbd;
+
+       long int frontend_id;
+       long int pdev;
+       long int readonly;
+
+       /* watch back end for changes */
+       struct xenbus_watch backend_watch;
+
+       /* watch front end for changes */
+       struct xenbus_watch watch;
+       char *frontpath;
+};
+
+static int blkback_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->vbd)
+               vbd_free(be->blkif, be->vbd);
+       if (be->blkif)
+               blkif_put(be->blkif);
+       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 sharedmfn;
+       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, "")) {
+               xenbus_rm(be->dev->nodename, "");
+               device_unregister(&be->dev->dev);
+               return;
+       }
+       if (vbd_is_active(be->vbd))
+               return;
+
+#ifndef CONFIG_XEN_BLKDEV_GRANT
+       err = xenbus_gather(be->frontpath, "shared-frame", "%lu", &sharedmfn,
+                           "event-channel", "%u", &evtchn, NULL);
+       if (err) {
+               xenbus_dev_error(be->dev, err, 
+                                "reading %s/shared-frame and event-channel",
+                                be->frontpath);
+               return;
+       }
+#else
+       err = xenbus_gather(be->frontpath, "grant-id", "%lu", &sharedmfn,
+                           "event-channel", "%u", &evtchn, NULL);
+       if (err) {
+               xenbus_dev_error(be->dev, err, 
+                                "reading %s/grant-id and event-channel",
+                                be->frontpath);
+               return;
+       }
+#endif
+
+       /* Domains must use same shared frame for all vbds. */
+       if (be->blkif->status == CONNECTED &&
+           (evtchn != be->blkif->remote_evtchn ||
+            sharedmfn != be->blkif->shmem_frame)) {
+               xenbus_dev_error(be->dev, err,
+                                "Shared frame/evtchn %li/%u not same as"
+                                " old %li/%u",
+                                sharedmfn, evtchn,
+                                be->blkif->shmem_frame,
+                                be->blkif->remote_evtchn);
+               return;
+       }
+
+       /* Supply the information about the device the frontend needs */
+       err = xenbus_transaction_start(be->dev->nodename);
+       if (err) {
+               xenbus_dev_error(be->dev, err, "starting transaction");
+               return;
+       }
+
+       err = xenbus_printf(be->dev->nodename, "sectors", "%lu",
+                           vbd_size(be->vbd));
+       if (err) {
+               xenbus_dev_error(be->dev, err, "writing %s/sectors",
+                                be->dev->nodename);
+               goto abort;
+       }
+
+       /* FIXME: use a typename instead */
+       err = xenbus_printf(be->dev->nodename, "info", "%u",
+                           vbd_info(be->vbd));
+       if (err) {
+               xenbus_dev_error(be->dev, err, "writing %s/info",
+                                be->dev->nodename);
+               goto abort;
+       }
+       err = xenbus_printf(be->dev->nodename, "sector-size", "%lu",
+                           vbd_secsize(be->vbd));
+       if (err) {
+               xenbus_dev_error(be->dev, err, "writing %s/sector-size",
+                                be->dev->nodename);
+               goto abort;
+       }
+
+       /* First vbd?  We need to map the shared frame, irq etc. */
+       if (be->blkif->status != CONNECTED) {
+               err = blkif_map(be->blkif, sharedmfn, evtchn);
+               if (err) {
+                       xenbus_dev_error(be->dev, err,
+                                        "mapping shared-frame %lu port %u",
+                                        sharedmfn, evtchn);
+                       goto abort;
+               }
+       }
+
+       /* We're ready, activate. */
+       vbd_activate(be->blkif, be->vbd);
+
+       xenbus_transaction_end(0);
+       xenbus_dev_ok(be->dev);
+
+       return;
+
+abort:
+       xenbus_transaction_end(1);
+}
+
+/* 
+   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;
+       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;
+
+       frontend = NULL;
+       err = xenbus_gather(dev->nodename,
+                           "frontend-id", "%li", &be->frontend_id,
+                           "frontend", NULL, &frontend,
+                           NULL);
+       if (err == -ENOENT || err == -ERANGE ||
+           strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
+               if (frontend)
+                       kfree(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 (!be->frontpath || strcmp(frontend, be->frontpath)) {
+               if (be->watch.node)
+                       unregister_xenbus_watch(&be->watch);
+               if (be->frontpath)
+                       kfree(be->frontpath);
+               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;
+                       goto device_fail;
+               }
+       } else
+               kfree(frontend);
+
+       err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev);
+       if (err == -ENOENT || err == -ERANGE)
+               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 = blkif_find(be->frontend_id);
+               if (IS_ERR(be->blkif)) {
+                       err = PTR_ERR(be->blkif);
+                       be->blkif = NULL;
+                       goto device_fail;
+               }
+
+               be->vbd = vbd_create(be->blkif, handle, be->pdev,
+                                    be->readonly);
+               if (IS_ERR(be->vbd)) {
+                       err = PTR_ERR(be->vbd);
+                       be->vbd = NULL;
+                       goto device_fail;
+               }
+
+               frontend_changed(&be->watch, be->frontpath);
+       }
+
+       return;
+
+ device_fail:
+       device_unregister(&be->dev->dev);
+ out:
+       return;
+}
+
+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)
+               return -ENOMEM;
+
+       memset(be, 0, sizeof(*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)
+               goto free_be;
+
+       dev->data = be;
+
+       backend_changed(&be->backend_watch, dev->nodename);
+       return err;
+ free_be:
+       kfree(be);
+       return err;
+}
+
+static struct xenbus_device_id blkback_ids[] = {
+       { "vbd" },
+       { "" }
+};
+
+static struct xenbus_driver blkback = {
+       .name = "vbd",
+       .owner = THIS_MODULE,
+       .ids = blkback_ids,
+       .probe = blkback_probe,
+       .remove = blkback_remove,
+};
+
+void blkif_xenbus_init(void)
+{
+       xenbus_register_backend(&blkback);
+}
diff -r 99914b54f7bf -r 81576d3d1ca8 
patches/linux-2.6.12/workaround_double_br_del_if.patch
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/patches/linux-2.6.12/workaround_double_br_del_if.patch    Fri Aug 19 
18:19:28 2005
@@ -0,0 +1,11 @@
+--- 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 99914b54f7bf -r 81576d3d1ca8 tools/security/example.txt
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/example.txt        Fri Aug 19 18:19:28 2005
@@ -0,0 +1,269 @@
+##
+# example.txt <description to the xen access control architecture>
+#
+# Author:
+# Reiner Sailer 08/15/2005 <sailer@xxxxxxxxxxxxxx>
+#
+#
+# This file introduces into the tools to manage policies
+# and to label domains and resources.
+##
+
+We will show how to install and use the chwall_ste policy.
+Other policies work similarly. Feedback welcome!
+
+
+
+1. Using secpol_xml2bin to translate the chwall_ste policy:
+===========================================================
+
+#tools/security/secpol_xml2bin chwall_ste
+
+Successful execution should print:
+
+    [root@laptopxn security]# ./secpol_xml2bin chwall_ste
+    Validating label file 
policies/chwall_ste/chwall_ste-security_label_template.xml...
+    XML Schema policies/security_policy.xsd valid.
+    Validating policy file 
policies/chwall_ste/chwall_ste-security_policy.xml...
+    XML Schema policies/security_policy.xsd valid.
+    Creating ssid mappings ...
+    Creating label mappings ...
+    Max chwall labels:  7
+    Max chwall-types:   4
+    Max chwall-ssids:   5
+    Max ste labels:     14
+    Max ste-types:      6
+    Max ste-ssids:      10
+
+The tool looks in directory policies/chwall_ste for
+the label and policy files.
+
+The default policy directory structure under tools/security looks like:
+
+policies
+|-- security_policy.xsd
+|-- chwall
+|   |-- chwall-security_label_template.xml
+|   `-- chwall-security_policy.xml
+|-- chwall_ste
+|   |-- chwall_ste-security_label_template.xml
+|   `-- chwall_ste-security_policy.xml
+|-- null
+|   |-- null-security_label_template.xml
+|   `-- null-security_policy.xml
+`-- ste
+    |-- ste-security_label_template.xml
+    `-- ste-security_policy.xml
+
+policies/security_policy.xsd contains the schema against which both the
+label-template and the policy files must validate during translation.
+
+policies/chwall_ste/chwall_ste-security_policy.xml defines the
+policies and the types known to the policies.
+
+policies/chwall_ste/chwall_ste-security_label_template.xml contains
+label definitions that group chwall and ste types together and make
+them easier to use for users
+
+After executing the above secpol_xml2bin command, you will find 2 new
+files in the policies/chwall_ste sub-directory:
+
+policies/chwall_ste/chwall_ste.map ... this file includes the mapping
+of names from the xml files into their binary code representation.
+
+policies/chwall_ste/chwall_ste.bin ... this is the binary policy file,
+the result of parsing the xml files and using the mapping to extract a
+binary version that can be loaded into the hypervisor.
+
+
+
+2. Loading and activating the policy:
+=====================================
+
+We assume that xen is already configured to use the chwall_ste policy;
+please refer to install.txt for instructions.
+
+To activate the policy from the command line (assuming that the
+currently established policy is the minimal boot-policy that is
+hard-coded into the hypervisor:
+
+# ./secpol_tool loadpolicy policies/chwall_ste/chwall_ste.bin
+
+To activate the policy at next reboot:
+
+# cp policies/chwall_ste/chwall_ste.bin /boot
+
+Add a module line to your /boot/grub/grub.conf Xen entry.
+My boot entry with chwall_ste enabled looks like this:
+
+    title Xen (2.6.12)
+        root (hd0,5)
+        kernel /boot/xen.gz dom0_mem=1200000 console=vga
+        module /boot/vmlinuz-2.6.12-xen0 ro root=/dev/hda6 rhgb
+        module /boot/initrd-2.6.12-xen0.img
+        module /boot/chwall_ste.bin
+
+This tells the grub boot-loader to load the binary policy, which
+the hypervisor will recognize. The hypervisor will then establish
+this binary policy during boot instead of the minimal policy that
+is hardcoded as default.
+
+If you have any trouble here, maks sure you have the access control
+framework enabled (see: install.txt).
+
+
+
+3. Labeling domains:
+====================
+
+a) Labeling Domain0:
+
+The chwall_ste-security_label_template.xml file includes an attribute
+"bootstrap", which is set to the label name that will be assigned to
+Dom0 (this label will be mapped to ssidref 1/1, the default for Dom0).
+
+b) Labeling User Domains:
+
+Use the script tools/security/setlabel.sh to choose a label and to
+assign labels to user domains.
+
+To show available labels for the chwall_ste policy:
+
+#tools/security/setlabel.sh -l
+
+lists all available labels. For the default chwall_ste it should print
+the following:
+
+    [root@laptopxn security]# ./setlabel.sh -l chwall_ste
+    The following labels are available:
+    dom_SystemManagement
+    dom_HomeBanking
+    dom_Fun
+    dom_BoincClient
+    dom_StorageDomain
+    dom_NetworkDomain
+
+You need to have compiled the policy beforehand so that a .map file
+exists. Setlabel.sh uses the mapping file created throughout the
+policy translation to translate a user-friendly label string into a
+ssidref-number that is eventually used by the Xen hypervisor.
+
+We distinguish two kinds of labels: a) VM labels (for domains) and RES
+Labels (for resources). We are currently working on support for
+resource labeling but will focus here on VM labels.
+
+Setlabel.sh only prints VM labels (which we have prefixed with "dom_")
+since only those are used at this time.
+
+If you would like to assign the dom_HomeBanking label to one of your
+user domains (which you hopefully keep clean), look at an example
+domain configuration homebanking.xm:
+
+    #------HOMEBANKING---------
+    kernel = "/boot/vmlinuz-2.6.12-xenU"
+    ramdisk="/boot/U1_ramdisk.img"
+    memory = 65
+    name = "test34"
+    cpu = -1   # leave to Xen to pick
+    # Number of network interfaces. Default is 1.
+    nics=1
+    dhcp="dhcp"
+    #-------------------------
+
+Now we label this domain
+
+[root@laptopxn security]# ./setlabel.sh homebanking.xm dom_HomeBanking 
chwall_ste
+Mapped label 'dom_HomeBanking' to ssidref '0x00020002'.
+
+The domain configuration my look now like:
+
+    [root@laptopxn security]# cat homebanking.xm
+    #------HOMEBANKING---------
+    kernel = "/boot/vmlinuz-2.6.12-xenU"
+    ramdisk="/boot/U1_ramdisk.img"
+    memory = 65
+    name = "test34"
+    cpu = -1   # leave to Xen to pick
+    # Number of network interfaces. Default is 1.
+    nics=1
+    dhcp="dhcp"
+    #-------------------------
+    #ACM_POLICY=chwall_ste-security_policy.xml
+    #ACM_LABEL=dom_HomeBanking
+    ssidref = 0x00020002
+
+You can see 3 new entries, two of which are comments.  The only value
+that the hypervisor cares about is the ssidref that will reference
+those types assigned to this label. You can look them up in the
+xml label-template file for the chwall_ste policy.
+
+This script will eventually move into the domain management and will
+be called when the domain is instantiated. For now, the setlabel
+script must be run on domains whenever the policy files change since
+the mapping between label names and ssidrefs can change in this case.
+
+
+4. Starting a labeled domain
+============================
+
+Now, start the domain:
+    #xm create -c homebanking.xm
+
+
+If you label another domain configuration as dom_Fun and try to start
+it afterwards, its start will fail. Why?
+
+Because the running homebanking domain has the chinese wall type
+"cw_Sensitive". The new domain dom_Fun has the chinese wall label
+"cw_Distrusted". This domain is not allowed to run simultaneously
+because of the defined conflict set
+
+                       <conflictset name="Protection1">
+                               <type>cw_Sensitive</type>
+                               <type>cw_Distrusted</type>
+                       </conflictset>
+
+(in policies/chwall_ste/chwall_ste-security_policy.xml), which says
+that only one of the types cw_sensitive and cw_Distrusted can run at a
+time.
+
+If you save or shutdown the HomeBanking domain, you will be able to
+start the "Fun" domain. You can look into the Xen log to see if a
+domain was denied to start because of the access control framework
+with the command 'xm dmesg'.
+
+It is important (and usually non-trivial) to define the labels in a
+way that the semantics of the labels are enforced and supported by the
+types and the conflict sets.
+
+Note: While the chinese wall policy enforcement is complete, the type
+enforcement is currently enforced in the Xen hypervisor
+only. Therefore, only point-to-point sharing with regard to the type
+enforcement is currently controlled. We are working on enhancements to
+Dom0 that enforce types also for network traffic that is routed
+through Dom0 and on the enforcement of resource labeling when binding
+resources to domains (e.g., enforcing types between domains and
+hardware resources, such as disk partitions).
+
+
+4. Adding your own policies
+===========================
+
+Writing your own policy (e.g. "mypolicy") requires the following:
+
+a) the policy definition (types etc.) file
+b) the label template definition (labels etc.) file
+
+If your policy name is "mypolicy", you need to create a
+subdirectory mypolicy in tools/security/policies.
+
+Then you create
+tools/security/policies/mypolicy/mypolicy-security_policy.xml and
+tools/security/policies/mypolicy/mypolicy-security_label_template.xml.
+
+You need to keep to the schema as defined in
+tools/security/security_policy.xsd since the translation tool
+secpol_xml2bin is written against this schema.
+
+If you keep to the security policy schema, then you can use all the
+tools described above. Refer to install.txt to install it.
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/security/install.txt
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/install.txt        Fri Aug 19 18:19:28 2005
@@ -0,0 +1,67 @@
+##
+# install.txt <description to the xen access control architecture>
+#
+# Author:
+# Reiner Sailer 08/15/2005 <sailer@xxxxxxxxxxxxxx>
+#
+#
+# This file shows how to activate and install the access control
+# framework.
+##
+
+
+INSTALLING A SECURITY POLICY IN XEN
+===================================
+
+By default, the access control architecture is disabled in Xen. To
+enable the access control architecture in Xen follow the steps below.
+This description assumes that you want to install the Chinese Wall and
+Simple Type Enforcement policy. Some file names need to be replaced
+below to activate the Chinese Wall OR the Type Enforcement policy
+exclusively (chwall_ste --> {chwall, ste}).
+
+1. enable access control in Xen
+       # cd "xen_root"
+       # edit/xemacs/vi Config.mk
+
+       change the line:
+       ACM_USE_SECURITY_POLICY ?= ACM_NULL_POLICY
+
+       to:
+       ACM_USE_SECURITY_POLICY ?= 
ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY
+
+       # make all
+       # ./install.sh
+
+2. compile the policy from xml to a binary format that can be loaded
+   into the hypervisor for enforcement
+       # cd tools/security
+       # make
+
+       manual steps (alternative to make boot_install):
+       #./secpol_xml2bin chwall_ste
+       #cp policies/chwall_ste/chwall_ste.bin /boot
+       #edit /boot/grub/grub.conf
+        add the follwoing line to your xen boot entry:
+       "module chwall_ste.bin"
+
+       alternatively, you can try our automatic translation and
+       installation of the policy:
+       # make boot_install
+
+       [we try hard to do the right thing to the right boot entry but
+        please verify boot entry in /boot/grub/grub.conf afterwards;
+        your xen boot entry should have an additional module line
+        specifying a chwall_ste.bin file with the correct directory
+        (e.g. "/" or "/boot").]
+
+
+3. reboot into the newly compiled hypervisor
+
+        after boot
+       #xm dmesg should show an entry about the policy being loaded
+            during the boot process
+
+        #tools/security/secpol_tool getpolicy
+            should print the new chwall_ste binary policy representation
+
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/security/policies/chwall/chwall-security_label_template.xml
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/policies/chwall/chwall-security_label_template.xml Fri Aug 
19 18:19:28 2005
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com  -->
+<!--              This file defines the security labels, which can  -->
+<!--              be attached to Domains and resources. Based on    -->
+<!--              these labels, the access control module decides   -->
+<!--              about sharing between Domains and about access    -->
+<!--              of Domains to real resources.                     -->
+
+<SecurityLabelTemplate
+ xmlns="http://www.ibm.com";
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+ xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
+   <LabelHeader>
+      <Name>chwall-security_label_template</Name>
+      <Date>2005-08-10</Date>
+      <PolicyName>
+         <Url>chwall-security_policy.xml</Url>
+         <Reference>abcdef123456abcdef</Reference>
+      </PolicyName>
+   </LabelHeader>
+
+   <SubjectLabels bootstrap="dom_SystemManagement">
+      <!-- single ste typed domains            -->
+      <!-- ACM enforces that only domains with -->
+      <!-- the same type can share information -->
+      <!--                                     -->
+      <!-- Bootstrap label is assigned to Dom0 -->
+      <VirtualMachineLabel>
+       <Name>dom_HomeBanking</Name>
+         <ChineseWallTypes>
+            <Type>cw_Sensitive</Type>
+         </ChineseWallTypes>
+      </VirtualMachineLabel>
+
+      <VirtualMachineLabel>
+       <Name>dom_Fun</Name>
+         <ChineseWallTypes>
+            <Type>cw_Distrusted</Type>
+         </ChineseWallTypes>
+      </VirtualMachineLabel>
+
+      <VirtualMachineLabel>
+        <!-- donating some cycles to seti@home -->
+       <Name>dom_BoincClient</Name>
+         <ChineseWallTypes>
+            <Type>cw_Isolated</Type>
+         </ChineseWallTypes>
+      </VirtualMachineLabel>
+
+      <!-- Domains with multiple ste types services; such domains   -->
+      <!-- must keep the types inside their domain safely confined. -->
+      <VirtualMachineLabel>
+       <Name>dom_SystemManagement</Name>
+         <ChineseWallTypes>
+            <Type>cw_SystemManagement</Type>
+         </ChineseWallTypes>
+      </VirtualMachineLabel>
+
+      <VirtualMachineLabel>
+        <!-- serves persistent storage to other domains -->
+       <Name>dom_StorageDomain</Name>
+         <ChineseWallTypes>
+            <Type>cw_SystemManagement</Type>
+         </ChineseWallTypes>
+      </VirtualMachineLabel>
+
+      <VirtualMachineLabel>
+        <!-- serves network access to other domains -->
+       <Name>dom_NetworkDomain</Name>
+         <ChineseWallTypes>
+            <Type>cw_SystemManagement</Type>
+         </ChineseWallTypes>
+      </VirtualMachineLabel>
+   </SubjectLabels>
+</SecurityLabelTemplate>
+
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/security/policies/chwall/chwall-security_policy.xml
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/policies/chwall/chwall-security_policy.xml Fri Aug 19 
18:19:28 2005
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com  -->
+<!--             This file defines the security policies, which     -->
+<!--             can be enforced by the Xen Access Control Module.  -->
+<!--             Currently: Chinese Wall and Simple Type Enforcement-->
+<SecurityPolicyDefinition xmlns="http://www.ibm.com";
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+ xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
+<PolicyHeader>
+               <Name>chwall-security_policy</Name>
+               <Date>2005-08-10</Date>
+</PolicyHeader>
+<!--                                             -->
+<!-- example of a chinese wall type definition   -->
+<!-- along with its conflict sets                -->
+<!-- (typse in a confict set are exclusive, i.e. -->
+<!--  once a Domain with one type of a set is    -->
+<!--  running, no other Domain with another type -->
+<!--  of the same conflict set can start.)       -->
+       <ChineseWall priority="PrimaryPolicyComponent">
+        <ChineseWallTypes>
+            <Type>cw_SystemManagement</Type>
+            <Type>cw_Sensitive</Type>
+            <Type>cw_Isolated</Type>
+            <Type>cw_Distrusted</Type>
+        </ChineseWallTypes>
+
+        <ConflictSets>
+        <Conflict name="Protection1">
+            <Type>cw_Sensitive</Type>
+            <Type>cw_Distrusted</Type>
+        </Conflict>
+        </ConflictSets>
+       </ChineseWall>
+</SecurityPolicyDefinition>
+
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/security/policies/chwall_ste/chwall_ste-security_label_template.xml
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/policies/chwall_ste/chwall_ste-security_label_template.xml 
Fri Aug 19 18:19:28 2005
@@ -0,0 +1,167 @@
+<?xml version="1.0"?>
+<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com  -->
+<!--              This file defines the security labels, which can  -->
+<!--              be attached to Domains and resources. Based on    -->
+<!--              these labels, the access control module decides   -->
+<!--              about sharing between Domains and about access    -->
+<!--              of Domains to real resources.                     -->
+
+<SecurityLabelTemplate
+ xmlns="http://www.ibm.com";
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+ xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
+   <LabelHeader>
+      <Name>chwall_ste-security_label_template</Name>
+      <Date>2005-08-10</Date>
+      <PolicyName>
+         <Url>chwall_ste-security_policy.xml</Url>
+         <Reference>abcdef123456abcdef</Reference>
+      </PolicyName>
+   </LabelHeader>
+
+   <SubjectLabels bootstrap="dom_SystemManagement">
+      <!-- single ste typed domains            -->
+      <!-- ACM enforces that only domains with -->
+      <!-- the same type can share information -->
+      <!--                                     -->
+      <!-- Bootstrap label is assigned to Dom0 -->
+      <VirtualMachineLabel>
+       <Name>dom_HomeBanking</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_PersonalFinances</Type>
+         </SimpleTypeEnforcementTypes>
+
+         <ChineseWallTypes>
+            <Type>cw_Sensitive</Type>
+         </ChineseWallTypes>
+      </VirtualMachineLabel>
+
+      <VirtualMachineLabel>
+       <Name>dom_Fun</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_InternetInsecure</Type>
+         </SimpleTypeEnforcementTypes>
+
+         <ChineseWallTypes>
+            <Type>cw_Distrusted</Type>
+         </ChineseWallTypes>
+      </VirtualMachineLabel>
+
+      <VirtualMachineLabel>
+        <!-- donating some cycles to seti@home -->
+       <Name>dom_BoincClient</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_DonatedCycles</Type>
+         </SimpleTypeEnforcementTypes>
+
+         <ChineseWallTypes>
+            <Type>cw_Isolated</Type>
+         </ChineseWallTypes>
+      </VirtualMachineLabel>
+
+      <!-- Domains with multiple ste types services; such domains   -->
+      <!-- must keep the types inside their domain safely confined. -->
+      <VirtualMachineLabel>
+       <Name>dom_SystemManagement</Name>
+         <SimpleTypeEnforcementTypes>
+            <!-- since dom0 needs access to every domain and -->
+            <!-- resource right now ... -->
+            <Type>ste_SystemManagement</Type>
+            <Type>ste_PersonalFinances</Type>
+            <Type>ste_InternetInsecure</Type>
+            <Type>ste_DonatedCycles</Type>
+            <Type>ste_PersistentStorageA</Type>
+            <Type>ste_NetworkAdapter0</Type>
+         </SimpleTypeEnforcementTypes>
+
+         <ChineseWallTypes>
+            <Type>cw_SystemManagement</Type>
+         </ChineseWallTypes>
+      </VirtualMachineLabel>
+
+      <VirtualMachineLabel>
+        <!-- serves persistent storage to other domains -->
+       <Name>dom_StorageDomain</Name>
+         <SimpleTypeEnforcementTypes>
+            <!-- access right to the resource (hard drive a) -->
+            <Type>ste_PersistentStorageA</Type>
+            <!-- can serve following types -->
+            <Type>ste_PersonalFinances</Type>
+            <Type>ste_InternetInsecure</Type>
+         </SimpleTypeEnforcementTypes>
+
+         <ChineseWallTypes>
+            <Type>cw_SystemManagement</Type>
+         </ChineseWallTypes>
+      </VirtualMachineLabel>
+
+      <VirtualMachineLabel>
+        <!-- serves network access to other domains -->
+       <Name>dom_NetworkDomain</Name>
+         <SimpleTypeEnforcementTypes>
+            <!-- access right to the resource (ethernet card) -->
+            <Type>ste_NetworkAdapter0</Type>
+            <!-- can serve following types -->
+            <Type>ste_PersonalFinances</Type>
+            <Type>ste_InternetInsecure</Type>
+            <Type>ste_DonatedCycles</Type>
+         </SimpleTypeEnforcementTypes>
+
+         <ChineseWallTypes>
+            <Type>cw_SystemManagement</Type>
+         </ChineseWallTypes>
+      </VirtualMachineLabel>
+   </SubjectLabels>
+
+   <ObjectLabels>
+      <ResourceLabel>
+       <Name>res_ManagementResource</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_SystemManagement</Type>
+         </SimpleTypeEnforcementTypes>
+      </ResourceLabel>
+
+      <ResourceLabel>
+       <Name>res_HardDrive (hda)</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_PersistentStorageA</Type>
+         </SimpleTypeEnforcementTypes>
+      </ResourceLabel>
+
+      <ResourceLabel>
+       <Name>res_LogicalDiskPartition1 (hda1)</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_PersonalFinances</Type>
+         </SimpleTypeEnforcementTypes>
+      </ResourceLabel>
+
+      <ResourceLabel>
+       <Name>res_LogicalDiskPartition2 (hda2)</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_InternetInsecure</Type>
+         </SimpleTypeEnforcementTypes>
+      </ResourceLabel>
+
+      <ResourceLabel>
+       <Name>res_EthernetCard</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_NetworkAdapter0</Type>
+         </SimpleTypeEnforcementTypes>
+      </ResourceLabel>
+
+      <ResourceLabel>
+       <Name>res_SecurityToken</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_PersonalFinances</Type>
+         </SimpleTypeEnforcementTypes>
+      </ResourceLabel>
+
+      <ResourceLabel>
+       <Name>res_GraphicsAdapter</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_SystemManagement</Type>
+         </SimpleTypeEnforcementTypes>
+      </ResourceLabel>
+   </ObjectLabels>
+</SecurityLabelTemplate>
+
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/security/policies/chwall_ste/chwall_ste-security_policy.xml
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/policies/chwall_ste/chwall_ste-security_policy.xml Fri Aug 
19 18:19:28 2005
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com  -->
+<!--             This file defines the security policies, which     -->
+<!--             can be enforced by the Xen Access Control Module.  -->
+<!--             Currently: Chinese Wall and Simple Type Enforcement-->
+<SecurityPolicyDefinition xmlns="http://www.ibm.com";
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+ xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
+<PolicyHeader>
+               <Name>chwall_ste-security_policy</Name>
+               <Date>2005-08-10</Date>
+</PolicyHeader>
+<!--                                                        -->
+<!-- example of a simple type enforcement policy definition -->
+<!--                                                        -->
+       <SimpleTypeEnforcement>
+        <SimpleTypeEnforcementTypes>
+            <Type>ste_SystemManagement</Type>   <!-- machine/security 
management -->
+            <Type>ste_PersonalFinances</Type>   <!-- personal finances -->
+            <Type>ste_InternetInsecure</Type>   <!-- games, active X, etc. -->
+            <Type>ste_DonatedCycles</Type>      <!-- donation to 
BOINC/seti@home -->
+            <Type>ste_PersistentStorageA</Type> <!-- domain managing the 
harddrive A-->
+            <Type>ste_NetworkAdapter0</Type>    <!-- type of the domain 
managing ethernet adapter 0-->
+        </SimpleTypeEnforcementTypes>
+       </SimpleTypeEnforcement>
+<!--                                             -->
+<!-- example of a chinese wall type definition   -->
+<!-- along with its conflict sets                -->
+<!-- (typse in a confict set are exclusive, i.e. -->
+<!--  once a Domain with one type of a set is    -->
+<!--  running, no other Domain with another type -->
+<!--  of the same conflict set can start.)       -->
+       <ChineseWall priority="PrimaryPolicyComponent">
+        <ChineseWallTypes>
+            <Type>cw_SystemManagement</Type>
+            <Type>cw_Sensitive</Type>
+            <Type>cw_Isolated</Type>
+            <Type>cw_Distrusted</Type>
+        </ChineseWallTypes>
+
+        <ConflictSets>
+        <Conflict name="Protection1">
+            <Type>cw_Sensitive</Type>
+            <Type>cw_Distrusted</Type>
+        </Conflict>
+        </ConflictSets>
+       </ChineseWall>
+</SecurityPolicyDefinition>
+
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/security/policies/null/null-security_label_template.xml
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/policies/null/null-security_label_template.xml     Fri Aug 
19 18:19:28 2005
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com  -->
+<!--              This file defines the security labels, which can  -->
+<!--              be attached to Domains and resources. Based on    -->
+<!--              these labels, the access control module decides   -->
+<!--              about sharing between Domains and about access    -->
+<!--              of Domains to real resources.                     -->
+
+<SecurityLabelTemplate
+ xmlns="http://www.ibm.com";
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+ xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
+   <LabelHeader>
+      <Name>null-security_label_template</Name>
+
+      <Date>2005-08-10</Date>
+      <PolicyName>
+         <Url>null-security_policy.xml</Url>
+
+         <Reference>abcdef123456abcdef</Reference>
+      </PolicyName>
+   </LabelHeader>
+</SecurityLabelTemplate>
+
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/security/policies/null/null-security_policy.xml
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/policies/null/null-security_policy.xml     Fri Aug 19 
18:19:28 2005
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com  -->
+<!--             This file defines the security policies, which     -->
+<!--             can be enforced by the Xen Access Control Module.  -->
+<!--             Currently: Chinese Wall and Simple Type Enforcement-->
+<SecurityPolicyDefinition xmlns="http://www.ibm.com";
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+ xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
+<PolicyHeader>
+               <Name>null-security_policy</Name>
+               <Date>2005-08-10</Date>
+</PolicyHeader>
+</SecurityPolicyDefinition>
+
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/security/policies/security_policy.xsd
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/policies/security_policy.xsd       Fri Aug 19 18:19:28 2005
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Author: Ray Valdez, Reiner Sailer {rvaldez,sailer}@us.ibm.com -->
+<!--         This file defines the schema, which is used to define -->
+<!--         the security policy and the security labels in Xe.    -->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"; 
targetNamespace="http://www.ibm.com"; xmlns="http://www.ibm.com"; 
elementFormDefault="qualified">
+       <xsd:element name="SecurityPolicyDefinition">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element ref="PolicyHeader" minOccurs="0" 
maxOccurs="1"></xsd:element>
+                               <xsd:element ref="SimpleTypeEnforcement" 
minOccurs="0" maxOccurs="1"></xsd:element>
+                               <xsd:element ref="ChineseWall" minOccurs="0" 
maxOccurs="1"></xsd:element>
+                       </xsd:sequence>
+               </xsd:complexType>
+       </xsd:element>
+       <xsd:element name="SecurityLabelTemplate">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element ref="LabelHeader" minOccurs="1" 
maxOccurs="1"></xsd:element>
+                               <xsd:element name="SubjectLabels" minOccurs="0" 
maxOccurs="1">
+                                       <xsd:complexType>
+                                               <xsd:sequence>
+                                                       <xsd:element 
ref="VirtualMachineLabel" minOccurs="1" maxOccurs="unbounded"></xsd:element>
+                                               </xsd:sequence>
+                                               <xsd:attribute name="bootstrap" 
type="xsd:string" use="required"></xsd:attribute>
+                                       </xsd:complexType>
+                               </xsd:element>
+                               <xsd:element name="ObjectLabels" minOccurs="0" 
maxOccurs="1">
+                                       <xsd:complexType>
+                                               <xsd:sequence>
+                                                       <xsd:element 
ref="ResourceLabel" minOccurs="1" maxOccurs="unbounded"></xsd:element>
+                                               </xsd:sequence>
+                                       </xsd:complexType>
+                               </xsd:element>
+                       </xsd:sequence>
+               </xsd:complexType>
+       </xsd:element>
+       <xsd:element name="PolicyHeader">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element ref="Name" minOccurs="1" 
maxOccurs="1" />
+                               <xsd:element ref="Date" minOccurs="1" 
maxOccurs="1" />
+                       </xsd:sequence>
+               </xsd:complexType>
+       </xsd:element>
+       <xsd:element name="LabelHeader">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element ref="Name"></xsd:element>
+                               <xsd:element ref="Date" minOccurs="1" 
maxOccurs="1"></xsd:element>
+                               <xsd:element ref="PolicyName" minOccurs="1" 
maxOccurs="1"></xsd:element>
+                       </xsd:sequence>
+               </xsd:complexType>
+       </xsd:element>
+       <xsd:element name="SimpleTypeEnforcement">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element ref="SimpleTypeEnforcementTypes" />
+                       </xsd:sequence>
+                       <xsd:attribute name="priority" type="PolicyOrder" 
use="optional"></xsd:attribute>
+               </xsd:complexType>
+       </xsd:element>
+       <xsd:element name="ChineseWall">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element ref="ChineseWallTypes" />
+                               <xsd:element ref="ConflictSets" />
+                       </xsd:sequence>
+                       <xsd:attribute name="priority" type="PolicyOrder" 
use="optional"></xsd:attribute>
+               </xsd:complexType>
+       </xsd:element>
+       <xsd:element name="ChineseWallTypes">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element maxOccurs="unbounded" 
minOccurs="1" ref="Type" />
+                       </xsd:sequence>
+               </xsd:complexType>
+       </xsd:element>
+       <xsd:element name="ConflictSets">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element maxOccurs="unbounded" 
minOccurs="1" ref="Conflict" />
+                       </xsd:sequence>
+               </xsd:complexType>
+       </xsd:element>
+       <xsd:element name="SimpleTypeEnforcementTypes">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element maxOccurs="unbounded" 
minOccurs="1" ref="Type" />
+                       </xsd:sequence>
+               </xsd:complexType>
+       </xsd:element>
+       <xsd:element name="Conflict">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element maxOccurs="unbounded" 
minOccurs="1" ref="Type" />
+                       </xsd:sequence>
+                       <xsd:attribute name="name" type="xsd:string" 
use="optional"></xsd:attribute>
+               </xsd:complexType>
+       </xsd:element>
+       <xsd:element name="VirtualMachineLabel">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element ref="Name"></xsd:element>
+                               <xsd:element ref="SimpleTypeEnforcementTypes" 
minOccurs="0" maxOccurs="unbounded" />
+                               <xsd:element ref="ChineseWallTypes" 
minOccurs="0" maxOccurs="unbounded" />
+                       </xsd:sequence>
+               </xsd:complexType>
+       </xsd:element>
+       <xsd:element name="ResourceLabel">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element ref="Name"></xsd:element>
+                               <xsd:element ref="SimpleTypeEnforcementTypes" 
minOccurs="0" maxOccurs="unbounded" />
+                       </xsd:sequence>
+               </xsd:complexType>
+       </xsd:element>
+       <xsd:element name="PolicyName">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element ref="Url" />
+                               <xsd:element ref="Reference" />
+                       </xsd:sequence>
+               </xsd:complexType>
+       </xsd:element>
+       <xsd:element name="Date" type="xsd:string" />
+       <xsd:element name="Name" type="xsd:string" />
+       <xsd:element name="Type" type="xsd:string" />
+       <xsd:element name="Reference" type="xsd:string" />
+       <xsd:element name="Url"></xsd:element>
+
+       <xsd:simpleType name="PolicyOrder">
+               <xsd:restriction base="xsd:string">
+                       <xsd:enumeration 
value="PrimaryPolicyComponent"></xsd:enumeration>
+               </xsd:restriction>
+       </xsd:simpleType>
+
+</xsd:schema>
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/security/policies/ste/ste-security_label_template.xml
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/policies/ste/ste-security_label_template.xml       Fri Aug 
19 18:19:28 2005
@@ -0,0 +1,143 @@
+<?xml version="1.0"?>
+<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com  -->
+<!--              This file defines the security labels, which can  -->
+<!--              be attached to Domains and resources. Based on    -->
+<!--              these labels, the access control module decides   -->
+<!--              about sharing between Domains and about access    -->
+<!--              of Domains to real resources.                     -->
+
+<SecurityLabelTemplate
+ xmlns="http://www.ibm.com";
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+ xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
+   <LabelHeader>
+      <Name>ste-security_label_template</Name>
+      <Date>2005-08-10</Date>
+      <PolicyName>
+         <Url>ste-security_policy.xml</Url>
+         <Reference>abcdef123456abcdef</Reference>
+      </PolicyName>
+   </LabelHeader>
+
+   <SubjectLabels bootstrap="dom_SystemManagement">
+      <!-- single ste typed domains            -->
+      <!-- ACM enforces that only domains with -->
+      <!-- the same type can share information -->
+      <!--                                     -->
+      <!-- Bootstrap label is assigned to Dom0 -->
+      <VirtualMachineLabel>
+       <Name>dom_HomeBanking</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_PersonalFinances</Type>
+         </SimpleTypeEnforcementTypes>
+      </VirtualMachineLabel>
+
+      <VirtualMachineLabel>
+       <Name>dom_Fun</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_InternetInsecure</Type>
+         </SimpleTypeEnforcementTypes>
+      </VirtualMachineLabel>
+
+      <VirtualMachineLabel>
+        <!-- donating some cycles to seti@home -->
+       <Name>dom_BoincClient</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_DonatedCycles</Type>
+         </SimpleTypeEnforcementTypes>
+      </VirtualMachineLabel>
+
+      <!-- Domains with multiple ste types services; such domains   -->
+      <!-- must keep the types inside their domain safely confined. -->
+      <VirtualMachineLabel>
+       <Name>dom_SystemManagement</Name>
+         <SimpleTypeEnforcementTypes>
+            <!-- since dom0 needs access to every domain and -->
+            <!-- resource right now ... -->
+            <Type>ste_SystemManagement</Type>
+            <Type>ste_PersonalFinances</Type>
+            <Type>ste_InternetInsecure</Type>
+            <Type>ste_DonatedCycles</Type>
+            <Type>ste_PersistentStorageA</Type>
+            <Type>ste_NetworkAdapter0</Type>
+         </SimpleTypeEnforcementTypes>
+      </VirtualMachineLabel>
+
+      <VirtualMachineLabel>
+        <!-- serves persistent storage to other domains -->
+       <Name>dom_StorageDomain</Name>
+         <SimpleTypeEnforcementTypes>
+            <!-- access right to the resource (hard drive a) -->
+            <Type>ste_PersistentStorageA</Type>
+            <!-- can serve following types -->
+            <Type>ste_PersonalFinances</Type>
+            <Type>ste_InternetInsecure</Type>
+         </SimpleTypeEnforcementTypes>
+      </VirtualMachineLabel>
+
+      <VirtualMachineLabel>
+        <!-- serves network access to other domains -->
+       <Name>dom_NetworkDomain</Name>
+         <SimpleTypeEnforcementTypes>
+            <!-- access right to the resource (ethernet card) -->
+            <Type>ste_NetworkAdapter0</Type>
+            <!-- can serve following types -->
+            <Type>ste_PersonalFinances</Type>
+            <Type>ste_InternetInsecure</Type>
+            <Type>ste_DonatedCycles</Type>
+         </SimpleTypeEnforcementTypes>
+      </VirtualMachineLabel>
+   </SubjectLabels>
+
+   <ObjectLabels>
+      <ResourceLabel>
+       <Name>res_ManagementResource</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_SystemManagement</Type>
+         </SimpleTypeEnforcementTypes>
+      </ResourceLabel>
+
+      <ResourceLabel>
+       <Name>res_HardDrive (hda)</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_PersistentStorageA</Type>
+         </SimpleTypeEnforcementTypes>
+      </ResourceLabel>
+
+      <ResourceLabel>
+       <Name>res_LogicalDiskPartition1 (hda1)</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_PersonalFinances</Type>
+         </SimpleTypeEnforcementTypes>
+      </ResourceLabel>
+
+      <ResourceLabel>
+       <Name>res_LogicalDiskPartition2 (hda2)</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_InternetInsecure</Type>
+         </SimpleTypeEnforcementTypes>
+      </ResourceLabel>
+
+      <ResourceLabel>
+       <Name>res_EthernetCard</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_NetworkAdapter0</Type>
+         </SimpleTypeEnforcementTypes>
+      </ResourceLabel>
+
+      <ResourceLabel>
+       <Name>res_SecurityToken</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_PersonalFinances</Type>
+         </SimpleTypeEnforcementTypes>
+      </ResourceLabel>
+
+      <ResourceLabel>
+       <Name>res_GraphicsAdapter</Name>
+         <SimpleTypeEnforcementTypes>
+            <Type>ste_SystemManagement</Type>
+         </SimpleTypeEnforcementTypes>
+      </ResourceLabel>
+   </ObjectLabels>
+</SecurityLabelTemplate>
+
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/security/policies/ste/ste-security_policy.xml
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/policies/ste/ste-security_policy.xml       Fri Aug 19 
18:19:28 2005
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com  -->
+<!--             This file defines the security policies, which     -->
+<!--             can be enforced by the Xen Access Control Module.  -->
+<!--             Currently: Chinese Wall and Simple Type Enforcement-->
+<SecurityPolicyDefinition xmlns="http://www.ibm.com";
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+ xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
+<PolicyHeader>
+               <Name>ste-security_policy</Name>
+               <Date>2005-08-10</Date>
+</PolicyHeader>
+<!--                                                        -->
+<!-- example of a simple type enforcement policy definition -->
+<!--                                                        -->
+       <SimpleTypeEnforcement>
+        <SimpleTypeEnforcementTypes>
+            <Type>ste_SystemManagement</Type>   <!-- machine/security 
management -->
+            <Type>ste_PersonalFinances</Type>   <!-- personal finances -->
+            <Type>ste_InternetInsecure</Type>   <!-- games, active X, etc. -->
+            <Type>ste_DonatedCycles</Type>      <!-- donation to 
BOINC/seti@home -->
+            <Type>ste_PersistentStorageA</Type> <!-- domain managing the 
harddrive A-->
+            <Type>ste_NetworkAdapter0</Type>    <!-- type of the domain 
managing ethernet adapter 0-->
+        </SimpleTypeEnforcementTypes>
+       </SimpleTypeEnforcement>
+</SecurityPolicyDefinition>
+
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/security/policy.txt
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/policy.txt Fri Aug 19 18:19:28 2005
@@ -0,0 +1,405 @@
+##
+# policy.txt <description to the Xen access control architecture>
+#
+# Author:
+# Reiner Sailer 08/15/2005 <sailer@xxxxxxxxxxxxxx>
+#
+#
+# This file gives an overview of the security policies currently
+# provided and also gives some reasoning about how to assign
+# labels to domains.
+##
+
+Xen access control policies
+
+
+General explanation of supported security policies:
+=====================================================
+
+We have implemented the mandatory access control architecture of our
+hypervisor security architecture (sHype) for the Xen hypervisor. It
+controls communication (in Xen: event channels, grant tables) between
+Virtual Machines (from here on called domains) and through this the
+virtual block devices, networking, and shared memory are implemented
+on top of these communication means. While we have implemented the
+described policies and access control architecture for other
+hypervisor systems, we will describe below specifically its
+implementation and use in the Xen hypervisor. The policy enforcement
+is called mandatory regarding user domains since the policy it is
+given by the security administration and enforced independently of the
+user domains by the Xen hypervisor in cooperation with the domain
+management.
+
+The access control architecture consists of three parts:
+
+i) The access control policy determines the "command set" of the ACM
+and the hooks with which they can be configured to constrain the
+sharing of virtual resources. The current access control architecture
+implemented for Xen supports two policies: Chinese Wall and Simple
+Type Enforcement, which we describe in turn below.
+
+
+ii) The actually enforced policy instantiation uses the policy
+language (i) to configure the Xen access control in a way that suits
+the specific application (home desktop environment, company desktop,
+Web server system, etc.). We have defined an exemplary policy
+instantiation for Chinese Wall (chwall policy) and Simple Type
+Enforcement (ste policy) for a desktop system. We offer these policies
+in combination since they are controlling orthogonal events.
+
+
+iii) The access control module (ACM) and related hooks are part of the
+core hypervisor and their controls cannot be bypassed by domains. The
+ACM and hooks are the active security components. We refer to
+publications that describe how access control is enforced in the Xen
+hypervisor using the ACM (access decision) and the hooks (decision
+enforcement) inserted into the setup of event channels and grant
+tables, and into domain operations (create, destroy, save, restore,
+migrate). These controls decide based on the active policy
+configuration (see i. and ii.) if the operation proceeds of if the
+operation is aborted (denied).
+
+
+In general, security policy instantiations in the Xen access control
+framework are defined by two files:
+
+a) a single "policy-name"-security_policy.xml file that defines the
+types known to the ACM and policy rules based on these types
+
+b) a single "policy-name"-security_label_template.xml file that
+defines labels based on known types
+
+Every security policy has its own sub-directory under
+"Xen-root"/tools/security/policies in order to simplify their
+management and the security policy tools. We will describe those files
+for our example policy (Chinese Wall and Simple Type Enforcement) in
+more detail as we go along. Eventually, we will move towards a system
+installation where the policies will reside under /etc.
+
+
+CHINESE WALL
+============
+
+The Chinese Wall policy enables the user to define "which workloads
+(domain payloads) cannot run on a single physical system at the same
+time". Why would we want to prevent workloads from running at the same
+time on the same system? This supports requirements that can (but
+don't have to) be rooted in the measure of trust into the isolation of
+different domains that share the same hardware. Since the access
+control architecture aims at high performance and non-intrusive
+implementation, it currently does not address covert (timing) channels
+and aims at medium assurance. Users can apply the Chinese Wall policy
+to guarantee an air-gap between very sensitive payloads both regarding
+covert information channels and regarding resource starvation.
+
+To enable the CW control, each domain is labeled with a set of Chinese
+Wall types and CW Conflict Sets are defined which include those CW
+types that cannot run simultaneously on the same hardware. This
+interpretation of conflict sets is the only policy rule for the Chines
+Wall policy.
+
+This is enforced by controlling the start of domains according to
+their assigned CW worload types. Domains with Chinese Wall types that
+appear in a common conflict set are running mutually exclusive on a
+platform, i.e., once a domain with one of the cw-types of a conflict
+set is running, no domain with another cw-type of the same conflict
+set can start until the first domain is destroyed, paused, or migrated
+away from the physical system (this assumes that such a partition can
+no longer be observed). The idea is to assign cw-types according to
+the type of payload that a domain runs and to use the Chinese Wall
+policy to ensure that payload types can be differentiated by the
+hypervisor and can be prevented from being executed on the same system
+at the same time. Using the flexible CW policy maintains system
+consolidation and workload-balancing while introducing guaranteed
+constraints where necessary.
+
+
+Example of a Chinese Wall Policy Instantiation
+----------------------------------------------
+
+The file chwall-security_policy.xml defines the Chinese Wall types as
+well as the conflict sets for our example policy (you find it in the
+directory "xen_root"/tools/security/policies/chwall).
+
+It defines four Chinese Wall types (prefixed with cw_) with the
+following meaning:
+
+* cw_SystemsManagement is a type identifying workloads for systems
+management, e.g., domain management, device management, or hypervisor
+management.
+
+* cw_Sensitive is identifying workloads that are critical to the user
+for one reason or another.
+
+* cw_Distrusted is identifying workloads a user does not have much
+confidence in. E.g. a domain used for surfing in the internet without
+protection( i.e., active-X, java, java-script, executing web content)
+or for (Internet) Games should be typed this way.
+
+* cw_Isolated is identifying workloads that are supposedly isolated by
+use of the type enforcement policy (described below). For example, if
+a user wants to donate cycles to seti@home, she can setup a separate
+domain for a Boinc (http://boinc.ssl.berkeley.edu/) client, disable
+this domain from accessing the hard drive and from communicating to
+other local domains, and type it as cw_Isolated. We will look at a
+specific example later.
+
+The example policy uses the defined types to define one conflict set:
+Protection1 = {cw_Sensitive, cw_Distrusted}. This conflict set tells
+the hypervisor that once a domain typed as cw_Sensitive is running, a
+domain typed as cw_Distrusted cannot run concurrently (and the other
+way round). With this policy, a domain typed as cw_Isolated is allowed
+to run simultaneously with domains tagged as cw_Sensitive.
+
+Consequently, the access control module in the Xen hypervisor
+distinguishes in this example policy 4 different workload types in
+this example policy. It is the user's responsibility to type the
+domains in a way that reflects the workloads of these domains and, in
+the case of cw_Isolated, its properties, e.g. by configuring the
+sharing capabilities of the domain accordingly by using the simple
+type enforcement policy.
+
+Users can define their own or change the existing example policy
+according to their working environment and security requirements. To
+do so, replace the file chwall-security_policy.xml with the new
+policy.
+
+
+SIMPLE TYPE ENFORCEMENT
+=======================
+
+The file ste-security_policy.xml defines the simple type enforcement
+types for our example policy (you find it in the directory
+"xen_root"/tools/security/policies/ste). The Simple Type Enforcement
+policy defines which domains can share information with which other
+domains. To this end, it controls
+
+i) inter-domain communication channels (e.g., network traffic, events,
+and shared memory).
+
+ii) access of domains to physical resources (e.g., hard drive, network
+cards, graphics adapter, keyboard).
+
+In order to enable the hypervisor to distinguish different domains and
+the user to express access rules, the simple type enforcement defines
+a set of types (ste_types).
+
+The policy defines that communication between domains is allowed if
+the domains share a common STE type. As with the chwall types, STE
+types should enable the differentiation of workloads. The simple type
+enforcement access control implementation in the hypervisor enforces
+that domains can only communicate (setup event channels, grant tables)
+if they share a common type, i.e., both domains have assigned at least
+on type in common. A domain can access a resource, if the domain and
+the resource share a common type. Hence, assigning STE types to
+domains and resources allows users to define constraints on sharing
+between domains and to keep sensitive data confined from distrusted
+domains.
+
+Domain <--> Domain Sharing
+''''''''''''''''''''''''''
+(implemented but its effective use requires factorization of Dom0)
+
+a) Domains with a single STE type (general user domains): Sharing
+between such domains is enforced entirely by the hypervisor access
+control. It is independent of the domains and does not require their
+co-operation.
+
+b) Domains with multiple STE types: One example is a domain that
+virtualizes a physical resource (e.g., hard drive) and serves it as
+multiple virtual resources (virtual block drives) to other domains of
+different types. The idea is that only a specific device domain has
+assigned the type required to access the physical hard-drive. Logical
+drives are then assigned the types of domains that have access to this
+logical drive. Since the Xen hypervisor cannot distinguish between the
+logical drives, the access control (type enforcement) is delegated to
+the device domain, which has access to the types of domains requesting
+to mount a logical drive as well as the types assigned to the
+different available logical drives.
+
+Currently in Xen, Dom0 controls all hardware, needs to communicate
+with all domains during their setup, and intercepts all communication
+between domains. Consequently, Dom0 needs to be assigned all types
+used and must be completely trusted to maintain the separation of
+informatio ncoming from domains with different STE types. Thus a
+refactoring of Dom0 is recommended for stronger confinement
+guarantees.
+
+Domain --> RESOURCES Access
+'''''''''''''''''''''''''''
+(current work)
+
+We define for each resource that we want to distinguish a separate STE
+type. Each STE type is assigned to the respective resource and to
+those domains that are allowed to access this resource. Type
+enforcement will guarantee that other domains cannot access this
+resource since they don't share the resource's STE type.
+
+Since in the current implementation of Xen, Dom0 controls access to
+all hardware (e.g., disk drives, network), Domain-->Resource access
+control enforcement must be implemented in Dom0. This is possible
+since Dom0 has access to both the domain configuration (including the
+domain STE types) and the resource configuration (including the
+resource STE types).
+
+For purposes of gaining higher assurance in the resulting system, it
+may be desirable to reduce the size of dom0 by adding one or more
+"device domains" (DDs). These DDs, e.g. providing storage or network
+access, can support one or more physical devices, and manage
+enforcement of MAC policy relevant for said devices. Security benefits
+come from the smaller size of these DDs, as they can be more easily
+audited than monolithic device driver domains. DDs can help to obtain
+maximum security benefit from sHype.
+
+
+Example of a Simple Type Enforcement Policy Instantiation
+---------------------------------------------------------
+
+We define the following types:
+
+* ste_SystemManagement identifies workloads (and domains that runs
+them) that must share information to accomplish the management of the
+system
+
+* ste_PersonalFinances identifies workloads that are related to
+sensitive programs such as HomeBanking applications or safely
+configured web browsers for InternetBanking
+
+* ste_InternetInsecure identifies workloads that are very
+function-rich and unrestricted to offer for example an environment
+where internet games can run efficiently
+
+* ste_DonatedCycles identifies workloads that run on behalf of others,
+e.g. a Boinc client
+
+* ste_PersistentStorage identifies workloads that have direct access
+to persistent storage (e.g., hard drive)
+
+* ste_NetworkAccess identifies workload that have direct access to
+network cards and related networks
+
+
+
+SECURITY LABEL TEMPLATES
+========================
+
+We introduce security label templates because it is difficult for
+users to ensure tagging of domains consistently and since there are
+--as we have seen in the case of isolation-- useful dependencies
+between the policies. Security Label Templates define type sets that
+can be addressed by more user-friendly label names,
+e.g. dom_Homebanking describes a typical typeset tagged to domains
+used for sensitive Homebanking work-loads. Labels are defined in the
+file
+
+Using Security Label Templates has multiple advantages:
+a) easy reference of typical sets of type assignments
+b) consistent interpretation of type combinations
+c) meaningful application-level label names
+
+The definition of label templates depends on the combination of
+policies that are used. We will describe some of the labels defined
+for the Chinese Wall and Simple Type Enforcement combination.
+
+In the BoincClient example, the label_template file specifies that
+this Label is assigned the Chinese Wall type cw_Isolated. We do this
+assuming that this BoincClient is isolated against the rest of the
+system infrastructure (no persistent memory, no sharing with local
+domains). Since cw_Isolated is not included in any conflict set, it
+can run at any time concurrently with any other domain. The
+ste_DonatedCycles type assigned to the BoincClient reflect the
+isolation assumption: it is only assigned to the dom_NetworkDomain
+giving the BoincClient domain access to the network to communicate
+with its BoincServer.
+
+The strategy for combining types into Labels is the following: First
+we define a label for each type of general user domain
+(workload-oriented). Then we define a new label for each physical
+resource that shall be shared using a DD domain (e.g., disk) and for
+each logical resource offered through this physical resource (logical
+disk partition). We define then device domain labels (here:
+dom_SystemManagement, dom_StorageDomain, dom_NetworkDomain) which
+include the types of the physical resources (e.g. hda) their domains
+need to connect to. Such physical resources can only be accessed
+directly by device domains types with the respective device's STE
+type. Additionally we assign to such a device domain Label the STE
+types of those user domains that are allowed to access one of the
+logical resources (e.g., hda1, hda2) built on top of this physical
+resource through the device domain.
+
+
+Label Construction Example:
+---------------------------
+
+We define here a storage domain label for a domain that owns a real
+disk drive and creates the logical disk partitions hda1 and hda2 which
+it serves to domains labeled dom_HomeBanking and dom_Fun
+respectively. The labels we refer to are defined in the label template
+file policies/chwall_ste/chwall_ste-security-label-template.xml.
+
+step1: To distinguish different shared disk drives, we create a
+separate Label and STE type for each of them. Here: we create a type
+ste_PersistentStorageA for disk drive hda. If you have another disk
+drive, you may define another persistent storage type
+ste_PersistentStorageB in the chwall_ste-security_policy.xml.
+
+step2: To distinguish different domains, we create multiple domain
+labels including different types. Here: label dom_HomeBanking includes
+STE type ste_PersonalFinances, label dom_Fun includes STE type
+ste_InternetInsecure.
+
+step3: The storage domain in charge of the hard drive A needs access
+to this hard drive. Therefore the storage domain label
+dom_StorageDomain must include the type assigned to the hard drive
+(ste_PersistentStorageA).
+
+step4: In order to serve dom hda1 to domains labeled dom_HomeBanking
+and hda2 to domains labeled dom_Fun, the storage domain label must
+include the types of those domains as well (ste_PersonalFinance,
+ste_InternetInsecure).
+
+step5: In order to keep the data for different types safely apart, the
+different logical disk partitions must be assigned unique labels and
+types, which are used inside the storage domain to extend the ACM
+access enforcement to logical resources served from inside the storage
+domain. We define labels "res_LogicalDiskPartition1 (hda1)" and assign
+it to hda1 and "res_LogicalDiskPartition2 (hda2)" and assign it to
+hda2. These labels must include the STE types of those domains that
+are allowed to use them (e.g., ste_PersonalFinances for hda1).
+
+The overall mandatory access control is then enforced in 3 different
+Xen components and these components use a single consistent policy to
+co-operatively enforce the policy. In the storage domain example, we
+have three components that co-operate:
+
+1. The ACM module inside the hypervisor enforces: communication between
+user domains and the storage domain (only domains including types
+ste_PersonalFinances or ste_InternetInsecure can communicate with the
+storage domain and request access to logical resource). This confines
+the sharing to the types assigned to the storage domain.
+
+2. The domain management will enforce (work in progress): assignment of
+real resources (hda) to domains (storage domain) that share a
+type with the resource.
+
+3. If the storage domain serves multiple STE types (as in our example),
+it enforces (work in progress): that domains can access (mount)
+logical resources only if they share an STE type with the respective
+resource. In our example, domains with the STE type
+ste_PersonalFinances can request access (mount) to logical resource
+hda1 from the storage domain.
+
+If you look at the virtual machine label dom_StorageDomain, you will
+see the minimal set of types assigned to our domain manageing disk
+drive hda for serving logical disk partitions exclusively to
+dom_HomeBanking and dom_Fun.
+
+Similary, network domains can confine access to the network or
+network communication between user domains.
+
+As a result, device domains (e.g., storage domain, network domain)
+must be simple and small to ensure their correct co-operation in the
+type enforcement model. If such trust is not possible, then hardware
+should be assigned exclusively to a single type (or to a single
+partition) in which case the hypervisor ACM enforcement enforces the
+types independently.
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/security/readme.txt
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/readme.txt Fri Aug 19 18:19:28 2005
@@ -0,0 +1,29 @@
+
+##
+# readme.txt <description to the xen access control architecture>
+#
+# Author:
+# Reiner Sailer 08/15/2005 <sailer@xxxxxxxxxxxxxx>
+#
+#
+# This file is a toc for information regarding
+# the access control policy and tools in Xen.
+##
+
+1. policy.txt:
+
+   describes the general reasoning and examples for access
+   control policies in Xen
+
+
+2. install.txt
+
+   describes the activation of the access control framework
+   in Xen
+
+3. example.txt
+
+   describes the available tools for managing security policies
+   in Xen and the tools to label domains
+
+
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/security/secpol_compat.h
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/secpol_compat.h    Fri Aug 19 18:19:28 2005
@@ -0,0 +1,14 @@
+/* secpol_compat.h
+ *     'translates' data types necessary to
+ *     include <xen/acm.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;
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/security/secpol_xml2bin.c
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/secpol_xml2bin.c   Fri Aug 19 18:19:28 2005
@@ -0,0 +1,1396 @@
+/****************************************************************
+ * secpol_xml2bin.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author: Reiner Sailer <sailer@xxxxxxxxxx>
+ *
+ * Maintained:
+ * Reiner Sailer <sailer@xxxxxxxxxx>
+ * Ray Valdez <rvaldez@xxxxxxxxxx>
+ *
+ * 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, version 2 of the
+ * License.
+ *
+ * sHype policy translation tool. This tool takes an XML
+ * policy specification as input and produces a binary
+ * policy file that can be loaded into Xen through the
+ * ACM operations (secpol_tool loadpolicy) interface or at
+ * boot time (grub module parameter)
+ *
+ * indent -i4 -kr -nut
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <libgen.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/queue.h>
+#include <netinet/in.h>
+#include <libxml/xmlschemas.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlreader.h>
+#include "secpol_compat.h"
+#include <xen/acm.h>
+
+#include "secpol_xml2bin.h"
+
+#define DEBUG    0
+
+/* primary / secondary policy component setting */
+enum policycomponent { CHWALL, STE, NULLPOLICY }
+    primary = NULLPOLICY, secondary = NULLPOLICY;
+
+/* general list element for ste and chwall type queues */
+struct type_entry {
+    TAILQ_ENTRY(type_entry) entries;
+    char *name;                 /* name of type from xml file */
+    type_t mapping;             /* type mapping into 16bit */
+};
+
+TAILQ_HEAD(tailhead, type_entry) ste_head, chwall_head;
+
+/* general list element for all label queues */
+enum label_type { VM, RES, ANY };
+struct ssid_entry {
+    TAILQ_ENTRY(ssid_entry) entries;
+    char *name;                 /* label name */
+    enum label_type type;       /* type: VM / RESOURCE LABEL */
+    u_int32_t num;              /* ssid or referenced ssid */
+    int is_ref;                 /* if this entry references earlier ssid 
number */
+    unsigned char *row;         /* index of types (if not a reference) */
+};
+
+TAILQ_HEAD(tailhead_ssid, ssid_entry) ste_ssid_head, chwall_ssid_head,
+    conflictsets_head;
+struct ssid_entry *current_chwall_ssid_p = NULL;
+struct ssid_entry *current_ste_ssid_p = NULL;
+struct ssid_entry *current_conflictset_p = NULL;
+
+/* which label to assign to dom0 during boot */
+char *bootstrap_label;
+
+u_int32_t max_ste_ssids = 0;
+u_int32_t max_chwall_ssids = 0;
+u_int32_t max_chwall_labels = 0;
+u_int32_t max_ste_labels = 0;
+u_int32_t max_conflictsets = 0;
+
+char *current_ssid_name;        /* store name until structure is allocated */
+char *current_conflictset_name; /* store name until structure is allocated */
+
+/* dynamic list of type mappings for STE */
+u_int32_t max_ste_types = 0;
+
+/* dynamic list of type mappings for CHWALL */
+u_int32_t max_chwall_types = 0;
+
+/* dynamic list of conflict sets */
+int max_conflict_set = 0;
+
+/* which policies are defined */
+int have_ste = 0;
+int have_chwall = 0;
+
+/* input/output file names */
+char *policy_filename = NULL,
+    *label_filename = NULL,
+    *binary_filename = NULL, *mapping_filename = NULL;
+
+void usage(char *prg)
+{
+    printf("usage:\n%s policyname[-policy.xml/-security_label_template.xml]\n",
+         prg);
+    exit(EXIT_FAILURE);
+}
+
+
+/***************** policy-related parsing *********************/
+
+char *type_by_mapping(struct tailhead *head, u_int32_t mapping)
+{
+    struct type_entry *np;
+    for (np = head->tqh_first; np != NULL; np = np->entries.tqe_next)
+        if (np->mapping == mapping)
+            return np->name;
+    return NULL;
+}
+
+
+struct type_entry *lookup(struct tailhead *head, char *name)
+{
+    struct type_entry *np;
+    for (np = head->tqh_first; np != NULL; np = np->entries.tqe_next)
+        if (!(strcmp(np->name, name)))
+            return np;
+    return NULL;
+}
+
+/* enforces single-entry lists */
+int add_entry(struct tailhead *head, char *name, type_t mapping)
+{
+    struct type_entry *e;
+    if (lookup(head, name))
+    {
+        printf("Error: Type >%s< defined more than once.\n", name);
+        return -EFAULT;         /* already in the list */
+    }
+    if (!(e = malloc(sizeof(struct type_entry))))
+        return -ENOMEM;
+
+    e->name = name;
+    e->mapping = mapping;
+    TAILQ_INSERT_TAIL(head, e, entries);
+    return 0;
+}
+
+int totoken(char *tok)
+{
+    int i;
+    for (i = 0; token[i] != NULL; i++)
+        if (!strcmp(token[i], tok))
+            return i;
+    return -EFAULT;
+}
+
+/* conflictsets use the same data structure as ssids; since
+ * they are similar in structure (set of types)
+ */
+int init_next_conflictset(void)
+{
+    struct ssid_entry *conflictset = malloc(sizeof(struct ssid_entry));
+
+    if (!conflictset)
+        return -ENOMEM;
+
+    conflictset->name = current_conflictset_name;
+    conflictset->num = max_conflictsets++;
+    conflictset->is_ref = 0;    /* n/a for conflictsets */
+        /**
+         *  row: allocate one byte per type;
+         *  [i] != 0 --> mapped type >i< is part of the conflictset
+         */
+    conflictset->row = malloc(max_chwall_types);
+    if (!conflictset->row)
+        return -ENOMEM;
+
+    memset(conflictset->row, 0, max_chwall_types);
+    TAILQ_INSERT_TAIL(&conflictsets_head, conflictset, entries);
+    current_conflictset_p = conflictset;
+    return 0;
+}
+
+int register_type(xmlNode * cur_node, xmlDocPtr doc, unsigned long state)
+{
+    xmlChar *text;
+    struct type_entry *e;
+
+
+    text = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
+    if (!text)
+    {
+        printf("Error reading type name!\n");
+        return -EFAULT;
+    }
+
+    switch (state) {
+    case XML2BIN_stetype_S:
+        if (add_entry(&ste_head, (char *) text, max_ste_types))
+        {
+            xmlFree(text);
+            return -EFAULT;
+        }
+        max_ste_types++;
+        break;
+
+    case XML2BIN_chwalltype_S:
+        if (add_entry(&chwall_head, (char *) text, max_chwall_types))
+        {
+            xmlFree(text);
+            return -EFAULT;
+        }
+        max_chwall_types++;
+        break;
+
+    case XML2BIN_conflictsettype_S:
+        /* a) search the type in the chwall_type list */
+        e = lookup(&chwall_head, (char *) text);
+        if (e == NULL)
+        {
+            printf("CS type >%s< not a CHWALL type.\n", text);
+            xmlFree(text);
+            return -EFAULT;
+        }
+        /* b) add type entry to the current cs set */
+        if (current_conflictset_p->row[e->mapping])
+        {
+            printf("ERROR: Double entry of type >%s< in conflict set %d.\n",
+                 text, current_conflictset_p->num);
+            xmlFree(text);
+            return -EFAULT;
+        }
+        current_conflictset_p->row[e->mapping] = 1;
+        break;
+
+    default:
+        printf("Incorrect type environment (state = %lx, text = %s).\n",
+               state, text);
+        xmlFree(text);
+        return -EFAULT;
+    }
+    return 0;
+}
+
+void set_component_type(xmlNode * cur_node, enum policycomponent pc)
+{
+    xmlChar *order;
+
+    if ((order = xmlGetProp(cur_node, (xmlChar *) 
PRIMARY_COMPONENT_ATTR_NAME))) {
+        if (strcmp((char *) order, PRIMARY_COMPONENT))
+        {
+            printf("ERROR: Illegal attribut value >order=%s<.\n",
+                   (char *) order);
+            xmlFree(order);
+            exit(EXIT_FAILURE);
+        }
+        if (primary != NULLPOLICY)
+        {
+            printf("ERROR: Primary Policy Component set twice!\n");
+            exit(EXIT_FAILURE);
+        }
+        primary = pc;
+        xmlFree(order);
+    }
+}
+
+void walk_policy(xmlNode * start, xmlDocPtr doc, unsigned long state)
+{
+    xmlNode *cur_node = NULL;
+    int code;
+
+    for (cur_node = start; cur_node; cur_node = cur_node->next)
+    {
+        if ((code = totoken((char *) cur_node->name)) < 0)
+        {
+            printf("Unknown token: >%s<. Aborting.\n", cur_node->name);
+            exit(EXIT_FAILURE);
+        }
+        switch (code) {         /* adjust state to new state */
+        case XML2BIN_SECPOL:
+        case XML2BIN_STETYPES:
+        case XML2BIN_CHWALLTYPES:
+        case XML2BIN_CONFLICTSETS:
+            walk_policy(cur_node->children, doc, state | (1 << code));
+            break;
+
+        case XML2BIN_STE:
+            if (WRITTEN_AGAINST_ACM_STE_VERSION != ACM_STE_VERSION)
+            {
+                printf("ERROR: This program was written against another STE 
version.\n");
+                exit(EXIT_FAILURE);
+            }
+            have_ste = 1;
+            set_component_type(cur_node, STE);
+            walk_policy(cur_node->children, doc, state | (1 << code));
+            break;
+
+        case XML2BIN_CHWALL:
+            if (WRITTEN_AGAINST_ACM_CHWALL_VERSION != ACM_CHWALL_VERSION)
+            {
+                printf("ERROR: This program was written against another CHWALL 
version.\n");
+                exit(EXIT_FAILURE);
+            }
+            have_chwall = 1;
+            set_component_type(cur_node, CHWALL);
+            walk_policy(cur_node->children, doc, state | (1 << code));
+            break;
+
+        case XML2BIN_CSTYPE:
+            current_conflictset_name =
+                (char *) xmlGetProp(cur_node, (xmlChar *) "name");
+            if (!current_conflictset_name)
+                current_conflictset_name = "";
+
+            if (init_next_conflictset())
+            {
+                printf
+                    ("ERROR: creating new conflictset structure failed.\n");
+                exit(EXIT_FAILURE);
+            }
+            walk_policy(cur_node->children, doc, state | (1 << code));
+            break;
+
+        case XML2BIN_TYPE:
+            if (register_type(cur_node, doc, state))
+                exit(EXIT_FAILURE);
+            /* type leaf */
+            break;
+
+        case XML2BIN_TEXT:
+        case XML2BIN_COMMENT:
+        case XML2BIN_POLICYHEADER:
+            /* leaf - nothing to do */
+            break;
+
+        default:
+            printf("Unkonwn token Error (%d)\n", code);
+            exit(EXIT_FAILURE);
+        }
+
+    }
+    return;
+}
+
+int create_type_mapping(xmlDocPtr doc)
+{
+    xmlNode *root_element = xmlDocGetRootElement(doc);
+    struct type_entry *te;
+    struct ssid_entry *se;
+    int i;
+
+    printf("Creating ssid mappings ...\n");
+
+    /* initialize the ste and chwall type lists */
+    TAILQ_INIT(&ste_head);
+    TAILQ_INIT(&chwall_head);
+    TAILQ_INIT(&conflictsets_head);
+
+    walk_policy(root_element, doc, XML2BIN_NULL);
+
+    /* determine primary/secondary policy component orders */
+    if ((primary == NULLPOLICY) && have_chwall)
+        primary = CHWALL;       /* default if not set */
+    else if ((primary == NULLPOLICY) && have_ste)
+        primary = STE;
+
+    switch (primary) {
+
+    case CHWALL:
+        if (have_ste)
+            secondary = STE;
+        /* else default = NULLPOLICY */
+        break;
+
+    case STE:
+        if (have_chwall)
+            secondary = CHWALL;
+        /* else default = NULLPOLICY */
+        break;
+
+    default:
+        /* NULL/NULL policy */
+        break;
+    }
+
+    if (!DEBUG)
+        return 0;
+
+    /* print queues */
+    if (have_ste)
+    {
+        printf("STE-Type queue (%s):\n",
+               (primary == STE) ? "PRIMARY" : "SECONDARY");
+        for (te = ste_head.tqh_first; te != NULL;
+             te = te->entries.tqe_next)
+            printf("name=%22s, map=%x\n", te->name, te->mapping);
+    }
+    if (have_chwall)
+    {
+        printf("CHWALL-Type queue (%s):\n",
+               (primary == CHWALL) ? "PRIMARY" : "SECONDARY");
+        for (te = chwall_head.tqh_first; te != NULL;
+             te = te->entries.tqe_next)
+            printf("name=%s, map=%x\n", te->name, te->mapping);
+
+        printf("Conflictset queue (max=%d):\n", max_conflictsets);
+        for (se = conflictsets_head.tqh_first; se != NULL;
+             se = se->entries.tqe_next)
+        {
+            printf("conflictset name >%s<\n",
+                   se->name ? se->name : "NONAME");
+            for (i = 0; i < max_chwall_types; i++)
+                if (se->row[i])
+                    printf("#%x ", i);
+            printf("\n");
+        }
+    }
+    return 0;
+}
+
+
+/***************** template-related parsing *********************/
+
+/* add default ssid at head of ssid queues */
+int init_ssid_queues(void)
+{
+    struct ssid_entry *default_ssid_chwall, *default_ssid_ste;
+
+    default_ssid_chwall = malloc(sizeof(struct ssid_entry));
+    default_ssid_ste = malloc(sizeof(struct ssid_entry));
+
+    if ((!default_ssid_chwall) || (!default_ssid_ste))
+        return -ENOMEM;
+
+    /* default chwall ssid */
+    default_ssid_chwall->name = "DEFAULT";
+    default_ssid_chwall->num = max_chwall_ssids++;
+    default_ssid_chwall->is_ref = 0;
+    default_ssid_chwall->type = ANY;
+
+    default_ssid_chwall->row = malloc(max_chwall_types);
+
+    if (!default_ssid_chwall->row)
+        return -ENOMEM;
+
+    memset(default_ssid_chwall->row, 0, max_chwall_types);
+
+    TAILQ_INSERT_TAIL(&chwall_ssid_head, default_ssid_chwall, entries);
+    current_chwall_ssid_p = default_ssid_chwall;
+    max_chwall_labels++;
+
+    /* default ste ssid */
+    default_ssid_ste->name = "DEFAULT";
+    default_ssid_ste->num = max_ste_ssids++;
+    default_ssid_ste->is_ref = 0;
+    default_ssid_ste->type = ANY;
+
+    default_ssid_ste->row = malloc(max_ste_types);
+
+    if (!default_ssid_ste->row)
+        return -ENOMEM;
+
+    memset(default_ssid_ste->row, 0, max_ste_types);
+
+    TAILQ_INSERT_TAIL(&ste_ssid_head, default_ssid_ste, entries);
+    current_ste_ssid_p = default_ssid_ste;
+    max_ste_labels++;
+    return 0;
+}
+
+int init_next_chwall_ssid(unsigned long state)
+{
+    struct ssid_entry *ssid = malloc(sizeof(struct ssid_entry));
+
+    if (!ssid)
+        return -ENOMEM;
+
+    ssid->name = current_ssid_name;
+    ssid->num = max_chwall_ssids++;
+    ssid->is_ref = 0;
+
+    if (state & (1 << XML2BIN_VM))
+        ssid->type = VM;
+    else
+        ssid->type = RES;
+        /**
+         *  row: allocate one byte per type;
+         *  [i] != 0 --> mapped type >i< is part of the ssid
+         */
+    ssid->row = malloc(max_chwall_types);
+    if (!ssid->row)
+        return -ENOMEM;
+
+    memset(ssid->row, 0, max_chwall_types);
+    TAILQ_INSERT_TAIL(&chwall_ssid_head, ssid, entries);
+    current_chwall_ssid_p = ssid;
+    max_chwall_labels++;
+    return 0;
+}
+
+int init_next_ste_ssid(unsigned long state)
+{
+    struct ssid_entry *ssid = malloc(sizeof(struct ssid_entry));
+
+    if (!ssid)
+        return -ENOMEM;
+
+    ssid->name = current_ssid_name;
+    ssid->num = max_ste_ssids++;
+    ssid->is_ref = 0;
+
+    if (state & (1 << XML2BIN_VM))
+        ssid->type = VM;
+    else
+        ssid->type = RES;
+
+        /**
+         *  row: allocate one byte per type;
+         *  [i] != 0 --> mapped type >i< is part of the ssid
+         */
+    ssid->row = malloc(max_ste_types);
+    if (!ssid->row)
+        return -ENOMEM;
+
+    memset(ssid->row, 0, max_ste_types);
+    TAILQ_INSERT_TAIL(&ste_ssid_head, ssid, entries);
+    current_ste_ssid_p = ssid;
+    max_ste_labels++;
+
+    return 0;
+}
+
+
+/* adds a type to the current ssid */
+int add_type(xmlNode * cur_node, xmlDocPtr doc, unsigned long state)
+{
+    xmlChar *text;
+    struct type_entry *e;
+
+    text = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
+    if (!text)
+    {
+        printf("Error reading type name!\n");
+        return -EFAULT;
+    }
+    /* same for all: 1. lookup type mapping, 2. mark type in ssid */
+    switch (state) {
+    case XML2BIN_VM_STE_S:
+    case XML2BIN_RES_STE_S:
+        /* lookup the type mapping and include the type mapping into the array 
*/
+        if (!(e = lookup(&ste_head, (char *) text)))
+        {
+            printf("ERROR: unknown VM STE type >%s<.\n", text);
+            exit(EXIT_FAILURE);
+        }
+        if (current_ste_ssid_p->row[e->mapping])
+            printf("Warning: double entry of VM STE type >%s<.\n", text);
+
+        current_ste_ssid_p->row[e->mapping] = 1;
+        break;
+
+    case XML2BIN_VM_CHWALL_S:
+        /* lookup the type mapping and include the type mapping into the array 
*/
+        if (!(e = lookup(&chwall_head, (char *) text)))
+        {
+            printf("ERROR: unknown VM CHWALL type >%s<.\n", text);
+            exit(EXIT_FAILURE);
+        }
+        if (current_chwall_ssid_p->row[e->mapping])
+            printf("Warning: double entry of VM CHWALL type >%s<.\n",
+                   text);
+
+        current_chwall_ssid_p->row[e->mapping] = 1;
+        break;
+
+    default:
+        printf("Incorrect type environment (state = %lx, text = %s).\n",
+               state, text);
+        xmlFree(text);
+        return -EFAULT;
+    }
+    return 0;
+}
+
+void set_bootstrap_label(xmlNode * cur_node)
+{
+    xmlChar *order;
+
+    if ((order = xmlGetProp(cur_node, (xmlChar *) BOOTSTRAP_LABEL_ATTR_NAME)))
+        bootstrap_label = (char *)order;
+    else {
+        printf("ERROR: No bootstrap label defined!\n");
+        exit(EXIT_FAILURE);
+    }
+}
+
+void walk_labels(xmlNode * start, xmlDocPtr doc, unsigned long state)
+{
+    xmlNode *cur_node = NULL;
+    int code;
+
+    for (cur_node = start; cur_node; cur_node = cur_node->next)
+    {
+        if ((code = totoken((char *) cur_node->name)) < 0)
+        {
+            printf("Unkonwn token: >%s<. Aborting.\n", cur_node->name);
+            exit(EXIT_FAILURE);
+        }
+        switch (code) {         /* adjust state to new state */
+
+        case XML2BIN_SUBJECTS:
+            set_bootstrap_label(cur_node);
+            /* fall through */
+        case XML2BIN_VM:
+        case XML2BIN_RES:
+        case XML2BIN_SECTEMPLATE:
+        case XML2BIN_OBJECTS:
+            walk_labels(cur_node->children, doc, state | (1 << code));
+            break;
+
+        case XML2BIN_STETYPES:
+            /* create new ssid entry to use and point current to it */
+            if (init_next_ste_ssid(state))
+            {
+                printf("ERROR: creating new ste ssid structure failed.\n");
+                exit(EXIT_FAILURE);
+            }
+            walk_labels(cur_node->children, doc, state | (1 << code));
+
+            break;
+
+        case XML2BIN_CHWALLTYPES:
+            /* create new ssid entry to use and point current to it */
+            if (init_next_chwall_ssid(state))
+            {
+                printf("ERROR: creating new chwall ssid structure failed.\n");
+                exit(EXIT_FAILURE);
+            }
+            walk_labels(cur_node->children, doc, state | (1 << code));
+
+            break;
+
+        case XML2BIN_TYPE:
+            /* add type to current ssid */
+            if (add_type(cur_node, doc, state))
+                exit(EXIT_FAILURE);
+            break;
+
+        case XML2BIN_NAME:
+            if ((state != XML2BIN_VM_S) && (state != XML2BIN_RES_S))
+            {
+                printf("ERROR: >name< out of VM/RES context.\n");
+                exit(EXIT_FAILURE);
+            }
+            current_ssid_name = (char *)
+                xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
+
+            if (!current_ssid_name)
+            {
+                printf("ERROR: empty >name<!\n");
+                exit(EXIT_FAILURE);
+            }
+            break;
+
+        case XML2BIN_TEXT:
+        case XML2BIN_COMMENT:
+        case XML2BIN_LABELHEADER:
+            break;
+
+        default:
+            printf("Unkonwn token Error (%d)\n", code);
+            exit(EXIT_FAILURE);
+        }
+
+    }
+    return;
+}
+
+/* this function walks through a ssid queue
+ * and transforms double entries into references
+ * of the first definition (we need to keep the
+ * entry to map labels but we don't want double
+ * ssids in the binary policy
+ */
+void
+remove_doubles(struct tailhead_ssid *head,
+                        u_int32_t max_types, u_int32_t * max_ssids)
+{
+    struct ssid_entry *np, *ni;
+
+    /* walk once through the list */
+    for (np = head->tqh_first; np != NULL; np = np->entries.tqe_next)
+    {
+        /* now search from the start until np for the same entry */
+        for (ni = head->tqh_first; ni != np; ni = ni->entries.tqe_next)
+        {
+            if (ni->is_ref)
+                continue;
+            if (memcmp(np->row, ni->row, max_types))
+                continue;
+            /* found one, set np reference to ni */
+            np->is_ref = 1;
+            np->num = ni->num;
+            (*max_ssids)--;
+        }
+    }
+
+    /* now minimize the ssid numbers used (doubles introduce holes) */
+    (*max_ssids) = 0; /* reset */
+
+    for (np = head->tqh_first; np != NULL; np = np->entries.tqe_next)
+    {
+        if (np->is_ref)
+            continue;
+
+        if (np->num != (*max_ssids)) {
+                /* first reset all later references to the new max_ssid */
+                for (ni = np->entries.tqe_next; ni != NULL; ni = 
ni->entries.tqe_next)
+                {
+                    if (ni->num == np->num)
+                        ni->num = (*max_ssids);
+                }
+                /* now reset num */
+                np->num = (*max_ssids)++;
+        }
+        else
+            (*max_ssids)++;
+    }
+}
+
+/*
+ * will go away as soon as we have non-static bootstrap ssidref for dom0
+ */
+void fixup_bootstrap_label(struct tailhead_ssid *head,
+                         u_int32_t max_types, u_int32_t * max_ssids)
+{
+    struct ssid_entry *np;
+    int i;
+
+    /* should not happen if xml / xsd checks work */
+    if (!bootstrap_label)
+    {
+        printf("ERROR: No bootstrap label defined.\n");
+        exit(EXIT_FAILURE);
+    }
+
+    /* search bootstrap_label */
+    for (np = head->tqh_first; np != NULL; np = np->entries.tqe_next)
+    {
+        if (!strcmp(np->name, bootstrap_label))
+        {
+            break;
+        }
+    }
+
+    if (!np) {
+        /* bootstrap label not found */
+        printf("ERROR: Bootstrap label >%s< not found.\n", bootstrap_label);
+        exit(EXIT_FAILURE);
+    }
+
+    /* move this entry ahead in the list right after the default entry so it
+     * receives ssidref 1/1 */
+    TAILQ_REMOVE(head, np, entries);
+    TAILQ_INSERT_AFTER(head, head->tqh_first, np, entries);
+
+    /* renumber the ssids (we could also just switch places with 1st element) 
*/
+    for (np = head->tqh_first, i=0; np != NULL; np = np->entries.tqe_next, i++)
+        np->num   = i;
+
+}
+
+int create_ssid_mapping(xmlDocPtr doc)
+{
+    xmlNode *root_element = xmlDocGetRootElement(doc);
+    struct ssid_entry *np;
+    int i;
+
+    printf("Creating label mappings ...\n");
+    /* initialize the ste and chwall type lists */
+    TAILQ_INIT(&chwall_ssid_head);
+    TAILQ_INIT(&ste_ssid_head);
+
+    /* init with default ssids */
+    if (init_ssid_queues())
+    {
+        printf("ERROR adding default ssids.\n");
+        exit(EXIT_FAILURE);
+    }
+
+    /* now walk the template DOM tree and fill in ssids */
+    walk_labels(root_element, doc, XML2BIN_NULL);
+
+    /*
+     * now sort bootstrap label to the head of the list
+     * (for now), dom0 assumes its label in the first
+     * defined ssidref (1/1). 0/0 is the default non-Label
+     */
+    if (have_chwall)
+        fixup_bootstrap_label(&chwall_ssid_head, max_chwall_types,
+                                &max_chwall_ssids);
+    if (have_ste)
+        fixup_bootstrap_label(&ste_ssid_head, max_ste_types,
+                                &max_ste_ssids);
+
+    /* remove any double entries (insert reference instead) */
+    if (have_chwall)
+        remove_doubles(&chwall_ssid_head, max_chwall_types,
+                       &max_chwall_ssids);
+    if (have_ste)
+        remove_doubles(&ste_ssid_head, max_ste_types,
+                       &max_ste_ssids);
+
+    if (!DEBUG)
+        return 0;
+
+    /* print queues */
+    if (have_chwall)
+    {
+        printf("CHWALL SSID queue (max ssidrefs=%d):\n", max_chwall_ssids);
+        np = NULL;
+        for (np = chwall_ssid_head.tqh_first; np != NULL;
+             np = np->entries.tqe_next)
+        {
+            printf("SSID #%02u (Label=%s)\n", np->num, np->name);
+            if (np->is_ref)
+                printf("REFERENCE");
+            else
+                for (i = 0; i < max_chwall_types; i++)
+                    if (np->row[i])
+                        printf("#%02d ", i);
+            printf("\n\n");
+        }
+    }
+    if (have_ste)
+    {
+        printf("STE SSID queue (max ssidrefs=%d):\n", max_ste_ssids);
+        np = NULL;
+        for (np = ste_ssid_head.tqh_first; np != NULL;
+             np = np->entries.tqe_next)
+        {
+            printf("SSID #%02u (Label=%s)\n", np->num, np->name);
+            if (np->is_ref)
+                printf("REFERENCE");
+            else
+                for (i = 0; i < max_ste_types; i++)
+                    if (np->row[i])
+                        printf("#%02d ", i);
+            printf("\n\n");
+        }
+    }
+    return 0;
+}
+
+/***************** writing the binary policy *********************/
+
+/*
+ * the mapping file is ascii-based since it will likely be used from
+ * within scripts (using awk, grep, etc.);
+ *
+ * We print from high-level to low-level information so that with one
+ * pass, any symbol can be resolved (e.g. Label -> types)
+ */
+int write_mapping(char *filename)
+{
+
+    struct ssid_entry *e;
+    struct type_entry *t;
+    int i;
+    FILE *file;
+
+    if ((file = fopen(filename, "w")) == NULL)
+        return -EIO;
+
+    fprintf(file, "MAGIC                  %08x\n", ACM_MAGIC);
+    fprintf(file, "POLICY                 %s\n",
+            basename(policy_filename));
+    fprintf(file, "BINARY                 %s\n",
+            basename(binary_filename));
+    if (have_chwall)
+    {
+        fprintf(file, "MAX-CHWALL-TYPES       %08x\n", max_chwall_types);
+        fprintf(file, "MAX-CHWALL-SSIDS       %08x\n", max_chwall_ssids);
+        fprintf(file, "MAX-CHWALL-LABELS      %08x\n", max_chwall_labels);
+    }
+    if (have_ste)
+    {
+        fprintf(file, "MAX-STE-TYPES          %08x\n", max_ste_types);
+        fprintf(file, "MAX-STE-SSIDS          %08x\n", max_ste_ssids);
+        fprintf(file, "MAX-STE-LABELS         %08x\n", max_ste_labels);
+    }
+    fprintf(file, "\n");
+
+    /* primary / secondary order for combined ssid synthesis/analysis
+     * if no primary is named, then chwall is primary */
+    switch (primary) {
+    case CHWALL:
+        fprintf(file, "PRIMARY                CHWALL\n");
+        break;
+
+    case STE:
+        fprintf(file, "PRIMARY                STE\n");
+        break;
+
+    default:
+        fprintf(file, "PRIMARY                NULL\n");
+        break;
+    }
+
+    switch (secondary) {
+    case CHWALL:
+        fprintf(file, "SECONDARY              CHWALL\n");
+        break;
+
+    case STE:
+        fprintf(file, "SECONDARY              STE\n");
+        break;
+
+    default:
+        fprintf(file, "SECONDARY              NULL\n");
+        break;
+    }
+    fprintf(file, "\n");
+
+    /* first labels to ssid mappings */
+    if (have_chwall)
+    {
+        for (e = chwall_ssid_head.tqh_first; e != NULL;
+             e = e->entries.tqe_next)
+        {
+            fprintf(file, "LABEL->SSID %s CHWALL %-25s %8x\n",
+                    (e->type ==
+                     VM) ? "VM " : ((e->type == RES) ? "RES" : "ANY"),
+                    e->name, e->num);
+        }
+        fprintf(file, "\n");
+    }
+    if (have_ste)
+    {
+        for (e = ste_ssid_head.tqh_first; e != NULL;
+             e = e->entries.tqe_next)
+        {
+            fprintf(file, "LABEL->SSID %s STE    %-25s %8x\n",
+                    (e->type ==
+                     VM) ? "VM " : ((e->type == RES) ? "RES" : "ANY"),
+                    e->name, e->num);
+        }
+        fprintf(file, "\n");
+    }
+
+    /* second ssid to type mappings */
+    if (have_chwall)
+    {
+        for (e = chwall_ssid_head.tqh_first; e != NULL;
+             e = e->entries.tqe_next)
+        {
+            if (e->is_ref)
+                continue;
+
+            fprintf(file, "SSID->TYPE CHWALL      %08x", e->num);
+
+            for (i = 0; i < max_chwall_types; i++)
+                if (e->row[i])
+                    fprintf(file, " %s", type_by_mapping(&chwall_head, i));
+
+            fprintf(file, "\n");
+        }
+        fprintf(file, "\n");
+    }
+    if (have_ste) {
+        for (e = ste_ssid_head.tqh_first; e != NULL;
+             e = e->entries.tqe_next)
+        {
+            if (e->is_ref)
+                continue;
+
+            fprintf(file, "SSID->TYPE STE         %08x", e->num);
+
+            for (i = 0; i < max_ste_types; i++)
+                if (e->row[i])
+                    fprintf(file, " %s", type_by_mapping(&ste_head, i));
+
+            fprintf(file, "\n");
+        }
+        fprintf(file, "\n");
+    }
+    /* third type mappings */
+    if (have_chwall)
+    {
+        for (t = chwall_head.tqh_first; t != NULL; t = t->entries.tqe_next)
+        {
+            fprintf(file, "TYPE CHWALL            %-25s %8x\n",
+                    t->name, t->mapping);
+        }
+        fprintf(file, "\n");
+    }
+    if (have_ste) {
+        for (t = ste_head.tqh_first; t != NULL; t = t->entries.tqe_next)
+        {
+            fprintf(file, "TYPE STE               %-25s %8x\n",
+                    t->name, t->mapping);
+        }
+        fprintf(file, "\n");
+    }
+    fclose(file);
+    return 0;
+}
+
+unsigned char *write_chwall_binary(u_int32_t * len_chwall)
+{
+    unsigned char *buf, *ptr;
+    struct acm_chwall_policy_buffer *chwall_header;
+    u_int32_t len;
+    struct ssid_entry *e;
+    int i;
+
+    if (!have_chwall)
+        return NULL;
+
+    len = sizeof(struct acm_chwall_policy_buffer) +
+        sizeof(type_t) * max_chwall_types * max_chwall_ssids +
+        sizeof(type_t) * max_chwall_types * max_conflictsets;
+
+    buf = malloc(len);
+    ptr = buf;
+
+    if (!buf)
+    {
+        printf("ERROR: out of memory allocating chwall buffer.\n");
+        exit(EXIT_FAILURE);
+    }
+    /* chwall has 3 parts : header, types, conflictsets */
+
+    chwall_header = (struct acm_chwall_policy_buffer *) buf;
+    chwall_header->chwall_max_types = htonl(max_chwall_types);
+    chwall_header->chwall_max_ssidrefs = htonl(max_chwall_ssids);
+    chwall_header->policy_code = htonl(ACM_CHINESE_WALL_POLICY);
+    chwall_header->policy_version = htonl(ACM_CHWALL_VERSION);
+    chwall_header->chwall_ssid_offset =
+        htonl(sizeof(struct acm_chwall_policy_buffer));
+    chwall_header->chwall_max_conflictsets = htonl(max_conflictsets);
+    chwall_header->chwall_conflict_sets_offset =
+        htonl(ntohl(chwall_header->chwall_ssid_offset) +
+              sizeof(domaintype_t) * max_chwall_ssids * max_chwall_types);
+    chwall_header->chwall_running_types_offset = 0;     /* not set, only 
retrieved */
+    chwall_header->chwall_conflict_aggregate_offset = 0;        /* not set, 
only retrieved */
+    ptr += sizeof(struct acm_chwall_policy_buffer);
+
+    /* types */
+    for (e = chwall_ssid_head.tqh_first; e != NULL;
+         e = e->entries.tqe_next)
+    {
+        if (e->is_ref)
+            continue;
+
+        for (i = 0; i < max_chwall_types; i++)
+            ((type_t *) ptr)[i] = htons((type_t) e->row[i]);
+
+        ptr += sizeof(type_t) * max_chwall_types;
+    }
+
+    /* conflictsets */
+    for (e = conflictsets_head.tqh_first; e != NULL;
+         e = e->entries.tqe_next)
+    {
+        for (i = 0; i < max_chwall_types; i++)
+            ((type_t *) ptr)[i] = htons((type_t) e->row[i]);
+
+        ptr += sizeof(type_t) * max_chwall_types;
+    }
+
+    if ((ptr - buf) != len)
+    {
+        printf("ERROR: wrong lengths in %s.\n", __func__);
+        exit(EXIT_FAILURE);
+    }
+
+    (*len_chwall) = len;
+    return buf;
+}
+
+unsigned char *write_ste_binary(u_int32_t * len_ste)
+{
+    unsigned char *buf, *ptr;
+    struct acm_ste_policy_buffer *ste_header;
+    struct ssid_entry *e;
+    u_int32_t len;
+    int i;
+
+    if (!have_ste)
+        return NULL;
+
+    len = sizeof(struct acm_ste_policy_buffer) +
+        sizeof(type_t) * max_ste_types * max_ste_ssids;
+
+    buf = malloc(len);
+    ptr = buf;
+
+    if (!buf)
+    {
+        printf("ERROR: out of memory allocating chwall buffer.\n");
+        exit(EXIT_FAILURE);
+    }
+
+    /* fill buffer */
+    ste_header = (struct acm_ste_policy_buffer *) buf;
+    ste_header->policy_version = htonl(ACM_STE_VERSION);
+    ste_header->policy_code = htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
+    ste_header->ste_max_types = htonl(max_ste_types);
+    ste_header->ste_max_ssidrefs = htonl(max_ste_ssids);
+    ste_header->ste_ssid_offset =
+        htonl(sizeof(struct acm_ste_policy_buffer));
+
+    ptr += sizeof(struct acm_ste_policy_buffer);
+
+    /* types */
+    for (e = ste_ssid_head.tqh_first; e != NULL; e = e->entries.tqe_next)
+    {
+        if (e->is_ref)
+            continue;
+
+        for (i = 0; i < max_ste_types; i++)
+            ((type_t *) ptr)[i] = htons((type_t) e->row[i]);
+
+        ptr += sizeof(type_t) * max_ste_types;
+    }
+
+    if ((ptr - buf) != len)
+    {
+        printf("ERROR: wrong lengths in %s.\n", __func__);
+        exit(EXIT_FAILURE);
+    }
+    (*len_ste) = len;
+    return buf;                 /* for now */
+}
+
+int write_binary(char *filename)
+{
+    struct acm_policy_buffer header;
+    unsigned char *ste_buffer = NULL, *chwall_buffer = NULL;
+    u_int32_t len;
+    int fd;
+
+    u_int32_t len_ste = 0, len_chwall = 0;      /* length of policy components 
*/
+
+    /* open binary file */
+    if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) 
<= 0)
+        return -EIO;
+
+    ste_buffer = write_ste_binary(&len_ste);
+    chwall_buffer = write_chwall_binary(&len_chwall);
+
+    /* determine primary component (default chwall) */
+    header.policy_version = htonl(ACM_POLICY_VERSION);
+    header.magic = htonl(ACM_MAGIC);
+
+    len = sizeof(struct acm_policy_buffer);
+    if (have_chwall)
+        len += len_chwall;
+    if (have_ste)
+        len += len_ste;
+    header.len = htonl(len);
+
+    header.primary_buffer_offset = htonl(sizeof(struct acm_policy_buffer));
+    if (primary == CHWALL)
+    {
+        header.primary_policy_code = htonl(ACM_CHINESE_WALL_POLICY);
+        header.secondary_buffer_offset =
+            htonl((sizeof(struct acm_policy_buffer)) + len_chwall);
+    }
+    else if (primary == STE)
+    {
+        header.primary_policy_code =
+            htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
+        header.secondary_buffer_offset =
+            htonl((sizeof(struct acm_policy_buffer)) + len_ste);
+    }
+    else
+    {
+        /* null policy */
+        header.primary_policy_code = htonl(ACM_NULL_POLICY);
+        header.secondary_buffer_offset =
+            htonl(header.primary_buffer_offset);
+    }
+
+    if (secondary == CHWALL)
+        header.secondary_policy_code = htonl(ACM_CHINESE_WALL_POLICY);
+    else if (secondary == STE)
+        header.secondary_policy_code =
+            htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
+    else
+        header.secondary_policy_code = htonl(ACM_NULL_POLICY);
+
+    if (write(fd, (void *) &header, sizeof(struct acm_policy_buffer))
+        != sizeof(struct acm_policy_buffer))
+        return -EIO;
+
+    /* write primary policy component */
+    if (primary == CHWALL)
+    {
+        if (write(fd, chwall_buffer, len_chwall) != len_chwall)
+            return -EIO;
+    }
+    else if (primary == STE)
+    {
+        if (write(fd, ste_buffer, len_ste) != len_ste)
+            return -EIO;
+    } else
+        ;                     /* NULL POLICY has no policy data */
+
+    /* write secondary policy component */
+    if (secondary == CHWALL)
+    {
+        if (write(fd, chwall_buffer, len_chwall) != len_chwall)
+            return -EIO;
+    }
+    else if (secondary == STE)
+    {
+        if (write(fd, ste_buffer, len_ste) != len_ste)
+            return -EIO;
+    } else;                     /* NULL POLICY has no policy data */
+
+    close(fd);
+    return 0;
+}
+
+int is_valid(xmlDocPtr doc)
+{
+    int err = 0;
+    xmlSchemaPtr schema_ctxt = NULL;
+    xmlSchemaParserCtxtPtr schemaparser_ctxt = NULL;
+    xmlSchemaValidCtxtPtr schemavalid_ctxt = NULL;
+
+    schemaparser_ctxt = xmlSchemaNewParserCtxt(SCHEMA_FILENAME);
+    schema_ctxt = xmlSchemaParse(schemaparser_ctxt);
+    schemavalid_ctxt = xmlSchemaNewValidCtxt(schema_ctxt);
+
+#ifdef VALIDATE_SCHEMA
+    /* only tested to be available from libxml2-2.6.20 upwards */
+    if ((err = xmlSchemaIsValid(schemavalid_ctxt)) != 1)
+    {
+        printf("ERROR: Invalid schema file %s (err=%d)\n",
+               SCHEMA_FILENAME, err);
+        err = -EIO;
+        goto out;
+    }
+    else
+        printf("XML Schema %s valid.\n", SCHEMA_FILENAME);
+#endif
+    if ((err = xmlSchemaValidateDoc(schemavalid_ctxt, doc)))
+    {
+        err = -EIO;
+        goto out;
+    }
+  out:
+    xmlSchemaFreeValidCtxt(schemavalid_ctxt);
+    xmlSchemaFreeParserCtxt(schemaparser_ctxt);
+    xmlSchemaFree(schema_ctxt);
+    return (err != 0) ? 0 : 1;
+}
+
+int main(int argc, char **argv)
+{
+    xmlDocPtr labeldoc = NULL;
+    xmlDocPtr policydoc = NULL;
+
+    int err = EXIT_SUCCESS;
+
+    char *file_prefix;
+    int prefix_len;
+
+    if (ACM_POLICY_VERSION != WRITTEN_AGAINST_ACM_POLICY_VERSION)
+    {
+        printf("ERROR: This program was written against an older ACM 
version.\n");
+        exit(EXIT_FAILURE);
+    }
+
+    if (argc != 2)
+        usage(basename(argv[0]));
+
+    prefix_len = strlen(POLICY_SUBDIR) +
+        strlen(argv[1]) + 1 /* "/" */  +
+        strlen(argv[1]) + 1 /* "/" */ ;
+
+    file_prefix = malloc(prefix_len);
+    policy_filename = malloc(prefix_len + strlen(POLICY_EXTENSION));
+    label_filename = malloc(prefix_len + strlen(LABEL_EXTENSION));
+    binary_filename = malloc(prefix_len + strlen(BINARY_EXTENSION));
+    mapping_filename = malloc(prefix_len + strlen(MAPPING_EXTENSION));
+
+    if (!file_prefix || !policy_filename || !label_filename ||
+        !binary_filename || !mapping_filename)
+    {
+        printf("ERROR allocating file name memory.\n");
+        goto out2;
+    }
+
+    /* create input/output filenames out of prefix */
+    strcat(file_prefix, POLICY_SUBDIR);
+    strcat(file_prefix, argv[1]);
+    strcat(file_prefix, "/");
+    strcat(file_prefix, argv[1]);
+
+    strcpy(policy_filename, file_prefix);
+    strcpy(label_filename, file_prefix);
+    strcpy(binary_filename, file_prefix);
+    strcpy(mapping_filename, file_prefix);
+
+    strcat(policy_filename, POLICY_EXTENSION);
+    strcat(label_filename, LABEL_EXTENSION);
+    strcat(binary_filename, BINARY_EXTENSION);
+    strcat(mapping_filename, MAPPING_EXTENSION);
+
+    labeldoc = xmlParseFile(label_filename);
+
+    if (labeldoc == NULL)
+    {
+        printf("Error: could not parse file %s.\n", argv[1]);
+        goto out2;
+    }
+
+    printf("Validating label file %s...\n", label_filename);
+    if (!is_valid(labeldoc))
+    {
+        printf("ERROR: Failed schema-validation for file %s (err=%d)\n",
+               label_filename, err);
+        goto out1;
+    }
+
+    policydoc = xmlParseFile(policy_filename);
+
+    if (policydoc == NULL)
+    {
+        printf("Error: could not parse file %s.\n", argv[1]);
+        goto out1;
+    }
+
+    printf("Validating policy file %s...\n", policy_filename);
+
+    if (!is_valid(policydoc))
+    {
+        printf("ERROR: Failed schema-validation for file %s (err=%d)\n",
+               policy_filename, err);
+        goto out;
+    }
+
+    /* Init queues and parse policy */
+    create_type_mapping(policydoc);
+
+    /* create ssids */
+    create_ssid_mapping(labeldoc);
+
+    /* write label mapping file */
+    if (write_mapping(mapping_filename))
+    {
+        printf("ERROR: writing mapping file %s.\n", mapping_filename);
+        goto out;
+    }
+
+    /* write binary file */
+    if (write_binary(binary_filename))
+    {
+        printf("ERROR: writing binary file %s.\n", binary_filename);
+        goto out;
+    }
+
+    /* write stats */
+    if (have_chwall)
+    {
+        printf("Max chwall labels:  %u\n", max_chwall_labels);
+        printf("Max chwall-types:   %u\n", max_chwall_types);
+        printf("Max chwall-ssids:   %u\n", max_chwall_ssids);
+    }
+
+    if (have_ste)
+    {
+        printf("Max ste labels:     %u\n", max_ste_labels);
+        printf("Max ste-types:      %u\n", max_ste_types);
+        printf("Max ste-ssids:      %u\n", max_ste_ssids);
+    }
+    /* cleanup */
+  out:
+    xmlFreeDoc(policydoc);
+  out1:
+    xmlFreeDoc(labeldoc);
+  out2:
+    xmlCleanupParser();
+    return err;
+}
+
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/security/secpol_xml2bin.h
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/secpol_xml2bin.h   Fri Aug 19 18:19:28 2005
@@ -0,0 +1,139 @@
+/****************************************************************
+ * secpol_xml2bin.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Authors:
+ * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
+ *
+ * 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, version 2 of the
+ * License.
+ *
+ */
+#define POLICY_SUBDIR       "policies/"
+#define POLICY_EXTENSION    "-security_policy.xml"
+#define LABEL_EXTENSION     "-security_label_template.xml"
+#define BINARY_EXTENSION    ".bin"
+#define MAPPING_EXTENSION   ".map"
+#define PRIMARY_COMPONENT_ATTR_NAME "order"
+#define BOOTSTRAP_LABEL_ATTR_NAME   "bootstrap"
+#define PRIMARY_COMPONENT   "PrimaryPolicyComponent"
+#define SCHEMA_FILENAME     "policies/security_policy.xsd"
+
+/* basic states (used as 1 << X) */
+#define XML2BIN_SECPOL             0   /* policy tokens */
+#define XML2BIN_STE                    1
+#define XML2BIN_CHWALL          2
+#define XML2BIN_CONFLICTSETS           3
+#define XML2BIN_CSTYPE         4
+
+#define XML2BIN_SECTEMPLATE        5   /* label tokens */
+#define XML2BIN_POLICYHEADER           6
+#define XML2BIN_LABELHEADER     7
+#define XML2BIN_SUBJECTS        8
+#define XML2BIN_OBJECTS            9
+#define XML2BIN_VM                 10
+#define XML2BIN_RES            11
+
+#define XML2BIN_STETYPES           12  /* shared tokens */
+#define XML2BIN_CHWALLTYPES        13
+#define XML2BIN_TYPE               14
+#define XML2BIN_NAME            15
+#define XML2BIN_TEXT               16
+#define XML2BIN_COMMENT                17
+
+/* type "data type" (currently 16bit) */
+typedef u_int16_t type_t;
+
+/* list of known elements and token equivalent  *
+ * state constants and token positions must be  *
+ * in sync for correct state recognition        */
+
+char *token[20] =                       /* parser triggers */
+{
+    [0] = "SecurityPolicyDefinition",   /* policy xml */
+    [1] = "SimpleTypeEnforcement",
+    [2] = "ChineseWall",
+    [3] = "ConflictSets",
+    [4] = "Conflict",                   /* label-template xml */
+    [5] = "SecurityLabelTemplate",
+    [6] = "PolicyHeader",
+    [7] = "LabelHeader",
+    [8] = "SubjectLabels",
+    [9] = "ObjectLabels",
+    [10] = "VirtualMachineLabel",
+    [11] = "ResourceLabel",
+    [12] = "SimpleTypeEnforcementTypes",                  /* common tags */
+    [13] = "ChineseWallTypes",
+    [14] = "Type",
+    [15] = "Name",
+    [16] = "text",
+    [17] = "comment",
+    [18] = NULL,
+};
+
+/* important combined states */
+#define XML2BIN_NULL           0
+
+/* policy xml parsing states _S */
+
+/* e.g., here we are in a <secpol,ste,stetypes> environment,  *
+ * so when finding a type element, we know where to put it    */
+#define XML2BIN_stetype_S ((1 << XML2BIN_SECPOL) | \
+                                (1 << XML2BIN_STE) |    \
+                                (1 << XML2BIN_STETYPES))
+
+#define XML2BIN_chwalltype_S ((1 << XML2BIN_SECPOL) | \
+                                (1 << XML2BIN_CHWALL) | \
+                                (1 << XML2BIN_CHWALLTYPES))
+
+#define XML2BIN_conflictset_S ((1 << XML2BIN_SECPOL) | \
+                                (1 << XML2BIN_CHWALL) | \
+                                (1 << XML2BIN_CONFLICTSETS))
+
+#define XML2BIN_conflictsettype_S ((1 << XML2BIN_SECPOL) | \
+                                (1 << XML2BIN_CHWALL) | \
+                                (1 << XML2BIN_CONFLICTSETS) | \
+                                (1 << XML2BIN_CSTYPE))
+
+
+/* label xml states */
+#define XML2BIN_VM_S ((1 << XML2BIN_SECTEMPLATE) | \
+                      (1 << XML2BIN_SUBJECTS) |    \
+                      (1 << XML2BIN_VM))
+
+#define XML2BIN_RES_S ((1 << XML2BIN_SECTEMPLATE) | \
+                       (1 << XML2BIN_OBJECTS) |     \
+                       (1 << XML2BIN_RES))
+
+#define XML2BIN_VM_STE_S ((1 << XML2BIN_SECTEMPLATE) | \
+                        (1 << XML2BIN_SUBJECTS) | \
+                        (1 << XML2BIN_VM) | \
+                        (1 << XML2BIN_STETYPES))
+
+#define XML2BIN_VM_CHWALL_S ((1 << XML2BIN_SECTEMPLATE) | \
+                           (1 << XML2BIN_SUBJECTS) | \
+                           (1 << XML2BIN_VM) | \
+                           (1 << XML2BIN_CHWALLTYPES))
+
+#define XML2BIN_RES_STE_S ((1 << XML2BIN_SECTEMPLATE) | \
+                         (1 << XML2BIN_OBJECTS) | \
+                         (1 << XML2BIN_RES) | \
+                         (1 << XML2BIN_STETYPES))
+
+
+
+/* check versions of headers against which the
+ * xml2bin translation tool was written
+ */
+
+/* protects from unnoticed changes in struct acm_policy_buffer */
+#define WRITTEN_AGAINST_ACM_POLICY_VERSION  1
+
+/* protects from unnoticed changes in struct acm_chwall_policy_buffer */
+#define WRITTEN_AGAINST_ACM_CHWALL_VERSION  1
+
+/* protects from unnoticed changes in struct acm_ste_policy_buffer */
+#define WRITTEN_AGAINST_ACM_STE_VERSION     1
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/security/setlabel.sh
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/setlabel.sh        Fri Aug 19 18:19:28 2005
@@ -0,0 +1,345 @@
+#!/bin/sh
+# *
+# * setlabel
+# *
+# * Copyright (C) 2005 IBM Corporation
+# *
+# * Authors:
+# * Stefan Berger <stefanb@xxxxxxxxxx>
+# *
+# * 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, version 2 of the
+# * License.
+# *
+# * 'setlabel' labels virtual machine (domain) configuration files with
+# * security identifiers that can be enforced in Xen.
+# *
+# * 'setlabel -?' shows the usage of the program
+# *
+# * 'setlabel -l vmconfig-file' lists all available labels (only VM
+# *            labels are used right now)
+# *
+# * 'setlabel vmconfig-file security-label map-file' inserts the 'ssidref'
+# *                       that corresponds to the security-label under the
+# *                       current policy (if policy changes, 'label'
+# *                       must be re-run over the configuration files;
+# *                       map-file is created during policy translation and
+# *                       is found in the policy's directory
+#
+
+if [ -z "$runbash" ]; then
+       runbash="1"
+       export runbash
+       exec sh -c "bash $0 $*"
+fi
+
+
+usage ()
+{
+       echo "Usage: $0 [Option] <vmfile> <label> <policy name> "
+       echo "    or $0 -l <policy name>"
+       echo ""
+       echo "Valid Options are:"
+       echo "-r          : to relabel a file without being prompted"
+       echo ""
+       echo "vmfile      : XEN vm configuration file"
+       echo "label       : the label to map"
+       echo "policy name : the name of the policy, i.e. 'chwall'"
+       echo ""
+       echo "-l <policy name> is used to show valid labels in the map file"
+       echo ""
+}
+
+
+findMapFile ()
+{
+       mapfile="./$1.map"
+       if [ -r "$mapfile" ]; then
+               return 1
+       fi
+
+       mapfile="./policies/$1/$1.map"
+       if [ -r "$mapfile" ]; then
+               return 1
+       fi
+
+       return 0
+}
+
+showLabels ()
+{
+       mapfile=$1
+       if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
+               echo "Cannot read from vm configuration file $vmfile."
+               return -1
+       fi
+
+       getPrimaryPolicy $mapfile
+       getSecondaryPolicy $mapfile
+
+       echo "The following labels are available:"
+       let line=1
+       while [ 1 ]; do
+               ITEM=`cat $mapfile |         \
+                     awk -vline=$line       \
+                         -vprimary=$primary \
+                     '{                     \
+                        if ($1 == "LABEL->SSID" &&  \
+                            $2 == "VM" &&           \
+                            $3 == primary ) {       \
+                          ctr++;                    \
+                          if (ctr == line) {        \
+                            print $4;               \
+                          }                         \
+                        }                           \
+                      } END {                       \
+                      }'`
+
+               if [ "$ITEM" == "" ]; then
+                       break
+               fi
+               if [ "$secondary" != "NULL" ]; then
+                       LABEL=`cat $mapfile |     \
+                              awk -vitem=$ITEM   \
+                              '{
+                                 if ($1 == "LABEL->SSID" && \
+                                     $2 == "VM" &&          \
+                                     $3 == "CHWALL" &&      \
+                                     $4 == item ) {         \
+                                   result = item;           \
+                                 }                          \
+                               } END {                      \
+                                   print result             \
+                               }'`
+               else
+                       LABEL=$ITEM
+               fi
+
+               if [ "$LABEL" != "" ]; then
+                       echo "$LABEL"
+                       found=1
+               fi
+               let line=line+1
+       done
+       if [ "$found" != "1" ]; then
+               echo "No labels found."
+       fi
+}
+
+getPrimaryPolicy ()
+{
+       mapfile=$1
+       primary=`cat $mapfile  |   \
+                awk '             \
+                 {                \
+                   if ( $1 == "PRIMARY" ) { \
+                     res=$2;                \
+                   }                        \
+                 } END {                    \
+                   print res;               \
+                 } '`
+}
+
+getSecondaryPolicy ()
+{
+       mapfile=$1
+       secondary=`cat $mapfile  |   \
+                awk '             \
+                 {                \
+                   if ( $1 == "SECONDARY" ) { \
+                     res=$2;                \
+                   }                        \
+                 } END {                    \
+                   print res;               \
+                 } '`
+}
+
+
+getDefaultSsid ()
+{
+       mapfile=$1
+       pol=$2
+       RES=`cat $mapfile    \
+            awk -vpol=$pol  \
+             {              \
+               if ($1 == "LABEL->SSID" && \
+                   $2 == "ANY"         && \
+                   $3 == pol           && \
+                   $4 == "DEFAULT"       ) {\
+                     res=$5;                \
+               }                            \
+             } END {                        \
+               printf "%04x", strtonum(res) \
+            }'`
+       echo "default NULL mapping is $RES"
+       defaultssid=$RES
+}
+
+relabel ()
+{
+       vmfile=$1
+       label=$2
+       mapfile=$3
+       mode=$4
+
+       if [ ! -r "$vmfile" ]; then
+               echo "Cannot read from vm configuration file $vmfile."
+               return -1
+       fi
+
+       if [ ! -w "$vmfile" ]; then
+               echo "Cannot write to vm configuration file $vmfile."
+               return -1
+       fi
+
+       if [ ! -r "$mapfile" ] ; then
+               echo "Cannot read mapping file $mapfile."
+               return -1
+       fi
+
+       # Determine which policy is primary, which sec.
+       getPrimaryPolicy $mapfile
+       getSecondaryPolicy $mapfile
+
+       # Calculate the primary policy's SSIDREF
+       if [ "$primary" == "NULL" ]; then
+               SSIDLO="0000"
+       else
+               SSIDLO=`cat $mapfile |                    \
+                       awk -vlabel=$label                \
+                           -vprimary=$primary            \
+                          '{                             \
+                             if ( $1 == "LABEL->SSID" && \
+                                  $2 == "VM" &&          \
+                                  $3 == primary  &&      \
+                                  $4 == label ) {        \
+                               result=$5                 \
+                             }                           \
+                          } END {                        \
+                            if (result != "" )           \
+                              {printf "%04x", strtonum(result)}\
+                          }'`
+       fi
+
+       # Calculate the secondary policy's SSIDREF
+       if [ "$secondary" == "NULL" ]; then
+               SSIDHI="0000"
+       else
+               SSIDHI=`cat $mapfile |                    \
+                       awk -vlabel=$label                \
+                           -vsecondary=$secondary        \
+                          '{                             \
+                             if ( $1 == "LABEL->SSID" && \
+                                  $2 == "VM"          && \
+                                  $3 == secondary     && \
+                                  $4 == label ) {        \
+                               result=$5                 \
+                             }                           \
+                           }  END {                      \
+                             if (result != "" )          \
+                               {printf "%04x", strtonum(result)}\
+                           }'`
+       fi
+
+       if [ "$SSIDLO" == "" -o \
+            "$SSIDHI" == "" ]; then
+               echo "Could not map the given label '$label'."
+               return -1
+       fi
+
+       ACM_POLICY=`cat $mapfile |             \
+           awk ' { if ( $1 == "POLICY" ) {    \
+                     result=$2                \
+                   }                          \
+                 }                            \
+                 END {                        \
+                   if (result != "") {        \
+                     printf result            \
+                   }                          \
+                 }'`
+
+       if [ "$ACM_POLICY" == "" ]; then
+               echo "Could not find 'POLICY' entry in map file."
+               return -1
+       fi
+
+       SSIDREF="0x$SSIDHI$SSIDLO"
+
+       if [ "$mode" != "relabel" ]; then
+               RES=`cat $vmfile |  \
+                    awk '{         \
+                      if ( substr($1,0,7) == "ssidref" ) {\
+                        print $0;             \
+                      }                       \
+                    }'`
+               if [ "$RES" != "" ]; then
+                       echo "Do you want to overwrite the existing mapping 
($RES)? (y/N)"
+                       read user
+                       if [ "$user" != "y" -a "$user" != "Y" ]; then
+                               echo "Aborted."
+                               return 0
+                       fi
+               fi
+       fi
+
+       #Write the output
+       vmtmp1="/tmp/__setlabel.tmp1"
+       vmtmp2="/tmp/__setlabel.tmp2"
+       touch $vmtmp1
+       touch $vmtmp2
+       if [ ! -w "$vmtmp1" -o ! -w "$vmtmp2" ]; then
+               echo "Cannot create temporary files. Aborting."
+               return -1
+       fi
+       RES=`sed -e '/^#ACM_POLICY/d' $vmfile > $vmtmp1`
+       RES=`sed -e '/^#ACM_LABEL/d' $vmtmp1 > $vmtmp2`
+       RES=`sed -e '/^ssidref/d' $vmtmp2 > $vmtmp1`
+       echo "#ACM_POLICY=$ACM_POLICY" >> $vmtmp1
+       echo "#ACM_LABEL=$label" >> $vmtmp1
+       echo "ssidref = $SSIDREF" >> $vmtmp1
+       mv -f $vmtmp1 $vmfile
+       rm -rf $vmtmp1 $vmtmp2
+       echo "Mapped label '$label' to ssidref '$SSIDREF'."
+}
+
+
+
+if [ "$1" == "-r" ]; then
+       mode="relabel"
+       shift
+elif [ "$1" == "-l" ]; then
+       mode="show"
+       shift
+elif [ "$1" == "-?" ]; then
+       mode="usage"
+fi
+
+if [ "$mode" == "show" ]; then
+       if [ "$1" == "" ]; then
+               usage
+               exit -1;
+       fi
+       findMapFile $1
+       res=$?
+       if [ "$res" != "0" ]; then
+               showLabels $mapfile
+       else
+               echo "Could not find map file for policy '$1'."
+       fi
+elif [ "$mode" == "usage" ]; then
+       usage
+else
+       if [ "$3" == "" ]; then
+               usage
+               exit -1;
+       fi
+       findMapFile $3
+       res=$?
+       if [ "$res" != "0" ]; then
+               relabel $1 $2 $mapfile $mode
+       else
+               echo "Could not find map file for policy '$3'."
+       fi
+
+fi
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/security/updategrub.sh
--- /dev/null   Thu Aug 18 18:40:02 2005
+++ b/tools/security/updategrub.sh      Fri Aug 19 18:19:28 2005
@@ -0,0 +1,171 @@
+#!/bin/sh
+# *
+# * updategrub
+# *
+# * Copyright (C) 2005 IBM Corporation
+# *
+# * Authors:
+# * Stefan Berger <stefanb@xxxxxxxxxx>
+# *
+# * 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, version 2 of the
+# * License.
+# *
+# *
+#
+
+if [ -z "$runbash" ]; then
+       runbash="1"
+       export runbash
+       exec sh -c "bash $0 $*"
+       exit
+fi
+
+
+# Show usage of this program
+usage ()
+{
+       echo "Usage: $0 <policy name> <root of xen repository>"
+       echo ""
+       echo "<policy name>             : The name of the policy, i.e. xen_null"
+       echo "<root of xen repository>  : The root of the XEN repositrory."
+       echo ""
+}
+
+# This function sets the global variable 'linux'
+# to the name of the linux kernel that was compiled
+# For now a pattern should do the trick
+getLinuxVersion ()
+{
+       path=$1
+       linux=""
+       for f in $path/linux-*-xen0 ; do
+               versionfile=$f/include/linux/version.h
+               if [ -r $versionfile ]; then
+                       lnx=`cat $versionfile | \
+                            grep UTS_RELEASE | \
+                            awk '{             \
+                              len=length($3);  \
+                              print substr($3,2,len-2) }'`
+               fi
+               if [ "$lnx" != "" ]; then
+                       linux="[./0-9a-zA-z]*$lnx"
+                       return;
+               fi
+       done
+
+       #Last resort.
+       linux="vmlinuz-2.[45678].[0-9]*[.0-9]*-xen0$"
+}
+
+#Return where the grub.conf file is.
+#I only know of one place it can be.
+findGrubConf()
+{
+       grubconf="/boot/grub/grub.conf"
+       if [ -w $grubconf ]; then
+               return 1
+       fi
+       return 0
+}
+
+
+#Update the grub configuration file.
+#Search for existing entries and replace the current
+#policy entry with the policy passed to this script
+#
+#Arguments passed to this function
+# 1st : the grub configuration file
+# 2nd : the binary policy file name
+# 3rd : the name or pattern of the linux kernel name to match
+#
+# The algorithm here is based on pattern matching
+# and is working correctly if
+# - under a title a line beginning with 'kernel' is found
+#   whose following item ends with "xen.gz"
+#   Example:  kernel /xen.gz dom0_mem=....
+# - a module line matching the 3rd parameter is found
+#
+updateGrub ()
+{
+       grubconf=$1
+       policyfile=$2
+       linux=$3
+
+       tmpfile="/tmp/new_grub.conf"
+
+       cat $grubconf |                                \
+                awk -vpolicy=$policyfile              \
+                    -vlinux=$linux '{                 \
+                  if ( $1 == "title" ) {              \
+                    kernelfound = 0;                  \
+                    if ( policymaycome == 1 ){        \
+                      printf ("\tmodule %s%s\n", path, policy);      \
+                    }                                 \
+                    policymaycome = 0;                \
+                  }                                   \
+                  else if ( $1 == "kernel" ) {        \
+                    if ( match($2,"xen.gz$") ) {      \
+                      path=substr($2,1,RSTART-1);     \
+                      kernelfound = 1;                \
+                    }                                 \
+                  }                                   \
+                  else if ( $1 == "module" &&         \
+                            kernelfound == 1 &&       \
+                            match($2,linux) ) {       \
+                     policymaycome = 1;               \
+                  }                                   \
+                  else if ( $1 == "module" &&         \
+                            kernelfound == 1 &&       \
+                            policymaycome == 1 &&     \
+                            match($2,"[0-9a-zA-Z]*.bin$") ) { \
+                     printf ("\tmodule %s%s\n", path, policy); \
+                     policymaycome = 0;               \
+                     kernelfound = 0;                 \
+                     dontprint = 1;                   \
+                  }                                   \
+                  else if ( $1 == "" &&               \
+                            kernelfound == 1 &&       \
+                            policymaycome == 1) {     \
+                     dontprint = 1;                   \
+                  }                                   \
+                  if (dontprint == 0) {               \
+                    printf ("%s\n", $0);              \
+                  }                                   \
+                  dontprint = 0;                      \
+                } END {                               \
+                  if ( policymaycome == 1 ) {         \
+                    printf ("\tmodule %s%s\n", path, policy);  \
+                  }                                   \
+                }' > $tmpfile
+       if [ ! -r $tmpfile ]; then
+               echo "Could not create temporary file! Aborting."
+               exit -1
+       fi
+       mv -f $tmpfile $grubconf
+}
+
+if [ "$1" == "" -o "$2" == "" ]; then
+       usage
+       exit -1
+fi
+
+if [ "$1" == "-?" ]; then
+       usage
+       exit 0
+fi
+
+policy=$1
+policyfile=$policy.bin
+
+getLinuxVersion $2
+
+findGrubConf
+ERR=$?
+if [ $ERR -eq 0 ]; then
+       echo "Could not find grub.conf. Aborting."
+       exit -1
+fi
+
+updateGrub $grubconf $policyfile $linux
diff -r 99914b54f7bf -r 81576d3d1ca8 docs/misc/shype4xen_readme.txt
--- a/docs/misc/shype4xen_readme.txt    Thu Aug 18 18:40:02 2005
+++ /dev/null   Fri Aug 19 18:19:28 2005
@@ -1,588 +0,0 @@
-Copyright: IBM Corporation (C)
-20 June 2005
-Author: Reiner Sailer
-
-This document is a very short introduction into the sHype access control 
-security architecture implementation and how it is perceived by users. It 
-is a very preliminary draft  for the courageous ones to get "their feet wet" 
-and to be able to give feedback (via the xen-devel/xense-devel mailing lists).
-
-Install:
-
-cd into xeno-unstable.bk 
-(use --dry-run option if you want to test the patch only)
-patch -p1 -g0 < *tools.diff
-patch -p1 -g0 < *xen.diff
-
-(no rejects, probably some line offsets)
-
-make uninstall; make mrproper; make; ./install.sh should install the default 
-sHype into Xen (rebuild your initrd images if necessary). Reboot.
-
-Debug output: there are two triggers for debug output:
-a) General sHype debug:
-    xeno-unstable.bk/xen/include/public/acm.h
-    undefine ACM_DEBUG to switch this debug off
-
-b) sHype enforcement hook trace: This prints a small trace for each 
enforcement 
-hook that is executed. The trigger is in
-    xeno-unstable.bk/xen/include/acm/acm_hooks.h
-    undefine ACM_TRACE_MODE to switch this debug off
-
-1. The default NULL policy
-***************************
-When you apply the patches and startup xen, you should at first not notice any 
-difference because the default policy is the "NULL" policy, which as the name 
-implies does not enforce anything.
-
-To display the currently enforced policy, use the policy tool under xeno-
-unstable.bk/tools/policy: policy_tool getpolicy. You should see output like 
the 
-one below.
-
-[root@laptop policy]#./policy_tool getpolicy
-
-Policy dump:
-============
-Magic     = 1debc.
-PolVer    = aaaa0000.
-Len       = 14.
-Primary   = NULL policy (c=0, off=14).
-Secondary = NULL policy (c=0, off=14).
-No primary policy (NULL).
-No secondary policy (NULL).
-
-Policy dump End.
-
-Since this is a dump of a binary policy, it's not pretty. The important parts 
-are the "Primary" and "Secondary" policy fields set to "NULL policy". sHype 
-currently allows to set two independent policies; thus the two SSID-REF parts 
-shown in 'xm list'. Right here: primary policy only means this policy is 
-checked first, the secondary policy is checked if the primary results in 
-"permitted access". The result of the combined policy is "permitted" if both 
-policies return permitted (NULL policy always returns permitted). The result 
is 
-"denied" if at least one of the policies returns "denied". Look into xeno-
-unstable.bk/xen/include/acm/acm_hooks.h for the general hook structure 
-integrating the policy decisions (if you like, you won't need it for the rest 
-of the Readme file).
-
-2. Setting Chinese Wall and Simple Type Enforcement policies:
-*************************************************************
-
-We'll get fast to the point. However, in order to understand what we are 
doing, 
-we must at least understand the purpose of the policies that we are going to 
-enforce. The two policies presented here are just examples and the 
-implementation encourages adding new policies easily.
-
-2.1. Chinese Wall policy: "decides whether a domain can be started based on 
-this domain's ssidref and the ssidrefs of the currently running domains". 
-Generally, the Chinese wall policy allows specifying certain types (or classes 
-or categories, whatever the preferred word) that conflict; we usually assign a 
-type to a workload and the set of types of those workloads running in a domain 
-make up the type set for this domain.  Each domain is assigned a set of types 
-through its SSID-REF (we register Chinese Wall as primary policy, so the 
-ssidref used for determining the Chinese Wall types is the one annotated with 
-"p:" in xm list) since each SSID-REF points at a set of types. We'll see how 
-SSIDREFs are represented in Xen later when we will look at the policy. (A good 
-read for Chinese Wall is: Brewer/Nash The Chinese Wall Security Policy 1989.)
-
-So let's assume the Chinese Wall policy we are running distinguishes 10 types: 
-t0 ... t9. Let us assume further that each SSID-REF points to a set that 
-includes exactly one type (attached to domains that run workloads of a single 
-type). SSID-REF 0 points to {t0}, ssidref 1 points to {t1} ... 9 points to 
-{t9}. [This is actually the example policy we are going to push into xen later]
-
-Now the Chinese Wall policy allows you to define "Conflict type sets" and it 
-guarantees that of any conflict set at most one type is "running" at any time. 
-As an example, we have defined 2 conflict set: {t2, t3} and {t0, t5, t6}. 
-Specifying these conflict sets, sHype ensures that at most one type of each 
set 
-is running (either t2 or t3 but not both; either t0 or t5 or t6 but not 
-multiple of them).
-
-The effect is that administrators can define which workload types cannot run 
-simultaneously on a single Xen system. This is useful to limit the covert 
-timing channels between such payloads or to ensure that payloads don't 
-interfere with each other through existing resource dependencies.
-
-2.2. Simple Type Enforcement (ste) policy: "decides whether two domains can 
-share data, e.g., setup event channels or grant tables to each other, based on 
-the two domains' ssidref. This, as the name says, is a simple policy. Think of 
-each type as of a single color. Each domain has one or more colors, i.e., the 
-domains ssid for the ste policy points to a set that has set one or multiple 
-types. Let us assume in our example policy we differentiate 5 colors (types) 
-and define 5 different ssids referenced by ssidref=0..4. Each ssid shall have 
-exactly one type set, i.e., describes a uni-color. Only ssid(0) has all types 
-set, i.e., has all defined colors.
-
-Sharing is enforced by the ste policy by requiring that two domains that want 
-to establish an event channel or grant pages to each other must have a common 
-color. Currently all domains communicate through DOM0 by default; i.e., 
Domain0 
-will necessarily have all colors to be able to create domains (thus, we will 
-assign ssidref(0) to Domain0 in our example below.
-
-More complex mandatory access control policies governing sharing will follow; 
-such policies are more sophisticated than the "color" scheme above by allowing 
-more flexible (and complex :_) access control decisions than "share a color" 
or 
-"don't share a color" and will be able to express finer-grained policies.
-
-
-2.3 Binary Policy:
-In the future, we will have a policy tool that takes as input a more humane 
-policy description, using types such as development, home-banking, donated-
-Grid, CorpA-Payload ... and translates the respective policy into what we see 
-today as the binary policy using 1s and 0s and sets of them. For now, we must 
-live with the binary policy when working with sHype.
-
-    
-2.4 Exemplary use of a real sHype policy on Xen. To activate a real policy, 
-edit the file (yes, this will soon be a compile option):
-  xeno-unstable.bk/xen/include/public/acm.h
-  Change: #define ACM_USE_SECURITY_POLICY ACM_NULL_POLICY
-   To : #define ACM_USE_SECURITY_POLICY 
ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY
-   cd xeno-unstable.bk
-   make mrproper
-   make uninstall (manually remove /etc/xen.old if necessary)
-   make
-   ./install.sh      (recreate your kernel initrd's if necessary)
-   Reboot into new xen.gz
-     
-After booting, check out 'xm dmesg'; should show somewhere in the middle:
-
-(XEN) acm_init: Enforcing Primary CHINESE WALL policy, Secondary SIMPLE TYPE 
-ENFORCEMENT policy.
-
-Even though you can activate those policies in any combination and also 
-independently, the policy tool currently only supports setting the policy for 
-the above combination.
-
-Now look at the minimal startup policy with:
-                xeno-unstable.bk/tools/policytool getpolicy
-
-You should see something like:
-
-[root@laptop policy]# ./policy_tool getpolicy
-
-Policy dump:
-============
-Magic     = 1debc.
-PolVer    = aaaa0000.
-Len       = 36.
-Primary   = CHINESE WALL policy (c=1, off=14).
-Secondary = SIMPLE TYPE ENFORCEMENT policy (c=2, off=2c).
-
-
-Chinese Wall policy:
-====================
-Max Types     = 1.
-Max Ssidrefs  = 1.
-Max ConfSets  = 1.
-Ssidrefs Off  = 10.
-Conflicts Off = 12.
-Runing T. Off = 14.
-C. Agg. Off   = 16.
-
-SSID To CHWALL-Type matrix:
-
-   ssidref 0:  00 
-
-Confict Sets:
-
-   c-set 0:    00 
-
-Running
-Types:         00 
-
-Conflict
-Aggregate Set: 00 
-
-
-Simple Type Enforcement policy:
-===============================
-Max Types     = 1.
-Max Ssidrefs  = 1.
-Ssidrefs Off  = 8.
-
-SSID To STE-Type matrix:
-
-   ssidref 0: 01 
-
-
-Policy dump End.
-
-This is a minimal policy (of little use), except it will disable starting any 
-domain that does not have ssidref set to 0x0. The Chinese Wall policy has 
-nothing to enforce and the ste policy only knows one type, which is set for 
the 
-only defined ssidref.
-
-The item that defines the ssidref in a domain configuration is:
-
-ssidref = 0x12345678
-
-Where ssidref is interpreted as a 32bit number, where the lower 16bits become 
-the ssidref for the primary policy and the higher 16bits become the ssidref 
for 
-the secondary policy. sHype currently supports two policies but this is an 
-implementation decision and can be extended if necessary.
-
-This reference defines the security information of a domain. The meaning of 
the 
-SSID-REF depends on the policy, so we explain it when we explain the real 
-policies.
-
-
-Setting a new Security Policy:
-******************************
-The policy tool with all its current limitations has one usable example policy 
-compiled-in. Please try at this time to use the setpolicy command:
-       xeno-unstable.bk/tools/policy/policy_tool setpolicy
-
-You should see a dump of the policy you are setting. It should say at the very 
-end: 
-
-Policy successfully set.
-
-Now try to dump the currently enforced policy, which is the policy we have 
just 
-set and the dynamic security state information of this policy 
-(<<< ... some additional explanations)
-
-[root@laptop policy]# ./policy_tool getpolicy
-
-Policy dump:
-============
-Magic     = 1debc.
-PolVer    = aaaa0000.
-Len       = 112.
-Primary   = CHINESE WALL policy (c=1, off=14).
-Secondary = SIMPLE TYPE ENFORCEMENT policy (c=2, off=d8).
-
-
-Chinese Wall policy:
-====================
-Max Types     = a.
-Max Ssidrefs  = 5.
-Max ConfSets  = 2.
-Ssidrefs Off  = 10.
-Conflicts Off = 74.
-Runing T. Off = 9c.
-C. Agg. Off   = b0.
-
-SSID To CHWALL-Type matrix:
-
-   ssidref 0:  01 00 00 00 00 00 00 00 00 00  <<< type0 is set for ssidref0
-   ssidref 1:  00 01 00 00 00 00 00 00 00 00 
-   ssidref 2:  00 00 01 00 00 00 00 00 00 00 
-   ssidref 3:  00 00 00 01 00 00 00 00 00 00 
-   ssidref 4:  00 00 00 00 01 00 00 00 00 00  <<< type4 is set for ssidref4
-                                              <<< types 5-9 are unused
-Confict Sets:
-
-   c-set 0:    00 00 01 01 00 00 00 00 00 00  <<< type2 and type3 never run 
together
-   c-set 1:    01 00 00 00 00 01 01 00 00 00  <<< only one of types 0, 5 or 6 
-                                              <<<   can run simultaneously
-Running
-Types:         01 00 00 00 00 00 00 00 00 00  <<< ref-count for types of 
running domains
-
-Conflict
-Aggregate Set: 00 00 00 00 00 01 01 00 00 00  <<< aggregated set of types that 
                 
-                                              <<< cannot run because they 
-                                              <<< are in conflict set 1 and
-                                              <<< (domain 0 is running w t0)
-                                             
-
-Simple Type Enforcement policy:
-===============================
-Max Types     = 5.
-Max Ssidrefs  = 5.
-Ssidrefs Off  = 8.
-
-SSID To STE-Type matrix:
-
-   ssidref 0: 01 01 01 01 01                  <<< ssidref0 points to a set 
that                  
-                                              <<< has all types set (colors)
-   ssidref 1: 00 01 00 00 00                  <<< ssidref1 has color1 set
-   ssidref 2: 00 00 01 00 00                  <<< ...
-   ssidref 3: 00 00 00 01 00 
-   ssidref 4: 00 00 00 00 01 
-
-
-Policy dump End.
-
-
-This is a small example policy with which we will demonstrate the enforcement.
-
-Starting Domains with policy enforcement
-========================================
-Now let us play with this policy. 
-
-Define 3 or 4 domain configurations. I use the following config using a 
ramdisk 
-only and about 8MBytes of memory for each DomU (test purposes):
-
-#-------configuration xmsec1-------------------------
-kernel = "/boot/vmlinuz-2.6.11-xenU"
-ramdisk="/boot/U1_ramdisk.img"
-#security reference identifier
-ssidref= 0x00010001
-memory = 10
-name = "xmsec1"
-cpu = -1   # leave to Xen to pick
-# Number of network interfaces. Default is 1.
-nics=1
-dhcp="dhcp"
-#-----------------------------------------------------
-
-xmsec2 and xmsec3 look the same except for the name and the ssidref line. Use 
-your domain config file and add "ssidref = 0x00010001" to the first (xmsec1),  
-"ssidref= 0x00020002" to the second (call it xmsec2), and "ssidref=0x00030003" 
 
-to the third (we will call this one xmsec3).
-
-First start xmsec1: xm create -c xmsec1 (succeeds)
-
-Then
-[root@laptop policy]# xm list 
-Name              Id  Mem(MB)  CPU  State  Time(s)  Console  
-Domain-0           0      620   0  r----     42.3            s:00/p:00
-xmnosec            1        9   0  -b---      0.3    9601    s:00/p:05
-xmsec1             2        9   0  -b---      0.2    9602    s:01/p:01
-
-Shows a new domain xmsec1 running with primary (here: chinese wall) ssidref 1 
-and secondary (here: simple type enforcement) ssidref 1. The ssidrefs are  
-independent and can differ for a domain.
-
-[root@laptop policy]# ./policy_tool getpolicy
-
-Policy dump:
-============
-Magic     = 1debc.
-PolVer    = aaaa0000.
-Len       = 112.
-Primary   = CHINESE WALL policy (c=1, off=14).
-Secondary = SIMPLE TYPE ENFORCEMENT policy (c=2, off=d8).
-
-
-Chinese Wall policy:
-====================
-Max Types     = a.
-Max Ssidrefs  = 5.
-Max ConfSets  = 2.
-Ssidrefs Off  = 10.
-Conflicts Off = 74.
-Runing T. Off = 9c.
-C. Agg. Off   = b0.
-
-SSID To CHWALL-Type matrix:
-
-   ssidref 0:  01 00 00 00 00 00 00 00 00 00
-   ssidref 1:  00 01 00 00 00 00 00 00 00 00
-   ssidref 2:  00 00 01 00 00 00 00 00 00 00
-   ssidref 3:  00 00 00 01 00 00 00 00 00 00
-   ssidref 4:  00 00 00 00 01 00 00 00 00 00
-
-Confict Sets:
-
-   c-set 0:    00 00 01 01 00 00 00 00 00 00
-   c-set 1:    01 00 00 00 00 01 01 00 00 00   <<< t1 is not part of any c-set
-
-Running
-Types:         01 01 00 00 00 00 00 00 00 00   <<< xmsec1 has ssidref 1->type1
-                  ^^                           <<< ref-count at position 1 incr
-Conflict
-Aggregate Set: 00 00 00 00 00 01 01 00 00 00   <<< domain 1 was allowed to     
  
-                                               <<< start since type 1 was not
-                                               <<< in conflict with running 
-                                               <<< types
-                                            
-Simple Type Enforcement policy:
-===============================
-Max Types     = 5.
-Max Ssidrefs  = 5.
-Ssidrefs Off  = 8.
-
-SSID To STE-Type matrix:
-
-   ssidref 0: 01 01 01 01 01           <<< the ste policy does not maintain; we
-   ssidref 1: 00 01 00 00 00   <--     <<< see that domain xmsec1 has ste 
-   ssidref 2: 00 00 01 00 00           <<< ssidref1->type1 and has this type in
-   ssidref 3: 00 00 00 01 00           <<< common with dom0
-   ssidref 4: 00 00 00 00 01
-
-
-Policy dump End.
-
-Look at sHype output in xen dmesg:
-
-[root@laptop xen]# xm dmesg
-.
-.
-[somewhere near the very end]
-(XEN) chwall_init_domain_ssid: determined chwall_ssidref to 1.
-(XEN) ste_init_domain_ssid.
-(XEN) ste_init_domain_ssid: determined ste_ssidref to 1.
-(XEN) acm_init_domain_ssid: Instantiated individual ssid for domain 0x01.
-(XEN) chwall_post_domain_create.
-(XEN) ste_pre_eventchannel_interdomain.
-(XEN) ste_pre_eventchannel_interdomain: (evtchn 0 --> 1) common type #01.
-(XEN) shype_authorize_domops.
-(XEN) ste_pre_eventchannel_interdomain.
-(XEN) ste_pre_eventchannel_interdomain: (evtchn 0 --> 1) common type #01.
-(XEN) ste_pre_eventchannel_interdomain.
-(XEN) ste_pre_eventchannel_interdomain: (evtchn 0 --> 1) common type #01.
-
-
-You can see that the chinese wall policy does not complain and that the ste 
-policy makes three access control decisions for three event-channels setup 
-between domain 0 and the new domain 1. Each time, the two domains share the 
-type1 and setting up the eventchannel is permitted.
-
-
-Starting up a second domain xmsec2:
-
-[root@laptop xen]# xm create -c xmsec2
-Using config file "xmsec2".
-Started domain xmsec2, console on port 9602
-************ REMOTE CONSOLE: CTRL-] TO QUIT ********
-Linux version 2.6.11-xenU (root@xxxxxxxxxxxxxxx) (gcc version 3.4.2 20041017 
-(Red Hat 3.4.2-6.fc3)) #1 Wed Mar 30 13:14:31 EST 2005
-.
-.
-.
-[root@laptop policy]# xm list
-Name              Id  Mem(MB)  CPU  State  Time(s)  Console  
-Domain-0           0      620   0  r----     71.7            s:00/p:00
-xmsec1             1        9   0  -b---      0.3    9601    s:01/p:01
-xmsec2             2        7   0  -b---      0.3    9602    s:02/p:02   << 
our domain runs both policies with ssidref 2
-
-
-[root@laptop policy]# ./policy_tool getpolicy
-
-Policy dump:
-============
-Magic     = 1debc.
-PolVer    = aaaa0000.
-Len       = 112.
-Primary   = CHINESE WALL policy (c=1, off=14).
-Secondary = SIMPLE TYPE ENFORCEMENT policy (c=2, off=d8).
-
-
-Chinese Wall policy:
-====================
-Max Types     = a.
-Max Ssidrefs  = 5.
-Max ConfSets  = 2.
-Ssidrefs Off  = 10.
-Conflicts Off = 74.
-Runing T. Off = 9c.
-C. Agg. Off   = b0.
-
-SSID To CHWALL-Type matrix:
-
-   ssidref 0:  01 00 00 00 00 00 00 00 00 00
-   ssidref 1:  00 01 00 00 00 00 00 00 00 00
-   ssidref 2:  00 00 01 00 00 00 00 00 00 00   <<< our domain has type 2 set
-   ssidref 3:  00 00 00 01 00 00 00 00 00 00
-   ssidref 4:  00 00 00 00 01 00 00 00 00 00
-
-Confict Sets:
-
-   c-set 0:    00 00 01 01 00 00 00 00 00 00   <<< t2 is in c-set0 with type 3
-   c-set 1:    01 00 00 00 00 01 01 00 00 00
-
-Running
-Types:         01 01 01 00 00 00 00 00 00 00   <<< t2 is running since the 
-                     ^^                        <<< current aggregate conflict
-                                               <<< set (see above) does not 
-                                               <<< include type 2
-Conflict
-Aggregate Set: 00 00 00 01 00 01 01 00 00 00   <<< type 3 is added to the 
-                                               <<< conflict aggregate
-
-
-Simple Type Enforcement policy:
-===============================
-Max Types     = 5.
-Max Ssidrefs  = 5.
-Ssidrefs Off  = 8.
-
-SSID To STE-Type matrix:
-
-   ssidref 0: 01 01 01 01 01
-   ssidref 1: 00 01 00 00 00
-   ssidref 2: 00 00 01 00 00
-   ssidref 3: 00 00 00 01 00
-   ssidref 4: 00 00 00 00 01
-
-
-Policy dump End.
-
-
-The sHype xen dmesg output looks similar to the one above when starting the 
-first domain.
-
-Now we start xmsec3 and it has ssidref3. Thus, it tries to run as type3 which 
-conflicts with running type2 (from xmsec2). As expected, creating this domain 
-fails for security policy enforcement reasons.
-
-[root@laptop xen]# xm create -c xmsec3
-Using config file "xmsec3".
-Error: Error creating domain: (22, 'Invalid argument')
-[root@laptop xen]#
-
-[root@laptop xen]# xm dmesg
-.
-.
-[somewhere near the very end]
-(XEN) chwall_pre_domain_create.
-(XEN) chwall_pre_domain_create: CHINESE WALL CONFLICT in type 03.
-
-xmsec3 ssidref3 points to type3, which is in the current conflict aggregate 
-set. This domain cannot start until domain xmsec2 is destroyed, at which time 
-the aggregate conflict set is reduced and type3 is excluded from it. Then, 
-xmsec3 can start. Of course, afterwards, xmsec2 cannot be restarted. Try it.
-
-3. Policy tool
-**************
-toos/policy/policy_tool.c
-
-a) ./policy_tool getpolicy
-      prints the currently enforced policy
-      (see for example section 1.)
-
-b) ./policy_tool setpolicy
-      sets a predefined and hardcoded security
-      policy (the one described in section 2.)
-
-c) ./policy_tool dumpstats
-      prints some status information about the caching
-      of access control decisions (number of cache hits
-      and number of policy evaluations for grant_table
-      and event channels).
-
-d) ./policy_tool loadpolicy <binary_policy_file>
-      sets the policy defined in the <binary_policy_file>
-      please use the policy_processor that is posted to this
-      mailing list to create such a binary policy from an XML
-      policy description
-
-4. Policy interface:
-********************
-The Policy interface is working in "network-byte-order" (big endian). The 
reason for this
-is that policy files/management should be portable and independent of the 
platforms.
-
-Our policy interface enables managers to create a single binary policy file in 
a trusted
-environment and distributed it to multiple systems for enforcement.
-
-5. Booting with a binary policy:
-********************************
-The grub configuration file can be adapted to boot the hypervisor with an
-already active policy. To do this, a binary policy file - this can be
-the same file as used by the policy_tool - should be placed into the boot
-partition. The following entry from the grub configuration file shows how
-a binary policy can be added to the system during boot time. Note that the 
-binary policy must be of the same type that the hypervisor was compiled 
-for. The policy module line should also only be added as the last module
-line if XEN was compiled with the access control module (ACM).
-
-title XEN0 3.0 Devel
-       kernel /xen.gz dom0_mem=400000
-       module /vmlinuz-2.6.12-xen0 root=/dev/hda2 ro console=tty0
-       module /initrd-2.6.12-xen0.img
-       module /xen_sample_policy.bin
-
-
-====================end-of file=======================================
diff -r 99914b54f7bf -r 81576d3d1ca8 
linux-2.6-xen-sparse/drivers/xen/blkback/control.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/control.c        Thu Aug 18 
18:40:02 2005
+++ /dev/null   Fri Aug 19 18:19:28 2005
@@ -1,61 +0,0 @@
-/******************************************************************************
- * arch/xen/drivers/blkif/backend/control.c
- * 
- * Routines for interfacing with the control plane.
- * 
- * Copyright (c) 2004, Keir Fraser
- */
-
-#include "common.h"
-
-static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
-{
-    DPRINTK("Received blkif backend message, subtype=%d\n", msg->subtype);
-    
-    switch ( msg->subtype )
-    {
-    case CMSG_BLKIF_BE_CREATE:
-        blkif_create((blkif_be_create_t *)&msg->msg[0]);
-        break;        
-    case CMSG_BLKIF_BE_DESTROY:
-        blkif_destroy((blkif_be_destroy_t *)&msg->msg[0]);
-        break;        
-    case CMSG_BLKIF_BE_CONNECT:
-        blkif_connect((blkif_be_connect_t *)&msg->msg[0]);
-        break;        
-    case CMSG_BLKIF_BE_DISCONNECT:
-        if ( !blkif_disconnect((blkif_be_disconnect_t *)&msg->msg[0],msg->id) )
-            return; /* Sending the response is deferred until later. */
-        break;        
-    case CMSG_BLKIF_BE_VBD_CREATE:
-        vbd_create((blkif_be_vbd_create_t *)&msg->msg[0]);
-        break;
-    case CMSG_BLKIF_BE_VBD_DESTROY:
-        vbd_destroy((blkif_be_vbd_destroy_t *)&msg->msg[0]);
-        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 blkif_ctrlif_init(void)
-{
-    ctrl_msg_t cmsg;
-    blkif_be_driver_status_t st;
-
-    (void)ctrl_if_register_receiver(CMSG_BLKIF_BE, blkif_ctrlif_rx, 
-                                    CALLBACK_IN_BLOCKING_CONTEXT);
-
-    /* Send a driver-UP notification to the domain controller. */
-    cmsg.type      = CMSG_BLKIF_BE;
-    cmsg.subtype   = CMSG_BLKIF_BE_DRIVER_STATUS;
-    cmsg.length    = sizeof(blkif_be_driver_status_t);
-    st.status      = BLKIF_DRIVER_STATUS_UP;
-    memcpy(cmsg.msg, &st, sizeof(st));
-    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
-}
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/misc/policyprocessor/Makefile
--- a/tools/misc/policyprocessor/Makefile       Thu Aug 18 18:40:02 2005
+++ /dev/null   Fri Aug 19 18:19:28 2005
@@ -1,42 +0,0 @@
-XEN_ROOT = ../../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-CFLAGS   += -static
-CFLAGS   += -Wall
-CFLAGS   += -Werror
-CFLAGS   += -O3
-CFLAGS   += -fno-strict-aliasing
-CFLAGS   += -I.
-
-all: build
-
-build: mk-symlinks
-       $(MAKE) xml_to_bin
-
-default: all
-
-install: all
-
-xml_to_bin : make_include XmlToBin.java XmlToBinInterface.java SsidsEntry.java 
SecurityLabel.java myHandler.java
-       javac XmlToBin.java
-
-make_include : c2j_include
-       ./c2j_include
-
-c2j_include: c2j_include.c
-       $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
-
-clean:
-       rm -rf *.class xen c2j_include policy_version.java *.bin
-
-
-LINUX_ROOT := $(XEN_ROOT)/linux-2.6-xen-sparse
-mk-symlinks:
-       [ -e xen/linux ] || mkdir -p xen/linux
-       [ -e xen/io ]    || mkdir -p xen/io
-       ( cd xen >/dev/null ; \
-         ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
-       ( cd xen/io >/dev/null ; \
-         ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
-       ( cd xen/linux >/dev/null ; \
-         ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . )
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/misc/policyprocessor/SecurityLabel.java
--- a/tools/misc/policyprocessor/SecurityLabel.java     Thu Aug 18 18:40:02 2005
+++ /dev/null   Fri Aug 19 18:19:28 2005
@@ -1,34 +0,0 @@
-/**
- * (C) Copyright IBM Corp. 2005
- *
- * $Id: SecurityLabel.java,v 1.2 2005/06/17 20:00:04 rvaldez Exp $
- *
- * Author: Ray Valdez
- *
- * 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, version 2 of the
- * License.
- *
- * SecurityLabel Class.  
- *
- * <p>
- *
- * Keeps track of types.
- *
- * <p>
- *
- *
- */
-import java.util.*;
-public class SecurityLabel
-{
- Vector ids;
- Vector vlans;
- Vector slots;
- Vector steTypes;
- int steSsidPosition;
- Vector chwIDs;
- Vector chwTypes;
- int chwSsidPosition;
-}
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/misc/policyprocessor/SecurityPolicySpec.xsd
--- a/tools/misc/policyprocessor/SecurityPolicySpec.xsd Thu Aug 18 18:40:02 2005
+++ /dev/null   Fri Aug 19 18:19:28 2005
@@ -1,115 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Author: Ray Valdez, rvaldez@xxxxxxxxxx -->
-<!-- xml schema definition for xen xml policies -->
-<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema";
-targetNamespace="http://www.ibm.com";
-xmlns="http://www.ibm.com"; 
-elementFormDefault="qualified">
-
-<xsd:element name="TE" type="xsd:string" />
-<xsd:element name="ChWall" type="xsd:string" />
-
-<xsd:element name="Definition">
-  <xsd:complexType>
-       <xsd:sequence>
-
-         <!-- simple type enforcement -->
-         <xsd:element name="Types" minOccurs ="0" maxOccurs="1">
-               <xsd:complexType>
-                 <xsd:sequence>
-                       <xsd:element ref="TE" minOccurs ="1" maxOccurs 
="unbounded"/>
-                 </xsd:sequence>
-               </xsd:complexType>
-         </xsd:element>
-
-         <!-- chinese wall -->
-         <!--   type definition -->
-         <xsd:element name="ChWallTypes" minOccurs ="0" maxOccurs="1">
-               <xsd:complexType>
-                 <xsd:sequence>
-                       <xsd:element ref="ChWall"  minOccurs ="1" maxOccurs 
="unbounded"/>
-
-               </xsd:sequence>
-          </xsd:complexType>
-       </xsd:element>
-
-       <!--   conflict set -->
-         <xsd:element name="ConflictSet" minOccurs ="0" maxOccurs="unbounded">
-               <xsd:complexType>
-                 <xsd:sequence>
-                       <xsd:element ref="ChWall"  minOccurs ="2" maxOccurs 
="unbounded"/>
-                 </xsd:sequence>
-               </xsd:complexType>
-       </xsd:element>
-
-       </xsd:sequence>
-  </xsd:complexType>
-</xsd:element>
-
-<xsd:element name="Policy">
-    <xsd:complexType>
-      <xsd:sequence>
-
-       <xsd:element name="PolicyHeader">
-       <xsd:complexType>
-          <xsd:all>
-               <xsd:element name = "Name" type="xsd:string"/>
-               <xsd:element name = "DateTime" type="xsd:dateTime"/>
-               <xsd:element name = "Tag" minOccurs ="1" maxOccurs ="1" 
type="xsd:string"/>
-               <xsd:element name = "TypeDefinition">
-               <xsd:complexType>
-                 <xsd:all>
-                       <xsd:element name = "url" type="xsd:string"/>
-                       <xsd:element name = "hash" minOccurs ="0" maxOccurs 
="1" type="xsd:string"/>
-                 </xsd:all>
-               </xsd:complexType>
-               </xsd:element>
-
-          </xsd:all>
-       </xsd:complexType>
-       </xsd:element>
-
-       <xsd:element name="VM" minOccurs ="1" maxOccurs="unbounded">
-         <xsd:complexType>
-          <xsd:sequence>
-               <xsd:element name="id" type="xsd:integer"/>
-               <xsd:element ref="TE" minOccurs="0" maxOccurs="unbounded" />
-               <xsd:element ref="ChWall" minOccurs ="0" maxOccurs="unbounded"/>
-          </xsd:sequence>
-         </xsd:complexType>
-       </xsd:element>
-
-       <xsd:element name="Vlan" minOccurs ="0" maxOccurs="unbounded">
-         <xsd:complexType>
-          <xsd:sequence>
-               <xsd:element name="vid" type="xsd:integer"/>
-               <xsd:element ref="TE" minOccurs="1" maxOccurs="unbounded" />
-          </xsd:sequence>
-         </xsd:complexType>
-       </xsd:element>
-
-       <xsd:element name="Slot" minOccurs ="0" maxOccurs="unbounded">
-         <xsd:complexType>
-          <xsd:sequence>
-               <xsd:element name="bus" type="xsd:integer"/>
-               <xsd:element name="slot" type="xsd:integer"/>
-               <xsd:element ref="TE" minOccurs="1" maxOccurs="unbounded" />
-          </xsd:sequence>
-         </xsd:complexType>
-       </xsd:element>
-
-
-      </xsd:sequence>
-    </xsd:complexType>
-</xsd:element>
-
-<!-- root element -->
-<xsd:element name="SecurityPolicySpec">
-    <xsd:complexType>
-      <xsd:choice>
-               <xsd:element ref="Definition" minOccurs ="1" 
maxOccurs="unbounded"/>
-               <xsd:element ref="Policy" minOccurs ="1" maxOccurs="unbounded"/>
-      </xsd:choice>
-    </xsd:complexType>
-</xsd:element>
-</xsd:schema>
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/misc/policyprocessor/SsidsEntry.java
--- a/tools/misc/policyprocessor/SsidsEntry.java        Thu Aug 18 18:40:02 2005
+++ /dev/null   Fri Aug 19 18:19:28 2005
@@ -1,29 +0,0 @@
-/**
- * (C) Copyright IBM Corp. 2005
- *
- * $Id: SsidsEntry.java,v 1.2 2005/06/17 20:02:40 rvaldez Exp $
- *
- * Author: Ray Valdez
- * 
- * 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, version 2 of the
- * License.
- *
- * SsidsEntry Class.  
- * <p>
- *
- * Holds ssid information.
- *
- * <p>
- *
- *
- */
-public class SsidsEntry 
- {
-  int id;      /* used for partition and vlan */
-  int bus;     /* used for slots */
-  int slot;
-  int ste = 0xffffffff;
-  int chw = 0xffffffff;
- }
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/misc/policyprocessor/XmlToBin.java
--- a/tools/misc/policyprocessor/XmlToBin.java  Thu Aug 18 18:40:02 2005
+++ /dev/null   Fri Aug 19 18:19:28 2005
@@ -1,1570 +0,0 @@
-/**
- * (C) Copyright IBM Corp. 2005
- *
- * $Id: XmlToBin.java,v 1.3 2005/06/20 21:07:37 rvaldez Exp $
- *
- * Author: Ray Valdez
- *
- * Contributors:
- *         Reiner Sailer - adjust type-lengths
- *
- * 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, version 2 of the
- * License.
- *
- * XmlToBin  Class.  
- * <p>
- *
- * Translates a xml representation of a SHYPE policy into a binary  
- * format.  The class processes an xml policy file based on elment tags 
- * defined in a schema definition files: SecurityPolicySpec.xsd.
- *
- * XmlToBin Command line Options: 
- *
- *      -i              inputFile:      name of policyfile (.xml)
- *      -o              outputFile:     name of binary policy file (Big Endian)
- *      -xssid          SsidFile:       xen ssids to types text file
- *      -xssidconf      SsidConf:      xen conflict ssids to types text file
- *      -debug                          turn on debug messages
- *      -help                           help. This printout
- *
- * <p>
- *
- *
- */
-import java.util.*;
-import java.io.*;
-import java.io.IOException;
-import java.io.FileNotFoundException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.Attr;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.NamedNodeMap;
-import org.xml.sax.*;
-import javax.xml.parsers.*;
-import org.xml.sax.helpers.*;
-
-public class XmlToBin 
- implements XmlToBinInterface
-{
-  class SlotInfo {
-       String bus;
-       String slot;
-  }
-
- boolean LittleEndian = false;
- boolean debug = false;
-
- static final String JAXP_SCHEMA_LANGUAGE = 
"http://java.sun.com/xml/jaxp/properties/schemaLanguage";;
-
- static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";;
-
- public static void printUsage()
- {
-  System.out.println("XmlToBin Command line Options: ");
-  System.out.println("\t-i\t\tinputFile:\tname of policyfile (.xml)");
-  System.out.println("\t-o\t\toutputFile:\tname of binary policy file (Big 
Endian)");
-  System.out.println("\t-xssid\t\tSsidFile:\tXen ssids to named types text 
file");
-  System.out.println("\t-xssidconf\tSsidConfFile:\tXen conflict ssids to named 
types text file");
-  System.out.println("\t-debug\t\t\t\tturn on debug messages");
-  System.out.println("\t-help\t\t\t\thelp. This printout");
-  return;
- }
-
- public void printDebug(String message) 
- {
-  if (debug)
-    System.out.println(message);
- }
-
- public void writeBinPolicy(byte[] binPolicy, String outputFileName)
-  throws Exception
- {
-    if (debug) 
-       printHex(binPolicy,binPolicy.length);
-
-    DataOutputStream writeObj = new DataOutputStream(
-                                new FileOutputStream(outputFileName));
-
-    writeObj.write(binPolicy);
-    writeObj.flush();
-    writeObj.close();
-    System.out.println(" wBP:: wrote outputfile: " + outputFileName);
-
-    return; 
- }  
-
- public void writeXenTypeVectorFile(Vector list, String outputFileName)
-  throws Exception
- {
-  PrintWriter out;
-
-  if (0 == list.size())
-  {
-       printDebug(" wSTF : size of input is zero when writing :" + 
outputFileName); 
-       return;
-  }
- out = new PrintWriter(
-               new BufferedWriter(
-                      new FileWriter(outputFileName)));
-
-
-  for (int i = 0; i < list.size(); i++)
-  {
-       Vector  ee = (Vector) list.elementAt(i);
-       out.println(i + " " +ee.toString());
-  } 
-    out.close();
-   
-    return; 
- }
-
- public void writeXenTypeFile(Vector list, String outputFileName, boolean 
slabel)
-  throws Exception
- {
-  Vector entry; 
-  String strTypes = "";
-  SecurityLabel ee;
-  PrintWriter out;
-
-  if (0 == list.size())
-  {
-       printDebug(" wSTF : size of input is zero when writing :" + 
outputFileName); 
-       return;
-  }
-  out = new PrintWriter(
-               new BufferedWriter(
-                      new FileWriter(outputFileName)));
-
-  for (int i = 0; i < list.size(); i++)
-  {
-       ee = (SecurityLabel) list.elementAt(i);
-
-       if (slabel)
-       {
-               entry = ee.steTypes; 
-       } else {
-
-               entry = ee.chwTypes; 
-       }
-       if (null == entry) continue;
-
-       Enumeration e = entry.elements(); 
-       while (e.hasMoreElements())
-       {
-         String typeName = (String) e.nextElement(); 
-         strTypes = strTypes + " " + typeName;
-        }
-         printDebug(" WXTF:: ssid : "+i +" :"+strTypes); 
-         out.println(i +" "+strTypes);
-         strTypes = "";
-  } 
-  out.close();
-   
-  return; 
- }
-
- public void setDebug(boolean value)
- {
-  debug=value;
- }
-
- public void setEndian(boolean value)
- {
-  LittleEndian = value;
- }
-
- public byte[] generateVlanSsids(Vector bagOfSsids)
-  throws Exception
- {
-  /**
-        typedef struct {
-        u16 vlan;
-        u16 ssid_ste;
-        } acm_vlan_entry_t;
-  **/
-
-  Hashtable  vlanSsid = new Hashtable();
-  printDebug(" gVS::Size of bagOfSsids: "+ bagOfSsids.size());
-
-  /* Get the number of partitions */
-  for (int i = 0; i < bagOfSsids.size(); i++)
-  {
-       SecurityLabel entry = (SecurityLabel) bagOfSsids.elementAt(i);
-
-       if (null == entry.vlans)
-         continue;
-
-       Enumeration e = entry.vlans.elements(); 
-       while (e.hasMoreElements())
-       {
-         String id = (String) e.nextElement(); 
-         printDebug(" gVS:: vlan: " + id + "has ste ssid: " + 
entry.steSsidPosition);
-         if (-1 == entry.steSsidPosition)
-               continue;  
-
-         /* Only use ste for vlan */
-         SsidsEntry  ssidsObj = new SsidsEntry();
-
-         ssidsObj.id = Integer.parseInt(id); 
-         ssidsObj.ste = entry.steSsidPosition;
-
-         if (vlanSsid.contains(id))
-               printDebug(" gVS:: Error already in the Hash part:" + 
ssidsObj.id);
-         else 
-               vlanSsid.put(id, ssidsObj);
-               printDebug(" gVS:: added part: " + id + "has ste ssid: " + 
entry.steSsidPosition);
-       }
-  }
-
-  /* allocate array */ 
-  int numOfVlan = vlanSsid.size();
-  int totalSize = (numOfVlan * vlanEntrySz);  
-
-  if (0 == numOfVlan) 
-  {
-       printDebug(" gVS:: vlan: binary ==> zero");
-        return new byte[0];
-  }
-
-  byte[] vlanArray = new byte[totalSize];
-
-  int index = 0;
-
-  Enumeration e = vlanSsid.elements(); 
-  while (e.hasMoreElements())
-  {
-       SsidsEntry entry = (SsidsEntry) e.nextElement(); 
-       printDebug(" gVS:: part: " + entry.id + " ste ssid: " + entry.ste);
-
-       /* Write id */
-       writeShortToStream(vlanArray,(short)entry.id,index);
-       index = index + u16Size;
-
-       /* write ste ssid */
-       writeShortToStream(vlanArray,(short) entry.ste,index);
-       index = index + u16Size;
-  }
-
-  printDebug(" gVS:: vlan: num of vlans  " + numOfVlan);
-  printDebug(" gVS:: vlan: binary ==> Length "+ vlanArray.length);
-
-  if (debug) 
-       printHex(vlanArray,vlanArray.length);
-  printDebug("\n");
-
-  return vlanArray; 
- }  
-
- public byte[] generateSlotSsids(Vector bagOfSsids)
-  throws Exception
- {
-  /**
-        typedef struct {
-        u16 slot_max;
-        u16 slot_offset;
-        } acm_slot_buffer_t;
-
-        typedef struct {
-        u16 bus;
-        u16 slot;
-        u16 ssid_ste;
-        } acm_slot_entry_t;
-  **/
-  Hashtable  slotSsid = new Hashtable();
-  printDebug(" gSS::Size of bagOfSsids: "+ bagOfSsids.size());
-
-  /* Find the number of VMs */ 
-  for (int i = 0; i < bagOfSsids.size(); i++)
-  {
-       SecurityLabel entry = (SecurityLabel) bagOfSsids.elementAt(i);
-
-       if (null == entry.slots)
-         continue;
-
-       Enumeration e = entry.slots.elements(); 
-       while (e.hasMoreElements())
-       {
-         SlotInfo item = (SlotInfo) e.nextElement(); 
-         printDebug(" gSS:: bus slot: " + item.bus + " "+ item.slot + " " +  
entry.steSsidPosition);
-         if (-1 == entry.steSsidPosition)
-               continue;  
-
-         SsidsEntry  ssidsObj = new SsidsEntry();
-
-         String id = item.bus +" "+item.slot;
-         ssidsObj.bus = Integer.parseInt(item.bus); 
-         ssidsObj.slot = Integer.parseInt(item.slot); 
-         /* set ste ssid */
-         ssidsObj.ste = entry.steSsidPosition;
-
-         if (slotSsid.contains(id))
-               printDebug(" gSS:: Error already in the Hash part:" + id);
-         else 
-               slotSsid.put(id, ssidsObj);
-
-               printDebug(" gSS:: added slot: " + id + "has ste ssid: " + 
entry.steSsidPosition);
-       }
-  }
-
-  /* allocate array */
-  int numOfSlot = slotSsid.size();
-
-  if (0 == numOfSlot) 
-  {
-       printDebug(" gVS:: slot: binary ==> zero");
-        return new byte[0];
-  }
-
-  int totalSize = (numOfSlot * slotEntrySz);  
-
-  byte[] slotArray = new byte[totalSize];
-
-  int index = 0;
-
-  Enumeration e = slotSsid.elements(); 
-  while (e.hasMoreElements())
-  {
-       SsidsEntry entry = (SsidsEntry) e.nextElement(); 
-       System.out.println(" gSS:: bus slot: " + entry.bus + " " + entry.slot + 
" ste ssid: " + entry.ste);
-
-       /* Write bus */
-       writeShortToStream(slotArray,(short)entry.bus,index);
-       index = index + u16Size;
-
-       /* Write slot */ 
-       writeShortToStream(slotArray,(short)entry.slot,index);
-       index = index + u16Size;
-
-       /* Write ste ssid */
-       writeShortToStream(slotArray,(short) entry.ste,index);
-       index = index + u16Size;
-
-  }
-   
-  printDebug(" gSS:: slot: num of vlans  " + numOfSlot);
-  printDebug(" gSS:: slot: binary ==> Length "+ slotArray.length);
-
-  if (debug) 
-        printHex(slotArray,slotArray.length);
-  printDebug("\n");
-
-  return slotArray; 
-
- }  
-
- public byte[] generatePartSsids(Vector bagOfSsids, Vector bagOfChwSsids)
-  throws Exception
- {
-  /**
-        typedef struct {
-        u16 id;
-        u16 ssid_ste;
-        u16 ssid_chwall;
-        } acm_partition_entry_t;
-
-  **/
-  Hashtable  partSsid = new Hashtable();
-  printDebug(" gPS::Size of bagOfSsids: "+ bagOfSsids.size());
-
-  /* Find the number of VMs */ 
-  for (int i = 0; i < bagOfSsids.size(); i++)
-  {
-       SecurityLabel entry = (SecurityLabel) bagOfSsids.elementAt(i);
-
-       if (null == entry.ids)
-         continue;
-
-       Enumeration e = entry.ids.elements(); 
-       while (e.hasMoreElements())
-       {
-         String id = (String) e.nextElement(); 
-         printDebug(" gPS:: part: " + id + "has ste ssid: " + 
entry.steSsidPosition);
-         if (-1 == entry.steSsidPosition)
-               continue;  
-
-         SsidsEntry  ssidsObj = new SsidsEntry();
-
-         ssidsObj.id = Integer.parseInt(id); 
-         ssidsObj.ste = entry.steSsidPosition;
-
-         if (partSsid.contains(id))
-               printDebug(" gPS:: Error already in the Hash part:" + 
ssidsObj.id);
-         else 
-               partSsid.put(id, ssidsObj);
-               printDebug(" gPS:: added part: " + id + "has ste ssid: " + 
entry.steSsidPosition);
-       }
-
-  }
-
-  for (int i = 0; i < bagOfChwSsids.size(); i++)
-  {
-       SecurityLabel entry = (SecurityLabel) bagOfChwSsids.elementAt(i);
-
-       Enumeration e = entry.chwIDs.elements(); 
-       while (e.hasMoreElements())
-       {
-         String id = (String) e.nextElement(); 
-         printDebug(" gPS:: part: " + id + "has chw ssid: " + 
entry.chwSsidPosition);
-         if (partSsid.containsKey(id))
-         {
-               SsidsEntry item = (SsidsEntry) partSsid.get(id);
-               item.chw = entry.chwSsidPosition;
-               printDebug(" gPS:: added :" + item.id +" chw: " + item.chw);
-         }
-         else 
-         {
-               printDebug(" gPS:: creating :" + id +" chw: " + 
entry.chwSsidPosition);
-               SsidsEntry  ssidsObj = new SsidsEntry();
-               ssidsObj.id = Integer.parseInt(id); 
-               ssidsObj.chw = entry.chwSsidPosition;
-               partSsid.put(id, ssidsObj);
-
-         }
-       }
-  }      
-
-  /* Allocate array */
-  int numOfPar = partSsid.size();
-  int totalSize =  (numOfPar * partitionEntrySz);  
-
-  if (0 == numOfPar) 
-  {
-       printDebug(" gPS:: part: binary ==> zero");
-        return new byte[0];
-  }
-
-  byte[] partArray = new byte[totalSize];
-
-  int index = 0;
-
-  Enumeration e = partSsid.elements(); 
-  while (e.hasMoreElements())
-  {
-       SsidsEntry entry = (SsidsEntry) e.nextElement(); 
-       printDebug(" gPS:: part: " + entry.id + " ste ssid: " + entry.ste + " 
chw ssid: "+ entry.chw);
-
-       /* Write id */
-       writeShortToStream(partArray,(short)entry.id,index);
-       index = index + u16Size;
-
-       /* Write ste ssid */
-       writeShortToStream(partArray,(short) entry.ste,index);
-       index = index + u16Size;
-
-       /* Write chw ssid */
-       writeShortToStream(partArray,(short) entry.chw,index);
-       index = index + u16Size;
-  }
-
-  printDebug(" gPS:: part: num of partitions  " + numOfPar);
-  printDebug(" gPS:: part: binary ==> Length " + partArray.length);
-
-  if (debug) 
-       printHex(partArray,partArray.length);
-  printDebug("\n");
-   
-   return partArray; 
- }
-
- public  byte[] GenBinaryPolicyBuffer(byte[] chwPolicy, byte[] stePolicy, byte 
[] partMap, byte[] vlanMap, byte[] slotMap)
- {
-  byte[] binBuffer;
-  short chwSize =0;
-  short steSize =0;
-  int  index = 0;
-
-  /* Builds data structure acm_policy_buffer_t */
-  /* Get number of colorTypes */
-  if (null != chwPolicy)
-       chwSize = (short) chwPolicy.length;
-
-  if (null != stePolicy)
-       steSize = (short) stePolicy.length;
-
-  int totalDataSize = chwSize + steSize + resourceOffsetSz +  3 *(2 * u16Size);
-
-  /*  Add vlan and slot */ 
-  totalDataSize = totalDataSize +partMap.length + vlanMap.length + 
slotMap.length; 
-  binBuffer = new byte[binaryBufferHeaderSz +totalDataSize];
-       
-
-  try {
-         index = 0;
-         /* fill in General Policy Version */
-         writeIntToStream(binBuffer, ACM_POLICY_VERSION, index);
-         index += u32Size;
-
-         /* Write magic */
-         writeIntToStream(binBuffer, ACM_MAGIC, index);
-         index += u32Size;
-
-         /* write len */
-         writeIntToStream(binBuffer, binBuffer.length, index);
-         index += u32Size;
-
-  } catch (IOException ee) {
-         System.out.println(" GBPB:: got exception : " + ee);
-         return null;
-  }
-
-  int offset, address;
-  address = index;
-
-  if (null != partMap) 
-         offset = binaryBufferHeaderSz + resourceOffsetSz;
-  else
-         offset = binaryBufferHeaderSz;
-
-  try {
-         int skip = 0;
-
-         /* init with NULL policy setting */
-         writeIntToStream(binBuffer, ACM_NULL_POLICY, index);
-         writeIntToStream(binBuffer, 0, index + u32Size);
-         writeIntToStream(binBuffer, ACM_NULL_POLICY, index + 2*u32Size);
-         writeIntToStream(binBuffer, 0, index + 3*u32Size);
-         
-         index = address;
-         if (null != chwPolicy) {
-         
-                 /* Write policy name */
-                 writeIntToStream(binBuffer, ACM_CHINESE_WALL_POLICY, index);
-                 index += u32Size;
-
-                 /* Write offset */
-                 writeIntToStream(binBuffer, offset, index);
-                 index += u32Size;
-
-                 /* Write payload. No need increment index */
-                 address = offset;
-                 System.arraycopy(chwPolicy, 0, binBuffer,address, 
chwPolicy.length);
-                 address = address + chwPolicy.length;
-         } else
-                 skip += 2*u32Size;
-
-         if (null != stePolicy) 
-         {     
-               /* Write policy name */
-               writeIntToStream(binBuffer, ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
index);
-               index += u32Size;
-
-               /* Write offset */
-               writeIntToStream(binBuffer, address, index);
-               index += u32Size;
-
-               /* Copy array */
-               System.arraycopy(stePolicy, 0, binBuffer,address, 
stePolicy.length);
-               /* Update address */
-               address = address + stePolicy.length;
-         } else
-                skip += 2*u32Size;
-
-         /* Skip writing policy name and offset for each null policy*/
-         index +=  skip;
-
-         int size;
-         /* Assumes that you will always have a partition defined in policy */
-         if ( 0 < partMap.length) {
-                 writeIntToStream(binBuffer, address, index);
-                 index = address;
-
-                 /* Compute num of VMs */
-                 size = partMap.length / (3 * u16Size);
-
-                 writeShortToStream(binBuffer, (short)size,index);
-                 index = index + u16Size;
-
-                 /* part, vlan and slot: each one consists of two entries */
-                 offset = 3 * (2 * u16Size);
-                 writeShortToStream(binBuffer, (short) offset,index);
-
-                 /* Write partition array at offset */
-                 System.arraycopy(partMap, 0, binBuffer,(offset + address), 
partMap.length);
-                 index = index + u16Size;
-                 offset = offset + partMap.length;
-         }
-
-         if ( 0 < vlanMap.length) {
-                 size = vlanMap.length / (2 * u16Size);
-                 writeShortToStream(binBuffer, (short) size,index);
-                 index = index + u16Size;
-
-                 writeShortToStream(binBuffer, (short) offset,index);
-                 index = index + u16Size;
-                 System.arraycopy(vlanMap, 0, binBuffer,(offset + address), 
vlanMap.length);
-         } else {
-                 /* Write vlan max */
-                 writeShortToStream(binBuffer, (short) 0,index);
-                 index = index + u16Size;
- 
-                 /* Write vlan offset */
-                 writeShortToStream(binBuffer, (short) 0,index);
-                 index = index + u16Size;
-         }
-
-         offset = offset + vlanMap.length;
-         if ( 0 < slotMap.length) {
-                 size = slotMap.length / (3 * u16Size);
-                 writeShortToStream(binBuffer, (short) size,index);
-                 index = index + u16Size;
-
-                 writeShortToStream(binBuffer, (short) offset,index);
-                 index = index + u16Size;
-                 System.arraycopy(slotMap, 0, binBuffer,(offset + address), 
slotMap.length);
-         }
-  } catch (IOException ee) {
-         System.out.println(" GBPB:: got exception : " + ee);
-         return null;
-  }
-
-  printDebug(" GBP:: Binary Policy ==> length " + binBuffer.length);
-  if (debug)
-         printHex(binBuffer,binBuffer.length);
-
-  return  binBuffer;
- } 
-
- public  byte[] generateChwBuffer(Vector Ssids, Vector ConflictSsids, Vector 
ColorTypes)
- {
-  byte[] chwBuffer;
-  int index = 0;
-  int position = 0;
-
-  /* Get number of rTypes */
-  int maxTypes = ColorTypes.size();
-
-  /* Get number of SSids entry */
-  int maxSsids = Ssids.size();
-
-  /* Get number of conflict sets */
-  int maxConflict = ConflictSsids.size();
-
-   
-  if (maxTypes * maxSsids == 0)
-       return null; 
-  /*
-     data structure acm_chwall_policy_buffer
-     se XmlToBinInterface.java
-  */
-  int totalBytes = chwHeaderSize  + u16Size *(maxTypes * (maxSsids + 
maxConflict)); 
-
-  chwBuffer = new byte[ totalBytes ];
-  int address = chwHeaderSize + (u16Size * maxTypes * maxSsids );
-
-  printDebug(" gCB:: chwall totalbytes : "+totalBytes); 
-
-  try {
-         index = 0;
-         /* fill in General Policy Version */
-         writeIntToStream(chwBuffer, ACM_CHWALL_VERSION, index);
-         index += u32Size;
-
-         writeIntToStream(chwBuffer, ACM_CHINESE_WALL_POLICY, index);
-         index += u32Size;
-
-         writeIntToStream(chwBuffer, maxTypes, index);
-         index += u32Size;
-
-         writeIntToStream(chwBuffer, maxSsids, index);
-         index += u32Size;
-
-         writeIntToStream(chwBuffer, maxConflict, index);
-         index += u32Size;
-
-         /*  Write chwall_ssid_offset */
-         writeIntToStream(chwBuffer, chwHeaderSize, index);
-         index += u32Size;
-
-         /* Write chwall_conflict_sets_offset */
-         writeIntToStream(chwBuffer, address, index);
-         index += u32Size;
-
-         /*  Write chwall_running_types_offset */
-         writeIntToStream(chwBuffer, 0, index);
-         index += u32Size;
-
-         /*  Write chwall_conflict_aggregate_offset */
-         writeIntToStream(chwBuffer, 0, index);
-         index += u32Size;
-
-  } catch (IOException ee) {
-       System.out.println(" gCB:: got exception : " + ee); 
-       return null;
-  }
-  int markPos = 0;
-
-  /* Create the SSids entry */
-  for (int i = 0; i < maxSsids; i++)
-  {
-       SecurityLabel ssidEntry = (SecurityLabel) Ssids.elementAt(i);
-       /* Get chwall types */
-       ssidEntry.chwSsidPosition = i;
-       Enumeration e = ssidEntry.chwTypes.elements(); 
-       while (e.hasMoreElements())
-       {
-         String typeName = (String) e.nextElement(); 
-         printDebug(" gCB:: Ssid "+ i+ ": has type : " + typeName);
-         position = ColorTypes.indexOf(typeName);
-
-         if (position < 0) 
-         {
-               System.out.println (" gCB:: Error type : " + typeName + " not 
found in ColorTypes"); 
-               return null; 
-         }
-         printDebug(" GCB:: type : " + typeName + "  found in ColorTypes at 
position: " + position); 
-         markPos = ((i * maxTypes + position) * u16Size) + index;      
-
-         try {
-               writeShortToStream(chwBuffer,markSymbol,markPos);
-         } catch (IOException ee) {
-               System.out.println(" gCB:: got exception : "); 
-               return null; 
-         }
-       }
-  }
-
-  if (debug) 
-      printHex(chwBuffer,chwBuffer.length);
-
-  /* Add conflict set */
-  index = address;
-  for (int i = 0; i < maxConflict; i++)
-  {
-       /* Get ste types */
-       Vector entry = (Vector) ConflictSsids.elementAt(i);
-       Enumeration e = entry.elements(); 
-       while (e.hasMoreElements())
-       {
-         String typeName = (String) e.nextElement(); 
-         printDebug (" GCB:: conflict Ssid "+ i+ ": has type : " + typeName);
-         position = ColorTypes.indexOf(typeName);
-
-         if (position < 0) 
-         {
-               System.out.println (" GCB:: Error type : " + typeName + " not 
found in ColorTypes"); 
-               return null; 
-         }
-         printDebug(" GCB:: type : " + typeName + "  found in ColorTypes at 
position: " + position); 
-         markPos = ((i * maxTypes + position) * u16Size) + index;      
-
-         try {
-               writeShortToStream(chwBuffer,markSymbol,markPos);
-         } catch (IOException ee) {
-               System.out.println(" GCB:: got exception : "); 
-               return null; 
-         }
-       }
-               
-  } 
-  printDebug(" gSB:: chw binary  ==> Length " + chwBuffer.length); 
-  if (debug) 
-       printHex(chwBuffer,chwBuffer.length);
-  printDebug("\n");
-
-  return chwBuffer;
- }
-
-/**********************************************************************
- Generate byte representation of policy using type information
- <p>
- @param Ssids                  Vector
- @param ColorTypes             Vector
- <p>
- @return bytes represenation of simple type enforcement policy 
-**********************************************************************/
- public  byte[] generateSteBuffer(Vector Ssids, Vector ColorTypes)
- {
-  byte[] steBuffer;
-  int index = 0;
-  int position = 0;
-
-  /* Get number of colorTypes */
-  int numColorTypes = ColorTypes.size();
-
-  /* Get number of SSids entry */
-  int numSsids = Ssids.size();
-   
-  if (numColorTypes * numSsids == 0)
-       return null; 
-
-  /* data structure: acm_ste_policy_buffer
-   * see XmlToBinInterface.java
-   * total bytes: steHeaderSize * 2B + colorTypes(size) * Ssids(size)
-   * 
-  */
-  steBuffer = new byte[ steHeaderSize + (numColorTypes * numSsids) * 2];
-
-  try {
-       
-         index = 0;
-         writeIntToStream(steBuffer, ACM_STE_VERSION, index);
-         index += u32Size;
-
-         writeIntToStream(steBuffer, ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
index);
-         index += u32Size;
-
-         writeIntToStream(steBuffer, numColorTypes, index);
-         index += u32Size;
-
-         writeIntToStream(steBuffer, numSsids, index);
-         index += u32Size;
-
-         writeIntToStream(steBuffer, steHeaderSize, index);
-         index += u32Size;
-
-
-  } catch (IOException ee) {
-       System.out.println(" gSB:: got exception : " + ee); 
-       return null; 
-  }
-  int markPos = 0;
-  for (int i = 0; i < numSsids; i++)
-  {
-       
-       SecurityLabel ssidEntry = (SecurityLabel) Ssids.elementAt(i);
-       ssidEntry.steSsidPosition = i;
-       /* Get ste types */
-       Enumeration e = ssidEntry.steTypes.elements(); 
-       while (e.hasMoreElements())
-       {
-         String typeName = (String) e.nextElement(); 
-         printDebug (" gSB:: Ssid "+ i+ ": has type : " + typeName);
-         position = ColorTypes.indexOf(typeName);
-
-         if (position < 0) 
-         {
-               printDebug(" gSB:: Error type : " + typeName + " not found in 
ColorTypes"); 
-               return null; 
-         }
-         printDebug(" gSB:: type : " + typeName + "  found in ColorTypes at 
position: " + position); 
-         markPos = ((i * numColorTypes + position) * u16Size) + index; 
-
-         try {
-               writeShortToStream(steBuffer,markSymbol,markPos);
-         } catch (IOException ee)
-         {
-               System.out.println(" gSB:: got exception : "); 
-               return null; 
-         }
-       }
-               
-  } 
-
-  printDebug(" gSB:: ste binary  ==> Length " + steBuffer.length); 
-  if (debug) 
-       printHex(steBuffer,steBuffer.length);
-  printDebug("\n");
-
-  return steBuffer;
- }
-
- public static  void printHex(byte [] dataArray, int length)
- {
-  char[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7',
-                '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
-  int hexIndex;
-  int value;
-  int arraylength;
-
-  arraylength = length;
-
-  if (dataArray == null)
-  {
-        System.err.print("printHex: input byte array is null");
-  }
-
-  if (length > dataArray.length || length < 0)
-        arraylength = dataArray.length;
-
-  System.out.print("\n\t");
-
-  int i;
-  for(i = 0; i < arraylength; )
-  {
-        value = dataArray[i] & 0xFF;
-        hexIndex = (value >>> 4);
-        System.out.print(hexChars[hexIndex]);
-        hexIndex = (value & 0x0F);
-        System.out.print(hexChars[hexIndex]);
-
-        i++;
-        /* if done, print a final newline */
-        if (i == arraylength) {
-            if (arraylength < dataArray.length) {
-                System.out.print("...");
-            }
-            System.out.println();
-        }
-        else if ((i % 24) == 0) {
-            System.out.print("\n\t");
-        }
-        else if ((i % 4) == 0) {
-                System.out.print(" ");
-        }
-  }
-
-  return;
- }
-
-  
- private void writeShortToStream(byte[] stream, short value, int index)
-  throws IOException
- {
-  int littleEndian = 0;
-  int byteVal;
-
-  if (index + 2 > stream.length)
-  {
-      throw new IOException("Writing beyond stream length: " +
-                            stream.length + " writing at locations from: " + 
index + " to " + (index + 4));
-  }
-
-  if (!LittleEndian)
-  {
-
-       byteVal = value >> 8;
-       stream[index ] = (byte) byteVal;
-
-       byteVal = value;
-       stream[index + 1] = (byte) byteVal;
-  } else {
-       stream[index]  = (byte) ((value & 0x00ff) );
-       stream[index + 1]  = (byte) ((value & 0xff00) >> 8);
- }
-  return;
- }
-
- private void writeIntToStream(byte[] stream, int value, int index)
-  throws IOException
- {
-  int littleEndian = 0;
-  int byteVal;
-
-  if (4 > stream.length)
-  {
-      throw new IOException("writeIntToStream: stream length less than 4 bytes 
" +
-                            stream.length);
-  }
-
-  /* Do not Write beyond range */
-  if (index + 4 > stream.length)
-  {
-      throw new IOException("writeIntToStream: writing beyond stream length: " 
+
-                            stream.length + " writing at locations from: " + 
index + " to " + (index + 4));
-  }
-  if (!LittleEndian)
-  {
-       byteVal = value >>> 24;
-       stream[index] = (byte) byteVal;
-
-       byteVal = value >> 16;
-       stream[index + 1] = (byte) byteVal;
-
-       byteVal = value >> 8;
-       stream[index + 2] = (byte) byteVal;
-
-       byteVal = value;
-       stream[index + 3] = (byte) byteVal;
-  } else {
-       stream[index] = (byte) value;
-       stream[index + 1]  = (byte) ((value & 0x0000ff00) >> 8);
-       stream[index + 2]  = (byte) ((value & 0x00ff0000) >> 16);
-       stream[index + 3] = (byte) ( value >>> 24);
-  }
-  return;
- }
-
- public Document getDomTree(String xmlFileName)
-  throws Exception, SAXException, ParserConfigurationException
- {
-  javax.xml.parsers.DocumentBuilderFactory dbf = 
-       javax.xml.parsers.DocumentBuilderFactory.newInstance();
-
-  /* Turn on namespace aware and validation */
-  dbf.setNamespaceAware(true); 
-  dbf.setValidating(true);     
-  dbf.setAttribute(JAXP_SCHEMA_LANGUAGE,W3C_XML_SCHEMA);
-
-  /* Checks that the document is well-formed */
-  javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
-
-  myHandler errHandler= new myHandler();
-  db.setErrorHandler(errHandler);
-  Document doc = db.parse(xmlFileName);
-
-  /* Checks for validation errors */
-  if (errHandler.isValid)
-       printDebug(" gDT:: Xml file: " + xmlFileName + " is valid");
-   else
-      throw new Exception("Xml file: " + xmlFileName + " is NOT valid");
-
-  return doc;
- }  
-
- public void processDomTree(
-       Document doc,
-       Vector bagOfSsids,      
-       Vector bagOfTypes, 
-       Vector bagOfChwSsids, 
-       Vector bagOfChwTypes, 
-       Vector bagOfConflictSsids)
-  throws Exception, SAXException, ParserConfigurationException
- {
-  boolean found;
-
-  /* print the root Element */
-  Element root = doc.getDocumentElement();
-  printDebug ("\n pDT:: Document Element: Name = " + root.getNodeName() + 
",Value = " + root.getNodeValue());
-
-  /* Go through the list of the root Element's Attributes */
-  NamedNodeMap nnm = root.getAttributes();
-  printDebug (" pDT:: # of Attributes: " + nnm.getLength());
-  for (int i = 0; i < nnm.getLength(); i++)
-  {
-         Node n = nnm.item (i);
-        printDebug (" pDT:: Attribute: Name = " + n.getNodeName() + ", Value = 
" 
-             + n.getNodeValue());
-  }
-
-  /* Retrieve the policy definition */ 
-  NodeList elementList = root.getElementsByTagName ("url");
-  String definitionFileName = 
elementList.item(0).getFirstChild().getNodeValue();  
-
-  String definitionHash = null;
-
-  /* Note that SecurityPolicySpec.xsd allows for 0 hash value! */
-  elementList = root.getElementsByTagName ("hash");
-  if (0 != elementList.getLength())
-       definitionHash = elementList.item(0).getFirstChild().getNodeValue();  
-
-  Document definitionDoc = 
pGetDomDefinition(definitionFileName,definitionHash);
-  pGetTypes(definitionDoc,bagOfTypes, bagOfChwTypes, bagOfConflictSsids);
-
-
-  /* Get VM security information */
-  elementList = root.getElementsByTagName ("VM");
-  printDebug ("\n pDT:: partition length of NodeList:" + 
elementList.getLength());
-  /* Add default Ssid to Ste and Chw bags */                   
-  SecurityLabel defEntry = new SecurityLabel();
-
-  defEntry.chwTypes = new Vector();
-  defEntry.steTypes = new Vector();
-  defEntry.chwIDs = new Vector();
-  defEntry.ids = new Vector();
-
-  defEntry.steSsidPosition =0;
-  defEntry.chwSsidPosition =0;
-  bagOfChwSsids.add(defEntry);
-  bagOfSsids.add(defEntry);
-
-  for (int x = 0; x < elementList.getLength(); x++)
-  {
-       found = false;
-
-        Node node = elementList.item (x);          
-
-       if (node.getNodeType() == Node.ELEMENT_NODE)
-       {
-         printDebug (" pDT:: child: " + x + " is an element node" );
-         Element e1 = (Element) node;
-
-         /* Get id */
-         NodeList elist = e1.getElementsByTagName ("id");
-         String idStr = elist.item(0).getFirstChild().getNodeValue();  
-         printDebug (" pDT:: id:" + idStr);
-
-         /* Get TE */
-         Vector colorTypes = new Vector();
-         pConflictEntries(e1, "TE", bagOfTypes, colorTypes);
-
-         Enumeration e = bagOfSsids.elements();
-         while (e.hasMoreElements())
-         {
-               SecurityLabel elem = (SecurityLabel) e.nextElement(); 
-               if ( elem.steTypes.size() == colorTypes.size() && 
elem.steTypes.containsAll(colorTypes))
-               {
-                 found = true;
-                 elem.ids.add(idStr);
-               }
-               
-         }
-               if (!found && (0 < colorTypes.size()))
-               {
-                SecurityLabel entry = new SecurityLabel();
-                entry.steTypes = colorTypes;
-                entry.ids = new Vector();
-                entry.ids.add(idStr);
-                bagOfSsids.add(entry);
-               }
-
-               /* Get Chinese wall type */
-               Vector chwTypes = new Vector();
-               pConflictEntries(e1, "ChWall", bagOfChwTypes, chwTypes);
-
-               found = false;
-               e = bagOfChwSsids.elements();
-
-               while (e.hasMoreElements())
-               {
-                 SecurityLabel elem = (SecurityLabel) e.nextElement(); 
-                 if ( elem.chwTypes.size() == chwTypes.size() && 
elem.chwTypes.containsAll(chwTypes))
-                 {
-                   found = true;
-                   elem.chwIDs.add(idStr);
-                 }
-               
-               }
-
-               if (!found && (0 < chwTypes.size()))
-               {
-                SecurityLabel entry = new SecurityLabel();
-                entry.chwTypes = chwTypes;
-                entry.chwIDs = new Vector();
-                entry.chwIDs.add(idStr);
-                bagOfChwSsids.add(entry);
-               }
-      }
-  } 
-  return;
- }
-
- public Document pGetDomDefinition(
-       String definitionFileName, 
-       String definitionHash) 
-  throws Exception, SAXException, ParserConfigurationException
- {
-  printDebug("\n pGDD:: definition file name: " + definitionFileName);
-  printDebug("\n pGDD:: definition file hash: " + definitionHash);
-  
-  Document doc =  getDomTree(definitionFileName);
-  return doc; 
- }
-
- public void pGetTypes(
-       Document defDoc,
-       Vector bagOfTypes, 
-       Vector bagOfChwTypes, 
-       Vector bagOfConflictSsids)
-  throws Exception
- {
-
-
-  if (null == defDoc)
-      throw new Exception(" pGT:: definition file DOM is null ");
-
-  Element root = defDoc.getDocumentElement();
-
-  /* Get list of TE types */
-  NodeList elementList = root.getElementsByTagName ("Types");
-  printDebug ("\n pGT:: Types length of NodeList:" + elementList.getLength());
-  Element e1 = (Element) elementList.item (0);          
-  pGetEntries(e1,"TE",bagOfTypes);
-
-  /* Get list of Chinese types */
-  elementList = root.getElementsByTagName ("ChWallTypes");
-  printDebug ("\n pGT:: ChwTypes length of NodeList:" + 
elementList.getLength());
-  if (0 ==  elementList.getLength())
-  {
-       printDebug ("\n pGT:: ChWallTypes has zero length: :" + 
elementList.getLength());
-  } else {
-       e1 = (Element) elementList.item (0);          
-       pGetEntries(e1,"ChWall",bagOfChwTypes);
-  }
-  printDebug (" pGT:: Total number of unique chw types: " + 
bagOfChwTypes.size());
-
-  /* Get Chinese type conflict sets */
-  elementList = root.getElementsByTagName ("ConflictSet");
-  printDebug ("\n pGT:: Conflict sets length of NodeList:" + 
elementList.getLength());
-  for (int x = 0; x < elementList.getLength(); x++)
-  {
-       Vector conflictEntry  = new Vector();
-       e1 = (Element) elementList.item (x);          
-       printDebug ("\n pGT:: Conflict sets : " + x);
-
-       pConflictEntries(e1, "ChWall", bagOfChwTypes, conflictEntry);
-
-       if (conflictEntry.size() > 0)
-       {
-         boolean found = false;
-         Enumeration e = bagOfConflictSsids.elements();
-       
-         while (e.hasMoreElements())
-         {
-               Vector elem = (Vector) e.nextElement(); 
-               if (elem.size() == conflictEntry.size() && 
elem.containsAll(conflictEntry))
-               {
-                 found = true;
-               }
-               
-         }
-         if (!found)
-         {
-               bagOfConflictSsids.add(conflictEntry);
-         }
-       }
-  }
-
- }
-
- public void  pGetEntries(Element doc, String tag, Vector typeBag)
-  throws Exception
- {
-
-  if (null == doc)
-      throw new Exception(" pGE:: Element doc is null");
-
-  if (null == typeBag)
-      throw new Exception(" pGE:: typeBag  is null");
-
-  NodeList elist = doc.getElementsByTagName (tag);
-  for (int j = 0; j < elist.getLength(); j++)
-  {
-       Node knode = elist.item (j);          
-               Node childNode = knode.getFirstChild();     
-               String value = childNode.getNodeValue();
-
-       printDebug (" pGT:: "+ tag +" type: " + value);
-
-        /* Check if value is known */
-       if (!typeBag.contains(value))
-               typeBag.addElement(value);
-  }
- }
-
- public void  pConflictEntries(Element doc, String tag, Vector typeBag, Vector 
conflictEntry)
-  throws Exception
- {
-
-  if (null == doc)
-      throw new Exception(" pGE:: Element doc is null");
-
-  if (null == typeBag)
-      throw new Exception(" pGE:: typeBag  is null");
-
-  if (null == conflictEntry)
-      throw new Exception(" pGE:: typeBag  is null");
-
-
-  NodeList elist = doc.getElementsByTagName (tag);
-
-  for (int j = 0; j < elist.getLength(); j++)
-  {
-       Node knode = elist.item (j);          
-               Node childNode = knode.getFirstChild();     
-               String value = childNode.getNodeValue();
-
-       printDebug (" pGE:: "+ tag +" type: " + value);
-
-        /* Check if value is known */
-       if (!typeBag.contains(value))
-               throw new Exception(" pCE:: found undefined type set " + value);
-
-       if (!conflictEntry.contains(value))
-               conflictEntry.addElement(value);
-
-  }
- }
-
-  public void processDomTreeVlanSlot(
-       Document doc,
-       Vector bagOfSsids,      
-       Vector bagOfTypes)      
-  throws Exception
- {
-      boolean found;
-
-  printDebug(" pDTVS::Size of bagOfSsids: "+ bagOfSsids.size());
-  Element root = doc.getDocumentElement();
-
-  NodeList elementList = root.getElementsByTagName ("Vlan");
-  printDebug("\n pDTVS:: Vlan length of NodeList:" + elementList.getLength());
-
-  for (int x = 0; x < elementList.getLength(); x++)
-  {
-       found = false;
-
-        Node node = elementList.item (x);          
-
-       if (node.getNodeType() == Node.ELEMENT_NODE)
-       {
-         printDebug(" pDTVS:: child: " + x + " is an element node" );
-         Element e1 = (Element) node;
-
-         /* Get vid */
-         NodeList elist = e1.getElementsByTagName ("vid");
-         String idStr = elist.item(0).getFirstChild().getNodeValue();  
-         printDebug (" pDTVS:: vid:" + idStr);
-
-         /* Get TE */
-         elist = e1.getElementsByTagName ("TE");
-          printDebug (" pDTVS:: Total ste types: " + elist.getLength());
-
-         Vector colorTypes = new Vector();
-         for (int j = 0; j < elist.getLength(); j++)
-         {
-               Node knode = elist.item (j);          
-               Node childNode = knode.getFirstChild();     
-               String value = childNode.getNodeValue();
-
-               printDebug (" pDT:: My color is: " + value);
-               if (!bagOfTypes.contains(value))
-               {
-                 throw new IOException("pDT:: Vlan: " + idStr+ " has unknown 
type : "+ value);
-               }
-
-               if (!colorTypes.contains(value))
-                 colorTypes.addElement(value);
-         }
-         Enumeration e = bagOfSsids.elements();
-         while (e.hasMoreElements())
-         {
-               SecurityLabel elem = (SecurityLabel) e.nextElement(); 
-               if ( elem.steTypes.size() == colorTypes.size() && 
elem.steTypes.containsAll(colorTypes))
-               {
-                 found = true;
-                 if (null == elem.vlans)
-                       elem.vlans = new Vector();
-                  elem.vlans.add(idStr);
-               }
-               
-         }
-         if (!found && (0 < colorTypes.size()))
-         {
-                SecurityLabel entry = new SecurityLabel();
-                entry.steTypes = colorTypes;
-                entry.vlans = new Vector();
-                entry.vlans.add(idStr);
-                bagOfSsids.add(entry);
-         }
-
-       }
-  } 
-  printDebug(" pDTVS::After slot Size of bagOfSsids: "+ bagOfSsids.size());
-
-  elementList = root.getElementsByTagName ("Slot");
-  printDebug ("\n pDTVS:: Slot length of NodeList:" + elementList.getLength());
-
-  for (int x = 0; x < elementList.getLength(); x++)
-  {
-       found = false;
-
-        Node node = elementList.item (x);          
-
-       if (node.getNodeType() == Node.ELEMENT_NODE)
-       {
-         printDebug(" pDT:: child: " + x + " is an element node" );
-         Element e1 = (Element) node;
-
-
-         /* Get slot and bus */
-         SlotInfo item = new SlotInfo();
-
-         NodeList elist = e1.getElementsByTagName ("bus");
-         item.bus = elist.item(0).getFirstChild().getNodeValue();  
-         elist = e1.getElementsByTagName ("slot");
-         item.slot = elist.item(0).getFirstChild().getNodeValue();  
-         printDebug (" pDT:: bus and slot:" + item.bus + " "+ item.slot);
-
-         /* Get TE */
-         elist = e1.getElementsByTagName ("TE");
-          printDebug (" pDT:: Total ste types: " + elist.getLength());
-
-         Vector colorTypes = new Vector();
-         for (int j = 0; j < elist.getLength(); j++)
-         {
-               Node knode = elist.item (j);          
-               Node childNode = knode.getFirstChild();     
-               String value = childNode.getNodeValue();
-
-               printDebug (" pDT:: My color is: " + value);
-               if (!bagOfTypes.contains(value))
-               {
-                 throw new IOException("pDT:: bus: " + item.bus + " slot: "+ 
item.slot + " has unknown type : "+ value);
-               }
-
-               if (!colorTypes.contains(value))
-                 colorTypes.addElement(value);
-               }
-
-               Enumeration e = bagOfSsids.elements();
-               while (e.hasMoreElements())
-               {
-                 SecurityLabel elem = (SecurityLabel) e.nextElement(); 
-                 if ( elem.steTypes.size() == colorTypes.size() && 
elem.steTypes.containsAll(colorTypes))
-                 {
-                       found = true;
-                       if (null == elem.slots)
-                         elem.slots = new Vector();
-                       elem.slots.add(item);
-
-                 }
-               
-               }
-
-               if (!found && (0 < colorTypes.size()))
-               {
-                 SecurityLabel entry = new SecurityLabel();
-                 entry.steTypes = colorTypes;
-                 entry.slots = new Vector();
-                 entry.slots.add(item);
-                 bagOfSsids.add(entry);
-               }
-
-       }
-  }
-  return;
- }
-
- public static void main (String[] args) 
- {
-  String xmlFileName = null;           /* policy file */ 
-  String outputFileName = null;        /* binary policy file */
-  String xenSsidOutputFileName = null;         /* outputfile ssid to named 
types */    
-                                       /* outputfile conflicts ssid to named 
types */  
-  String xenSsidConfOutputFileName = null;     
-
-  XmlToBin genObj = new XmlToBin(); 
-
-  policy_version active_policy = new policy_version();
-
-  if ((active_policy.ACM_POLICY_VERSION != ACM_POLICY_VERSION) ||
-      (active_policy.ACM_CHWALL_VERSION != ACM_CHWALL_VERSION) ||
-      (active_policy.ACM_STE_VERSION != ACM_STE_VERSION)) {
-         System.out.println("ACM policy versions differ.");
-         System.out.println("Please verify that data structures are correct");
-         System.out.println("and then adjust the version numbers in 
XmlToBinInterface.java.");
-         return;
-  }
-
-
-  for (int i = 0 ; i < args.length ; i++) {
-
-       if ( args[i].equals("-help"))  {
-          printUsage();
-          System.exit(1);
-
-        } else if ( args[i].equals("-i"))  {
-          i++;
-          if (i < args.length) {
-               xmlFileName = args[i];   
-          } else  {
-                System.out.println("-i argument needs parameter");
-                System.exit(1);
-          }
-
-       } else if ( args[i].equals("-o"))  {
-          i++;
-          if (i < args.length) {
-                outputFileName = args[i];   
-          } else {
-                System.out.println("-o argument needs parameter");
-                System.exit(1);
-          }
-
-       } else if ( args[i].equals("-xssid"))  {
-          i++;
-          if (i < args.length) {
-                 xenSsidOutputFileName = args[i];   
-          } else {
-                System.out.println("-xssid argument needs parameter");
-                System.exit(1);
-          }
-
-       } else if ( args[i].equals("-xssidconf"))  {
-          i++;
-          if (i < args.length) {
-                xenSsidConfOutputFileName = args[i]; 
-          } else {
-                System.out.println("-xssidconf argument needs parameter");
-                System.exit(1);
-          }
-       } else if ( args[i].equals("-debug"))  { /* turn on debug msg */
-               genObj.setDebug(true);
-        } else {
-          System.out.println("bad command line argument: " + args[i]);
-          printUsage();
-          System.exit(1);
-        }
-
-  }
-
-  if (xmlFileName == null)
-  { 
-       System.out.println("Need to specify input file -i option");
-        printUsage();
-        System.exit(1);
-  }
-
-
-  try 
-  {
-       /* Parse and validate */
-       Document doc =  genObj.getDomTree(xmlFileName);
-
-       /* Vectors to hold sets of types */
-       Vector bagOfSsids = new Vector();
-       Vector bagOfTypes = new Vector();
-       Vector bagOfChwSsids = new Vector();
-       Vector bagOfChwTypes = new Vector();
-       Vector bagOfConflictSsids = new Vector();
-
-       Vector vlanMapSsids = new Vector();
-       Vector slotMapSsids = new Vector();
-
-       genObj.processDomTree(doc, bagOfSsids, bagOfTypes, bagOfChwSsids, 
bagOfChwTypes, bagOfConflictSsids);
-
-       genObj.processDomTreeVlanSlot(doc, bagOfSsids, bagOfTypes);
-
-       /* Get binary representation of policies */
-       byte[] stePolicy = genObj.generateSteBuffer(bagOfSsids, bagOfTypes);
-       byte[] chwPolicy = genObj.generateChwBuffer(bagOfChwSsids, 
bagOfConflictSsids,bagOfChwTypes);
-
-       byte[] binPolicy = null;
-       byte[] binaryPartionSsid = null;
-       byte[] binaryVlanSsid = null;
-       byte[] binarySlotSsid = null;
-
-       /* Get binary representation of partition to ssid mapping */
-       binaryPartionSsid = genObj.generatePartSsids(bagOfSsids,bagOfChwSsids);
-
-       /* Get binary representation of vlan to ssid mapping */
-       binaryVlanSsid = genObj.generateVlanSsids(bagOfSsids);
-
-       /* Get binary representation of slot to ssid mapping */
-       binarySlotSsid = genObj.generateSlotSsids(bagOfSsids);
-
-       /* Generate binary representation: policy, partition, slot and vlan */
-       binPolicy = genObj.GenBinaryPolicyBuffer(chwPolicy,stePolicy, 
binaryPartionSsid, binaryVlanSsid, binarySlotSsid);
-
-
-       /* Write binary policy into file */
-       if (null != outputFileName)
-       {
-               genObj.writeBinPolicy(binPolicy, outputFileName);
-       } else {
-               System.out.println (" No binary policy generated, 
outputFileName:  " + outputFileName);
-       }
-
-       /* Print total number of types */
-       System.out.println (" Total number of unique ste types: " + 
bagOfTypes.size());
-       System.out.println (" Total number of Ssids : " + bagOfSsids.size());
-       System.out.println (" Total number of unique chw types: " + 
bagOfChwTypes.size());
-       System.out.println (" Total number of conflict ssids : " + 
bagOfConflictSsids.size());
-       System.out.println (" Total number of chw Ssids : " + 
bagOfChwSsids.size());
-
-       if (null != xenSsidOutputFileName)
-               genObj.writeXenTypeFile(bagOfSsids, xenSsidOutputFileName, 
true);
-
-       if (null != xenSsidConfOutputFileName)
-               genObj.writeXenTypeFile(bagOfChwSsids, 
xenSsidConfOutputFileName, false);
-    } 
-    catch (Exception e) 
-    {
-      e.printStackTrace();
-    }
-  }
-}
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/misc/policyprocessor/XmlToBinInterface.java
--- a/tools/misc/policyprocessor/XmlToBinInterface.java Thu Aug 18 18:40:02 2005
+++ /dev/null   Fri Aug 19 18:19:28 2005
@@ -1,138 +0,0 @@
-/**
- * (C) Copyright IBM Corp. 2005
- *
- * $Id: XmlToBinInterface.java,v 1.3 2005/06/20 21:07:37 rvaldez Exp $
- *
- * Author: Ray Valdez
- *
- * 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, version 2 of the
- * License.
- *
- * XmlToBinInterface Class.  
- * <p>
- *
- * Defines constants used by XmToBin.
- *
- * <p>
- *
- *     policy binary structures
- *
- * struct acm_policy_buffer {
- *     u32 policy_version; * ACM_POLICY_VERSION *
- *      u32 magic;
- *     u32 len;
- *     u32 primary_policy_code;
- *     u32 primary_buffer_offset;
- *     u32 secondary_policy_code;
- *     u32 secondary_buffer_offset;
- *      +u32 resource offset (not used yet in Xen)
- * };
- *
- *
- * struct acm_ste_policy_buffer {
- *     u32 policy_version; * ACM_STE_VERSION *
- *     u32 policy_code;
- *     u32 ste_max_types;
- *     u32 ste_max_ssidrefs;
- *     u32 ste_ssid_offset;
- * };
- *
- * struct acm_chwall_policy_buffer {
- *     u32 policy_version; * ACM_CHWALL_VERSION *
- *     u32 policy_code;
- *     u32 chwall_max_types;
- *     u32 chwall_max_ssidrefs;
- *     u32 chwall_max_conflictsets;
- *     u32 chwall_ssid_offset;
- *     u32 chwall_conflict_sets_offset;
- *     u32 chwall_running_types_offset;
- *     u32 chwall_conflict_aggregate_offset;
- * };
- *
- *     typedef struct {
- *     u16 partition_max;
- *     u16 partition_offset;
- *     u16 vlan_max;
- *     u16 vlan_offset;
- *     u16 slot_max;
- *     u16 slot_offset;
- *     } acm_resource_buffer_t;
- *
- *     typedef struct {
- *     u16 id;
- *     u16 ssid_ste;
- *     u16 ssid_chwall;
- *     } acm_partition_entry_t;
- *
- *     typedef struct {
- *     u16 vlan;
- *     u16 ssid_ste;
- *     } acm_vlan_entry_t;
- *
- *     typedef struct {
- *     u16 bus;
- *     u16 slot;
- *     u16 ssid_ste;
- *     } acm_slot_entry_t;
- *
- *       
- *
- */
-public interface XmlToBinInterface
-{
-  /* policy code  (uint16) */
-  final int policyCodeSize = 2;
-
-  /* max_types    (uint16) */
-  final int maxTypesSize = 2;
-
-  /* max_ssidrefs (uint16) */
-  final int maxSsidrefSize = 2;
-
-  /* ssid_offset  (uint32) */
-  final int ssidOffsetSize = 2;
-
-  final short markSymbol = 0x0001;
-
-  final int u32Size = 4;
-  final int u16Size = 2;
-
-  /* num of bytes for acm_ste_policy_buffer_t */
-  final int steHeaderSize = (5 * u32Size);
-
-  /* byte for acm_chinese_wall_policy_buffer_t */
-  final int chwHeaderSize = (9 * u32Size);
-
-  final int primaryPolicyCodeSize = u32Size;
-  final int primaryBufferOffsetSize = u32Size ;
-
-  final int secondaryPolicyCodeSz = u32Size;
-  final int secondaryBufferOffsetSz = u32Size;
-  final int resourceOffsetSz = u32Size;
-
-  final short partitionBufferSz = (2 * u16Size);
-  final short partitionEntrySz = (3 * u16Size);
-
-  final short slotBufferSz = (2 * u16Size);
-  final short slotEntrySz = (3 * u16Size);
-
-  final short vlanBufferSz = (2 * u16Size);
-  final short vlanEntrySz = (2 * u16Size);
-
-  final int binaryBufferHeaderSz = (8 * u32Size); /* 8th not used in Xen */
-
-  /* copied directly from acm.h */
-  final int ACM_MAGIC  =  0x0001debc;
-  final int ACM_NULL_POLICY = 0;
-  final int ACM_CHINESE_WALL_POLICY = 1;
-  final int ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY = 2;
-  final int ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY = 3;
-  final int ACM_EMPTY_POLICY = 4;
-
-  /* version for compatibility check */
-  final int ACM_POLICY_VERSION = 1;
-  final int ACM_STE_VERSION    = 1;
-  final int ACM_CHWALL_VERSION = 1;
-}
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/misc/policyprocessor/c2j_include.c
--- a/tools/misc/policyprocessor/c2j_include.c  Thu Aug 18 18:40:02 2005
+++ /dev/null   Fri Aug 19 18:19:28 2005
@@ -1,57 +0,0 @@
-/****************************************************************
- * c2j_include.c
- *
- * Copyright (C) 2005 IBM Corporation
- *
- * Authors:
- * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
- *
- * 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, version 2 of the
- * License.
- *
- * This tool makes some constants from acm.h available to the
- * java policyprocessor for version checking.
- */
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.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 <xen/acm.h>
-
-char *filename = "policy_version.java";
-
-int main(int argc, char **argv)
-{
-
-    FILE *fd;
-    if ((fd = fopen(filename, "w")) <= 0)
-    {
-        printf("File %s not found.\n", filename);
-        exit(-ENOENT);
-    }
-
-    fprintf(fd, "/*\n * This file was automatically generated\n");
-    fprintf(fd, " * Do not change it manually!\n */\n");
-    fprintf(fd, "public class policy_version {\n");
-    fprintf(fd, "      final int ACM_POLICY_VERSION = %x;\n",
-            ACM_POLICY_VERSION);
-    fprintf(fd, "      final int ACM_CHWALL_VERSION = %x;\n",
-            ACM_CHWALL_VERSION);
-    fprintf(fd, "      final int ACM_STE_VERSION = %x;\n",
-            ACM_STE_VERSION);
-    fprintf(fd, "}\n");
-    fclose(fd);
-    return 0;
-}
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/misc/policyprocessor/myHandler.java
--- a/tools/misc/policyprocessor/myHandler.java Thu Aug 18 18:40:02 2005
+++ /dev/null   Fri Aug 19 18:19:28 2005
@@ -1,47 +0,0 @@
-/**
- * (C) Copyright IBM Corp. 2005
- *
- * $Id: myHandler.java,v 1.2 2005/06/17 20:00:04 rvaldez Exp $
- *
- * Author: Ray Valdez
- *
- * 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, version 2 of the
- * License.
- *
- * myHandler Class.  
- *
- * <p>
- *
- * A dummy class used for detecting XML validating/parsing errors.
- *
- * <p>
- *
- *
- */
-import org.xml.sax.helpers.*;
-import org.xml.sax.SAXParseException;
-
-class myHandler extends DefaultHandler 
-{ 
- public boolean isValid = true;
-
- /* Notification of a recoverable error. */
- public void error(SAXParseException se) 
- { 
-  isValid = false;
- } 
-
- /* Notification of a non-recoverable error. */
- public void fatalError(SAXParseException se) 
- { 
-  isValid = false;
- } 
-
- /* Notification of a warning. */
- public void warning(SAXParseException se) 
- {
-  isValid = false;
- }
-}
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/misc/policyprocessor/readme.install
--- a/tools/misc/policyprocessor/readme.install Thu Aug 18 18:40:02 2005
+++ /dev/null   Fri Aug 19 18:19:28 2005
@@ -1,33 +0,0 @@
-# Author: Ray Valdez, rvaldez@xxxxxxxxxx 
-# Version: 1.0
-#
-# install readme
-#
-PREREQUISITES:
-
-Prior to installation of the policy processor tool (XmlToBin) you must have...
-
- 1. Java version 1.4.2
- 2. xmlParserAPIs.jar and xercesImpl.jar
-
-The above can be obtained from the Sun Developer Network web site at
-http://java.sun.com/j2se/1.4.2/download.html.
-
-XmlParserAPIs and xercesImpl jars can be obtained from
-http://www.apache.org/dist/xml/xerces-j (Xerces-J-bin.2.6.2.tar.gz,
-for example).
-
-The tool has been tested with J2SE v1.4.2_08 JRE on Linux (32-bit
-INTEL).
-
-INSTALLATION
-
-1. Set PATH to include $HOME_JAVA/bin and $HOME_JAVA/jre/bin
-   where $HOME_JAVA is your java installation directory
-
-2. Compile XmlToBin:
-   javac XmlToBin.java
-       
-USAGE
-
- See readme.xen
diff -r 99914b54f7bf -r 81576d3d1ca8 tools/misc/policyprocessor/readme.xen
--- a/tools/misc/policyprocessor/readme.xen     Thu Aug 18 18:40:02 2005
+++ /dev/null   Fri Aug 19 18:19:28 2005
@@ -1,65 +0,0 @@
-# Author: Ray Valdez, rvaldez@xxxxxxxxxx 
-# Version: 1.0
-#
-# This readme describes the policy processor tool for sHype.
-#
-
-Java program:
-
- java XmlToBin -i [file.xml] -o <file.bin> -xssid <SsidFile> -xssidconf 
<SsidConf>
-
- Command line options:
-
-        -i              inputFile:      name of policyfile (.xml)
-        -o              outputFile:     name of binary policy file (Big Endian)
-        -xssid          SsidFile:       xen ssids to named types text file
-        -xssidconf      SsidConf:      xen conflict ssids to types text file
-        -debug                          turn on debug messages
-        -help                           help. This printout
-
-Where:
-
-file.xml is the (input) xml policy file to be parsed and validated.
-The syntax for file.xml is defined in the SecurityPolicySpec.xsd file.
-file.bin is the (output) binary policy file generated by XmlToBin.
-This binary policy can be activated in sHype. The binary policy file
-is laid out in network byte order (i.e., big endian).  The SsidFile
-file contains the mapping of type enforcement (TE) ssids to the "named
-types".  Similarly, the SsidConf file contains the mapping of Chinese
-Wall (ChWall) ssids to conflict named types. The ssidFile and SsidConf
-files are used by Xen.
-
-Xml Schema and policy:
-
-The SecurityPolicySpec.xsd defines the syntax of a policy file. It
-declares the tags that are used by XmlToBin to generate the binary
-policy file. The tags that XmlToBin keys on are TE, ChWall, id, vid,
-etc.  The xml files that describe a policy are simple.  Semantic
-checking of a policy is performed mostly by XmlToBin.  A type, for
-example, is a string. No fixed values are defined for types in Xml.
-  
-A policy consists of two Xml files: definition and policy. The
-definition Xml declares the types that are permitted in the policy
-Xml.  The policy Xml contains the assignment of labels to
-subject/object (e.g., vm). This Xml file contains an explicit
-reference to the definition Xml (e.g., <url>xen_sample_def.xml</url>).
-The policy Xml is the one provided as a command line argument.
-
-
-Files:
-
-*.java                 - policy processor source 
-xen_sample_policy.xml  - sample xml policy file
-xen_sample_def.xml     - sample user defined types
-SecurityPolicySpec.xsd         - schema definition file
-
-
-To generate the sample binary policy: 
-
-export CLASSPATH=$XERCES_HOME/xercesImpl.jar:$XERCES_HOME/xmlParserAPIs.jar:.
-
-java XmlToBin -i xen_sample_policy.xml -o xen_sample_policy.bin
-
-where $XERCES_HOME is the installation directory of the Apache Xerces-J
-
-
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/misc/policyprocessor/xen_sample_def.xml
--- a/tools/misc/policyprocessor/xen_sample_def.xml     Thu Aug 18 18:40:02 2005
+++ /dev/null   Fri Aug 19 18:19:28 2005
@@ -1,46 +0,0 @@
-<?xml version="1.0"?>
-<!-- Author: Ray Valdez, rvaldez@xxxxxxxxxx -->
-<!-- example policy type definition -->
-<SecurityPolicySpec
-xmlns="http://www.ibm.com";
-xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-xsi:schemaLocation="http://www.ibm.com SecurityPolicySpec.xsd">
-
-<Definition>
-<!-- an example of a simple type enforcement type definition -->
-  <Types>
-        <TE>LOCAL-management</TE>
-        <TE>R-Company-development</TE>
-        <TE>S-Company-order</TE>
-        <TE>T-Company-advertising</TE>
-        <TE>U-Company-computing</TE>
-                <!-- TE nondevelopment  -->
-  </Types>
-
-<!-- an example of a chinese wall type definition along with conflict sets-->
-  <ChWallTypes>
-                <ChWall>Q-Company</ChWall>
-                <ChWall>R-Company</ChWall>
-                <ChWall>S-Company</ChWall>
-                <ChWall>T-Company</ChWall>
-                <ChWall>U-Company</ChWall>
-                <ChWall>V-Company</ChWall>
-                <ChWall>W-Company</ChWall>
-                <ChWall>X-Company</ChWall>
-                <ChWall>Y-Company</ChWall>
-                <ChWall>Z-Company</ChWall>
-  </ChWallTypes>
-
-  <ConflictSet>
-                <ChWall>T-Company</ChWall>
-                <ChWall>S-Company</ChWall>
-   </ConflictSet>
-
-   <ConflictSet>
-                <ChWall>R-Company</ChWall>
-                <ChWall>V-Company</ChWall>
-                <ChWall>W-Company</ChWall>
-   </ConflictSet>
-
-</Definition>
-</SecurityPolicySpec>
diff -r 99914b54f7bf -r 81576d3d1ca8 
tools/misc/policyprocessor/xen_sample_policy.xml
--- a/tools/misc/policyprocessor/xen_sample_policy.xml  Thu Aug 18 18:40:02 2005
+++ /dev/null   Fri Aug 19 18:19:28 2005
@@ -1,58 +0,0 @@
-<?xml version="1.0"?>
-<!-- Author: Ray Valdez, rvaldez@xxxxxxxxxx -->
-<!-- example xen policy file -->
-
-<SecurityPolicySpec
-xmlns="http://www.ibm.com";
-xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-xsi:schemaLocation="http://www.ibm.com SecurityPolicySpec.xsd">
-<Policy>
- <PolicyHeader>
-        <Name>xen sample policy</Name>
-        <DateTime>2005-05-20T16:56:00</DateTime>
-        <Tag>foobar</Tag>
-        <TypeDefinition>
-          <url>xen_sample_def.xml</url>
-          <hash>abcdef123456abcdef</hash>
-        </TypeDefinition>
- </PolicyHeader>
-
- <VM>
-        <id> 0 </id>
-        <TE>LOCAL-management</TE>
-        <TE>R-Company-development</TE>
-        <TE>S-Company-order</TE>
-        <TE>T-Company-advertising</TE>
-        <TE>U-Company-computing</TE>
-                <ChWall>Q-Company</ChWall>
- </VM>
-
- <VM>
-        <id> 1 </id>
-        <TE>R-Company-development</TE>
-                <ChWall>R-Company</ChWall>
- </VM>
-
- <VM>
-        <id> 2 </id>
-        <TE>S-Company-order</TE>
-                <ChWall>S-Company</ChWall>
-
- </VM>
-
- <VM>
-        <id> 3 </id>
-        <TE>T-Company-advertising</TE>
-                <ChWall>T-Company</ChWall>
- </VM>
-
-
- <VM>
-        <id> 4 </id>
-        <TE>U-Company-computing</TE>
-                <ChWall>U-Company</ChWall>
- </VM>
-
-
-</Policy>
-</SecurityPolicySpec>

_______________________________________________
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®.