diff options
author | Jan Beulich <JBeulich@suse.com> | 2012-05-30 09:21:04 +0100 |
---|---|---|
committer | Jan Beulich <JBeulich@suse.com> | 2012-05-30 09:21:04 +0100 |
commit | 346e974dcabe907927d6169c5db936ffec19358b (patch) | |
tree | 8d2b39e7320831234ab71ae0bbb2d4b6079567f1 /xen/arch/x86/hvm/nestedhvm.c | |
parent | d74ca2863a63202e09fb147a039c9af5f810e468 (diff) | |
download | xen-346e974dcabe907927d6169c5db936ffec19358b.tar.gz xen-346e974dcabe907927d6169c5db936ffec19358b.tar.bz2 xen-346e974dcabe907927d6169c5db936ffec19358b.zip |
x86: fix nested HVM initialization
- no need for calling nestedhvm_setup() explicitly (can be a normal
init-call, and can be __init)
- calling _xmalloc() for multi-page, page-aligned memory regions is
inefficient - use alloc_xenheap_pages() instead
- albeit an allocation error is unlikely here, add error handling
nevertheless (and have nestedhvm_vcpu_initialise() bail if an error
occurred during setup)
- nestedhvm_enabled() must no access d->arch.hvm_domain without first
checking that 'd' actually represents a HVM domain
Signed-off-by: Jan Beulich <JBeulich@suse.com>
Committed-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/hvm/nestedhvm.c')
-rw-r--r-- | xen/arch/x86/hvm/nestedhvm.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/xen/arch/x86/hvm/nestedhvm.c b/xen/arch/x86/hvm/nestedhvm.c index 4abbdb2d47..ba0bb8b4e1 100644 --- a/xen/arch/x86/hvm/nestedhvm.c +++ b/xen/arch/x86/hvm/nestedhvm.c @@ -25,16 +25,14 @@ #include <asm/event.h> /* for local_event_delivery_(en|dis)able */ #include <asm/paging.h> /* for paging_mode_hap() */ +static unsigned long *shadow_io_bitmap[3]; + /* Nested HVM on/off per domain */ bool_t nestedhvm_enabled(struct domain *d) { - bool_t enabled; - - enabled = !!(d->arch.hvm_domain.params[HVM_PARAM_NESTEDHVM]); - BUG_ON(enabled && !is_hvm_domain(d)); - - return enabled; + return is_hvm_domain(d) && + d->arch.hvm_domain.params[HVM_PARAM_NESTEDHVM]; } /* Nested VCPU */ @@ -76,6 +74,9 @@ nestedhvm_vcpu_initialise(struct vcpu *v) { int rc = -EOPNOTSUPP; + if ( !shadow_io_bitmap[0] ) + return -ENOMEM; + if ( !hvm_funcs.nhvm_vcpu_initialise || ((rc = hvm_funcs.nhvm_vcpu_initialise(v)) != 0) ) return rc; @@ -147,15 +148,15 @@ nestedhvm_is_n2(struct vcpu *v) * iomap[2] set set */ -static unsigned long *shadow_io_bitmap[3]; - -void +static int __init nestedhvm_setup(void) { /* Same format and size as hvm_io_bitmap (Intel needs only 2 pages). */ - unsigned int sz = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) - ? 2*PAGE_SIZE : 3*PAGE_SIZE; - unsigned int i; + unsigned int nr = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) ? 2 : 3; + unsigned int i, order = get_order_from_pages(nr); + + if ( !hvm_funcs.name ) + return 0; /* shadow_io_bitmaps can't be declared static because * they must fulfill hw requirements (page aligned section) @@ -169,13 +170,25 @@ nestedhvm_setup(void) for ( i = 0; i < ARRAY_SIZE(shadow_io_bitmap); i++ ) { - shadow_io_bitmap[i] = _xmalloc(sz, PAGE_SIZE); - memset(shadow_io_bitmap[i], ~0U, sz); + shadow_io_bitmap[i] = alloc_xenheap_pages(order, 0); + if ( !shadow_io_bitmap[i] ) + { + while ( i-- ) + { + free_xenheap_pages(shadow_io_bitmap[i], order); + shadow_io_bitmap[i] = NULL; + } + return -ENOMEM; + } + memset(shadow_io_bitmap[i], ~0U, nr << PAGE_SHIFT); } __clear_bit(0x80, shadow_io_bitmap[0]); __clear_bit(0xed, shadow_io_bitmap[1]); + + return 0; } +__initcall(nestedhvm_setup); unsigned long * nestedhvm_vcpu_iomap_get(bool_t port_80, bool_t port_ed) |