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

[Xen-changelog] Store admin-specified ioport capabilities in a rangeset



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 4369fd869f51e517dea1ee0ac3929a030d86deed
# Parent  c0d8e1cf0a633939d17479da3d54e5c15f4c5909
Store admin-specified ioport capabilities in a rangeset
rather than a bitmap. arch_do_createdomain() can now
fail and the caller will clean up.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Fri Dec 30 16:12:40 2005
+++ b/xen/arch/ia64/xen/domain.c        Sat Dec 31 12:11:47 2005
@@ -181,7 +181,7 @@
        memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96);
 }
 
-void arch_do_createdomain(struct vcpu *v)
+int arch_do_createdomain(struct vcpu *v)
 {
        struct domain *d = v->domain;
        struct thread_info *ti = alloc_thread_info(v);
@@ -248,7 +248,9 @@
                }
        } else
                d->arch.mm = NULL;
-       printf ("arch_do_create_domain: domain=%p\n", d);
+       printf ("arch_do_create_domain: domain=%p\n", d);
+
+       return 0;
 }
 
 void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c)
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c   Fri Dec 30 16:12:40 2005
+++ b/xen/arch/x86/dom0_ops.c   Sat Dec 31 12:11:47 2005
@@ -17,6 +17,7 @@
 #include <asm/msr.h>
 #include <xen/trace.h>
 #include <xen/console.h>
+#include <xen/iocap.h>
 #include <asm/shadow.h>
 #include <asm/irq.h>
 #include <asm/processor.h>
@@ -141,7 +142,6 @@
         struct domain *d;
         unsigned int fp = op->u.ioport_permission.first_port;
         unsigned int np = op->u.ioport_permission.nr_ports;
-        unsigned int p;
 
         ret = -EINVAL;
         if ( (fp + np) > 65536 )
@@ -152,25 +152,13 @@
             op->u.ioport_permission.domain)) == NULL) )
             break;
 
-        ret = -ENOMEM;
-        if ( d->arch.iobmp_mask == NULL )
-        {
-            if ( (d->arch.iobmp_mask = xmalloc_array(
-                u8, IOBMP_BYTES)) == NULL )
-            {
-                put_domain(d);
-                break;
-            }
-            memset(d->arch.iobmp_mask, 0xFF, IOBMP_BYTES);
-        }
-
         ret = 0;
-        for ( p = fp; p < (fp + np); p++ )
+        if ( np > 0 )
         {
             if ( op->u.ioport_permission.allow_access )
-                clear_bit(p, d->arch.iobmp_mask);
+                ioport_range_permit(d, fp, fp + np - 1);
             else
-                set_bit(p, d->arch.iobmp_mask);
+                ioport_range_deny(d, fp, fp + np - 1);
         }
 
         put_domain(d);
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Fri Dec 30 16:12:40 2005
+++ b/xen/arch/x86/domain.c     Sat Dec 31 12:11:47 2005
@@ -20,6 +20,7 @@
 #include <xen/delay.h>
 #include <xen/softirq.h>
 #include <xen/grant_table.h>
+#include <xen/iocap.h>
 #include <asm/regs.h>
 #include <asm/mc146818rtc.h>
 #include <asm/system.h>
@@ -36,7 +37,6 @@
 #include <xen/elf.h>
 #include <asm/vmx.h>
 #include <asm/msr.h>
-#include <asm/physdev.h>
 #include <xen/kernel.h>
 #include <xen/multicall.h>
 
@@ -249,21 +249,34 @@
 #endif
 }
 
-void arch_do_createdomain(struct vcpu *v)
+int arch_do_createdomain(struct vcpu *v)
 {
     struct domain *d = v->domain;
     l1_pgentry_t gdt_l1e;
-    int vcpuid, pdpt_order;
+    int vcpuid, pdpt_order, rc;
 #ifdef __x86_64__
     int i;
 #endif
 
     if ( is_idle_task(d) )
-        return;
+        return 0;
+
+    d->arch.ioport_caps = 
+        rangeset_new(d, "I/O Ports", RANGESETF_prettyprint_hex);
+    if ( d->arch.ioport_caps == NULL )
+        return -ENOMEM;
+
+    if ( (d->shared_info = alloc_xenheap_page()) == NULL )
+        return -ENOMEM;
+
+    if ( (rc = ptwr_init(d)) != 0 )
+    {
+        free_xenheap_page(d->shared_info);
+        return rc;
+    }
 
     v->arch.schedule_tail = continue_nonidle_task;
 
-    d->shared_info = alloc_xenheap_page();
     memset(d->shared_info, 0, PAGE_SIZE);
     v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
     v->cpumap = CPUMAP_RUNANYWHERE;
@@ -307,10 +320,10 @@
                             __PAGE_HYPERVISOR);
 #endif
 
-    (void)ptwr_init(d);
-
     shadow_lock_init(d);
     INIT_LIST_HEAD(&d->arch.free_shadow_frames);
+
+    return 0;
 }
 
 void vcpu_migrate_cpu(struct vcpu *v, int newcpu)
@@ -954,8 +967,6 @@
 
     BUG_ON(!cpus_empty(d->cpumask));
 
-    physdev_destroy_state(d);
-
     ptwr_destroy(d);
 
     /* Drop the in-use references to page-table bases. */
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Fri Dec 30 16:12:40 2005
+++ b/xen/arch/x86/domain_build.c       Sat Dec 31 12:11:47 2005
@@ -16,13 +16,13 @@
 #include <xen/kernel.h>
 #include <xen/domain.h>
 #include <xen/compile.h>
+#include <xen/iocap.h>
 #include <asm/regs.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/desc.h>
 #include <asm/i387.h>
-#include <asm/physdev.h>
 #include <asm/shadow.h>
 
 static long dom0_nrpages;
@@ -96,7 +96,7 @@
 
 static void process_dom0_ioports_disable()
 {
-    unsigned long io_from, io_to, io_nr;
+    unsigned long io_from, io_to;
     char *t, *u, *s = opt_dom0_ioports_disable;
 
     if ( *s == '\0' )
@@ -126,8 +126,7 @@
         printk("Disabling dom0 access to ioport range %04lx-%04lx\n",
             io_from, io_to);
 
-        io_nr = io_to - io_from + 1;
-        physdev_modify_ioport_access_range(dom0, 0, io_from, io_nr);
+        ioport_range_deny(dom0, io_from, io_to);
     }
 }
 
@@ -183,7 +182,6 @@
     /* Machine address of next candidate page-table page. */
     unsigned long mpt_alloc;
 
-    extern void physdev_init_dom0(struct domain *);
     extern void translate_l2pgtable(
         struct domain *d, l1_pgentry_t *p2m, unsigned long l2mfn);
 
@@ -692,9 +690,6 @@
     zap_low_mappings(l2start);
     zap_low_mappings(idle_pg_table_l2);
 #endif
-    
-    /* DOM0 gets access to everything. */
-    physdev_init_dom0(d);
 
     init_domain_time(d);
 
@@ -746,18 +741,22 @@
         printk("dom0: shadow setup done\n");
     }
 
+    /* DOM0 is permitted full I/O capabilities. */
+    ioport_range_permit(dom0, 0, 0xFFFF);
+    set_bit(_DOMF_physdev_access, &dom0->domain_flags);
+
     /*
      * Modify I/O port access permissions.
      */
     /* Master Interrupt Controller (PIC). */
-    physdev_modify_ioport_access_range(dom0, 0, 0x20, 2);
+    ioport_range_deny(dom0, 0x20, 0x21);
     /* Slave Interrupt Controller (PIC). */
-    physdev_modify_ioport_access_range(dom0, 0, 0xA0, 2);
+    ioport_range_deny(dom0, 0xA0, 0xA1);
     /* Interval Timer (PIT). */
-    physdev_modify_ioport_access_range(dom0, 0, 0x40, 4);
+    ioport_range_deny(dom0, 0x40, 0x43);
     /* PIT Channel 2 / PC Speaker Control. */
-    physdev_modify_ioport_access_range(dom0, 0, 0x61, 1);
-    /* Command-line passed i/o ranges */
+    ioport_range_deny(dom0, 0x61, 0x61);
+    /* Command-line I/O ranges. */
     process_dom0_ioports_disable();
 
     return 0;
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Fri Dec 30 16:12:40 2005
+++ b/xen/arch/x86/physdev.c    Sat Dec 31 12:11:47 2005
@@ -13,20 +13,6 @@
 
 extern int ioapic_guest_read(int apicid, int address, u32 *pval);
 extern int ioapic_guest_write(int apicid, int address, u32 pval);
-
-void physdev_modify_ioport_access_range(
-    struct domain *d, int enable, int port, int num)
-{
-    int i;
-    for ( i = port; i < (port + num); i++ )
-        (enable ? clear_bit : set_bit)(i, d->arch.iobmp_mask);
-}
-
-void physdev_destroy_state(struct domain *d)
-{
-    xfree(d->arch.iobmp_mask);
-    d->arch.iobmp_mask = NULL;
-}
 
 /* Check if a domain controls a device with IO memory within frame @pfn.
  * Returns: 1 if the domain should be allowed to map @pfn, 0 otherwise.  */
@@ -120,18 +106,6 @@
     return ret;
 }
 
