[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |