# 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", §ors,
+ "info", "%u", &binfo,
+ "sector-size", "%lu", §or_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
|