-/* Domain 0 has read access to all devices. */
-void physdev_init_dom0(struct domain *d)
-{
-    /* Access to all I/O ports. */
-    d->arch.iobmp_mask = xmalloc_array(u8, IOBMP_BYTES);
-    BUG_ON(d->arch.iobmp_mask == NULL);
-    memset(d->arch.iobmp_mask, 0, IOBMP_BYTES);
-
-    set_bit(_DOMF_physdev_access, &d->domain_flags);
-}
-
-
 /*
  * Local variables:
  * mode: C
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Fri Dec 30 16:12:40 2005
+++ b/xen/arch/x86/setup.c      Sat Dec 31 12:11:47 2005
@@ -388,8 +388,9 @@
 
     sort_exception_tables();
 
-    arch_do_createdomain(current);
-    
+    if ( arch_do_createdomain(current) != 0 )
+        BUG();
+
     /*
      * Map default GDT into its final positions in the idle page table. As
      * noted in arch_do_createdomain(), we must map for every possible VCPU#.
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Fri Dec 30 16:12:40 2005
+++ b/xen/arch/x86/traps.c      Sat Dec 31 12:11:47 2005
@@ -41,6 +41,7 @@
 #include <xen/softirq.h>
 #include <xen/domain_page.h>
 #include <xen/symbols.h>
+#include <xen/iocap.h>
 #include <asm/shadow.h>
 #include <asm/system.h>
 #include <asm/io.h>
@@ -622,17 +623,7 @@
     unsigned int port, unsigned int bytes,
     struct vcpu *v, struct cpu_user_regs *regs)
 {
-    struct domain *d = v->domain;
-    u16 x;
-
-    if ( d->arch.iobmp_mask != NULL )
-    {
-        x = *(u16 *)(d->arch.iobmp_mask + (port >> 3));
-        if ( (x & (((1<<bytes)-1) << (port&7))) == 0 )
-            return 1;
-    }
-
-    return 0;
+    return ioport_range_access_permitted(v->domain, port, port + bytes - 1);
 }
 
 /* Check admin limits. Silently fail the access if it is disallowed. */
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/common/domain.c
--- a/xen/common/domain.c       Fri Dec 30 16:12:40 2005
+++ b/xen/common/domain.c       Sat Dec 31 12:11:47 2005
@@ -53,24 +53,16 @@
 
     if ( !is_idle_task(d) &&
          ((evtchn_init(d) != 0) || (grant_table_create(d) != 0)) )
-    {
-        evtchn_destroy(d);
-        free_domain(d);
-        return NULL;
-    }
+        goto fail1;
     
     if ( (v = alloc_vcpu(d, 0, cpu)) == NULL )
-    {
-        grant_table_destroy(d);
-        evtchn_destroy(d);
-        free_domain(d);
-        return NULL;
-    }
+        goto fail2;
 
     rangeset_domain_initialise(d);
 
-    arch_do_createdomain(v);
-    
+    if ( arch_do_createdomain(v) != 0 )
+        goto fail3;
+
     if ( !is_idle_task(d) )
     {
         write_lock(&domlist_lock);
@@ -86,6 +78,15 @@
     }
 
     return d;
+
+ fail3:
+    rangeset_domain_destroy(d);
+ fail2:
+    grant_table_destroy(d);
+ fail1:
+    evtchn_destroy(d);
+    free_domain(d);
+    return NULL;
 }
 
 
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/common/rangeset.c
--- a/xen/common/rangeset.c     Fri Dec 30 16:12:40 2005
+++ b/xen/common/rangeset.c     Sat Dec 31 12:11:47 2005
@@ -350,7 +350,7 @@
 
     spin_lock(&r->lock);
 
