diff --git a/tools/examples/xmexample.hvm b/tools/examples/xmexample.hvm index 5cdf03dc83..a551c7a7b6 100644 --- a/tools/examples/xmexample.hvm +++ b/tools/examples/xmexample.hvm @@ -30,6 +30,9 @@ name = "ExampleHVMDomain" # the number of cpus guest platform has, default=1 #vcpus=1 +# enable/disable HVM guest PAE, default=0 (disabled) +#pae=0 + # enable/disable HVM guest ACPI, default=0 (disabled) #acpi=0 diff --git a/tools/libxc/xc_hvm_build.c b/tools/libxc/xc_hvm_build.c index 173f091d8c..dc88aae041 100644 --- a/tools/libxc/xc_hvm_build.c +++ b/tools/libxc/xc_hvm_build.c @@ -137,7 +137,7 @@ set_hvm_info_checksum(struct hvm_info_table *t) */ static int set_hvm_info(int xc_handle, uint32_t dom, unsigned long *pfn_list, unsigned int vcpus, - unsigned int acpi, unsigned int apic) + unsigned int pae, unsigned int acpi, unsigned int apic) { char *va_map; struct hvm_info_table *va_hvm; @@ -159,6 +159,7 @@ static int set_hvm_info(int xc_handle, uint32_t dom, va_hvm->length = sizeof(struct hvm_info_table); va_hvm->acpi_enabled = acpi; va_hvm->apic_enabled = apic; + va_hvm->pae_enabled = pae; va_hvm->nr_vcpus = vcpus; set_hvm_info_checksum(va_hvm); @@ -176,7 +177,8 @@ static int setup_guest(int xc_handle, unsigned long shared_info_frame, unsigned int control_evtchn, unsigned int vcpus, - unsigned int acpi, + unsigned int pae, + unsigned int acpi, unsigned int apic, unsigned int store_evtchn, unsigned long *store_mfn) @@ -265,7 +267,7 @@ static int setup_guest(int xc_handle, goto error_out; } - if ( set_hvm_info(xc_handle, dom, page_array, vcpus, acpi, apic) ) { + if ( set_hvm_info(xc_handle, dom, page_array, vcpus, pae, acpi, apic) ) { fprintf(stderr, "Couldn't set hvm info for HVM guest.\n"); goto error_out; } @@ -345,7 +347,8 @@ int xc_hvm_build(int xc_handle, const char *image_name, unsigned int control_evtchn, unsigned int vcpus, - unsigned int acpi, + unsigned int pae, + unsigned int acpi, unsigned int apic, unsigned int store_evtchn, unsigned long *store_mfn) @@ -400,7 +403,7 @@ int xc_hvm_build(int xc_handle, ctxt->flags = VGCF_HVM_GUEST; if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages, ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn, - vcpus, acpi, apic, store_evtchn, store_mfn) < 0) + vcpus, pae, acpi, apic, store_evtchn, store_mfn) < 0) { ERROR("Error constructing guest OS"); goto error_out; diff --git a/tools/libxc/xc_ia64_stubs.c b/tools/libxc/xc_ia64_stubs.c index 2a403cd3b6..c732f4aee0 100644 --- a/tools/libxc/xc_ia64_stubs.c +++ b/tools/libxc/xc_ia64_stubs.c @@ -626,9 +626,10 @@ int xc_hvm_build(int xc_handle, int memsize, const char *image_name, unsigned int control_evtchn, - unsigned int lapic, unsigned int vcpus, + unsigned int pae, unsigned int acpi, + unsigned int apic, unsigned int store_evtchn, unsigned long *store_mfn) { diff --git a/tools/libxc/xenguest.h b/tools/libxc/xenguest.h index 4a11b5ec1b..c612eeb2e7 100644 --- a/tools/libxc/xenguest.h +++ b/tools/libxc/xenguest.h @@ -40,7 +40,7 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, unsigned long nr_pfns, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, - unsigned long *console_mfn); + unsigned long *console_mfn); int xc_linux_build(int xc_handle, uint32_t domid, @@ -59,6 +59,7 @@ int xc_hvm_build(int xc_handle, const char *image_name, unsigned int control_evtchn, unsigned int vcpus, + unsigned int pae, unsigned int acpi, unsigned int apic, unsigned int store_evtchn, diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 1a3431e2b1..5e6d98587b 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -366,20 +366,21 @@ static PyObject *pyxc_hvm_build(XcObject *self, int control_evtchn, store_evtchn; int memsize; int vcpus = 1; + int pae = 0; int acpi = 0; int apic = 0; unsigned long store_mfn = 0; static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn", - "memsize", "image", "vcpus", "acpi", "apic", + "memsize", "image", "vcpus", "pae", "acpi", "apic", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisiii", kwd_list, + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisiiii", kwd_list, &dom, &control_evtchn, &store_evtchn, - &memsize, &image, &vcpus, &acpi, &apic) ) + &memsize, &image, &vcpus, &pae, &acpi, &apic) ) return NULL; if ( xc_hvm_build(self->xc_handle, dom, memsize, image, control_evtchn, - vcpus, acpi, apic, store_evtchn, &store_mfn) != 0 ) + vcpus, pae, acpi, apic, store_evtchn, &store_mfn) != 0 ) return PyErr_SetFromErrno(xc_error); return Py_BuildValue("{s:i}", "store_mfn", store_mfn); diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index 8a73ed90b6..e1c720deeb 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -191,8 +191,8 @@ class HVMImageHandler(ImageHandler): ImageHandler.configure(self, imageConfig, deviceConfig) info = xc.xeninfo() - if not 'hvm' in info['xen_caps']: - raise VmError("Not an HVM capable platform, we stop creating!") + if not 'hvm' in info['xen_caps']: + raise VmError("Not an HVM capable platform, we stop creating!") self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig) self.device_model = sxp.child_value(imageConfig, 'device_model') @@ -210,6 +210,8 @@ class HVMImageHandler(ImageHandler): self.dmargs += self.configVNC(imageConfig) + self.pae = int(sxp.child_value(imageConfig, 'pae', 0)) + self.acpi = int(sxp.child_value(imageConfig, 'acpi', 0)) self.apic = int(sxp.child_value(imageConfig, 'apic', 0)) @@ -227,6 +229,7 @@ class HVMImageHandler(ImageHandler): log.debug("store_evtchn = %d", store_evtchn) log.debug("memsize = %d", self.vm.getMemoryTarget() / 1024) log.debug("vcpus = %d", self.vm.getVCpuCount()) + log.debug("pae = %d", self.pae) log.debug("acpi = %d", self.acpi) log.debug("apic = %d", self.apic) @@ -238,6 +241,7 @@ class HVMImageHandler(ImageHandler): store_evtchn = store_evtchn, memsize = self.vm.getMemoryTarget() / 1024, vcpus = self.vm.getVCpuCount(), + pae = self.pae, acpi = self.acpi, apic = self.apic) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 1c698005bf..bfc96fa307 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -161,6 +161,10 @@ gopts.var('cpus', val='CPUS', fn=set_int, default=None, use="CPUS to run the domain on.") +gopts.var('pae', val='PAE', + fn=set_int, default=0, + use="Disable or enable PAE of HVM domain.") + gopts.var('acpi', val='ACPI', fn=set_int, default=0, use="Disable or enable ACPI of HVM domain.") @@ -545,7 +549,7 @@ def configure_vifs(config_devs, vals): def configure_hvm(config_image, vals): """Create the config for HVM devices. """ - args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb', + args = [ 'device_model', 'pae', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb', 'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'audio', 'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'acpi', 'apic', 'xauthority' ] diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index bbe3af8ea6..2c7569ec68 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -175,10 +175,12 @@ static void hvm_get_info(struct domain *d) if ( validate_hvm_info(t) ) { d->arch.hvm_domain.nr_vcpus = t->nr_vcpus; d->arch.hvm_domain.apic_enabled = t->apic_enabled; + d->arch.hvm_domain.pae_enabled = t->pae_enabled; } else { printk("Bad hvm info table\n"); d->arch.hvm_domain.nr_vcpus = 1; d->arch.hvm_domain.apic_enabled = 0; + d->arch.hvm_domain.pae_enabled = 0; } unmap_domain_page(p); diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index e685579c75..08a9115a32 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -662,19 +662,21 @@ static void vmx_vmexit_do_cpuid(unsigned long input, struct cpu_user_regs *regs) cpuid(input, &eax, &ebx, &ecx, &edx); - if (input == 1) + if ( input == 1 ) { if ( hvm_apic_support(v->domain) && !vlapic_global_enabled((VLAPIC(v))) ) clear_bit(X86_FEATURE_APIC, &edx); #if CONFIG_PAGING_LEVELS < 3 - clear_bit(X86_FEATURE_PSE, &edx); clear_bit(X86_FEATURE_PAE, &edx); + clear_bit(X86_FEATURE_PSE, &edx); clear_bit(X86_FEATURE_PSE36, &edx); #else if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 ) { + if ( !v->domain->arch.hvm_domain.pae_enabled ) + clear_bit(X86_FEATURE_PAE, &edx); clear_bit(X86_FEATURE_PSE, &edx); clear_bit(X86_FEATURE_PSE36, &edx); } diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h index 5edca8a078..812f91d76d 100644 --- a/xen/include/asm-x86/hvm/domain.h +++ b/xen/include/asm-x86/hvm/domain.h @@ -34,6 +34,7 @@ struct hvm_domain { unsigned long shared_page_va; unsigned int nr_vcpus; unsigned int apic_enabled; + unsigned int pae_enabled; struct hvm_virpit vpit; struct hvm_virpic vpic; diff --git a/xen/include/public/hvm/hvm_info_table.h b/xen/include/public/hvm/hvm_info_table.h index a576eb7c50..38911800cc 100644 --- a/xen/include/public/hvm/hvm_info_table.h +++ b/xen/include/public/hvm/hvm_info_table.h @@ -17,7 +17,7 @@ struct hvm_info_table { uint8_t checksum; uint8_t acpi_enabled; uint8_t apic_enabled; - uint8_t pad[1]; + uint8_t pae_enabled; uint32_t nr_vcpus; };