-    printk("%10s {", r->name);
+    printk("%-10s {", r->name);
 
     for ( x = first_range(r); x != NULL; x = next_range(r, x) )
     {
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        Fri Dec 30 16:12:40 2005
+++ b/xen/drivers/char/ns16550.c        Sat Dec 31 12:11:47 2005
@@ -13,6 +13,7 @@
 #include <xen/irq.h>
 #include <xen/sched.h>
 #include <xen/serial.h>
+#include <xen/iocap.h>
 #include <asm/io.h>
 
 /*
@@ -233,11 +234,10 @@
 }
 
 #ifdef CONFIG_X86
-#include <asm/physdev.h>
 static void ns16550_endboot(struct serial_port *port)
 {
     struct ns16550 *uart = port->uart;
-    physdev_modify_ioport_access_range(dom0, 0, uart->io_base, 8);
+    ioport_range_deny(dom0, uart->io_base, uart->io_base + 7);
 }
 #else
 #define ns16550_endboot NULL
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Fri Dec 30 16:12:40 2005
+++ b/xen/include/asm-ia64/domain.h     Sat Dec 31 12:11:47 2005
@@ -10,7 +10,7 @@
 #include <asm/vmx_platform.h>
 #include <xen/list.h>
 
-extern void arch_do_createdomain(struct vcpu *);
+extern int arch_do_createdomain(struct vcpu *);
 
 extern void domain_relinquish_resources(struct domain *);
 
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Fri Dec 30 16:12:40 2005
+++ b/xen/include/asm-x86/domain.h      Sat Dec 31 12:11:47 2005
@@ -24,8 +24,8 @@
     /* Writable pagetables. */
     struct ptwr_info ptwr[2];
 
-    /* I/O-port access bitmap mask. */
-    u8 *iobmp_mask;       /* Address of IO bitmap mask, or NULL.      */
+    /* I/O-port admin-specified access capabilities. */
+    struct rangeset *ioport_caps;
 
     /* Shadow mode status and controls. */
     struct shadow_ops *ops;
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/include/xen/domain.h
--- a/xen/include/xen/domain.h  Fri Dec 30 16:12:40 2005
+++ b/xen/include/xen/domain.h  Sat Dec 31 12:11:47 2005
@@ -13,9 +13,9 @@
 
 extern void free_vcpu_struct(struct vcpu *v);
 
-extern void arch_do_createdomain(struct vcpu *v);
+extern int arch_do_createdomain(struct vcpu *v);
 
-extern int  arch_set_info_guest(
+extern int arch_set_info_guest(
     struct vcpu *v, struct vcpu_guest_context *c);
 
 extern void vcpu_migrate_cpu(struct vcpu *v, int newcpu);
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/include/asm-ia64/iocap.h
--- /dev/null   Fri Dec 30 16:12:40 2005
+++ b/xen/include/asm-ia64/iocap.h      Sat Dec 31 12:11:47 2005
@@ -0,0 +1,10 @@
+/******************************************************************************
+ * iocap.h
+ * 
+ * Architecture-specific per-domain I/O capabilities.
+ */
+
+#ifndef __IA64_IOCAP_H__
+#define __IA64_IOCAP_H__
+
+#endif /* __IA64_IOCAP_H__ */
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/include/asm-x86/iocap.h
--- /dev/null   Fri Dec 30 16:12:40 2005
+++ b/xen/include/asm-x86/iocap.h       Sat Dec 31 12:11:47 2005
@@ -0,0 +1,17 @@
+/******************************************************************************
+ * iocap.h
+ * 
+ * Architecture-specific per-domain I/O capabilities.
+ */
+
+#ifndef __X86_IOCAP_H__
+#define __X86_IOCAP_H__
+
+#define ioport_range_permit(d, s, e)                    \
+    rangeset_add_range((d)->arch.ioport_caps, s, e)
+#define ioport_range_deny(d, s, e)                      \
+    rangeset_remove_range((d)->arch.ioport_caps, s, e)
+#define ioport_range_access_permitted(d, s, e)          \
+    rangeset_contains_range((d)->arch.ioport_caps, s, e)
+
+#endif /* __X86_IOCAP_H__ */
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/include/xen/iocap.h
--- /dev/null   Fri Dec 30 16:12:40 2005
+++ b/xen/include/xen/iocap.h   Sat Dec 31 12:11:47 2005
@@ -0,0 +1,13 @@
+/******************************************************************************
+ * iocap.h
+ * 
+ * Per-domain I/O capabilities.
+ */
+
+#ifndef __XEN_IOCAP_H__
+#define __XEN_IOCAP_H__
+
+#include <xen/rangeset.h>
+#include <asm/iocap.h>
+
+#endif /* __XEN_IOCAP_H__ */
diff -r c0d8e1cf0a63 -r 4369fd869f51 xen/include/asm-x86/physdev.h
--- a/xen/include/asm-x86/physdev.h     Fri Dec 30 16:12:40 2005
+++ /dev/null   Sat Dec 31 12:11:47 2005
@@ -1,17 +0,0 @@
-/******************************************************************************
- * physdev.h
- */
-
-#ifndef __XEN_PHYSDEV_H__
-#define __XEN_PHYSDEV_H__
-
-#include <public/physdev.h>
-
-void physdev_modify_ioport_access_range(
-    struct domain *d, int enable, int port, int num );
-void physdev_destroy_state(struct domain *d);
-int domain_iomem_in_pfn(struct domain *p, unsigned long pfn);
-long do_physdev_op(physdev_op_t *uop);
-void physdev_init_dom0(struct domain *d);
-
-#endif /* __XEN_PHYSDEV_H__ */

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


 


Rackspace

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