mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
Provide an option to disable ACPI from the VMX config file.
By default ACPI is disabled. Signed-off-by: Yu Ke <ke.yu@intel.com> Signed-off-by: Jun Nakajima <jun.nakajima@intel.com> Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
This commit is contained in:
1 parent
24b0fec3cf
commit
cfa0fac2c2
9 files changed
+140
-49
No files matched your search
@@ -30,6 +30,9 @@ name = "ExampleVMXDomain"
|
||||
# the number of cpus guest platform has, default=1
|
||||
vcpus=1
|
||||
|
||||
# enable/disalbe vmx guest ACPI, default=0 (disabled)
|
||||
#acpi=0
|
||||
|
||||
# List of which CPUS this domain is allowed to use, default Xen picks
|
||||
#cpus = "" # leave to Xen to pick
|
||||
#cpus = "0" # all vcpus run on CPU0
|
||||
|
||||
@@ -24,7 +24,7 @@ include $(XEN_ROOT)/tools/Rules.mk
|
||||
# The emulator code lives in ROM space
|
||||
TEXTADDR=0x000D0000
|
||||
|
||||
DEFINES=-DDEBUG -D_ACPI_ -DTEXTADDR=$(TEXTADDR)
|
||||
DEFINES=-DDEBUG -DTEXTADDR=$(TEXTADDR)
|
||||
XENINC=-I$(XEN_ROOT)/tools/libxc
|
||||
|
||||
LD = ld
|
||||
|
||||
@@ -24,23 +24,75 @@
|
||||
|
||||
extern int puts(const char *s);
|
||||
|
||||
#define VCPU_NR_PAGE 0x0009F000
|
||||
#define VCPU_NR_OFFSET 0x00000800
|
||||
#define VCPU_MAGIC 0x76637075 /* "vcpu" */
|
||||
#define HVM_INFO_PAGE 0x0009F000
|
||||
#define HVM_INFO_OFFSET 0x00000800
|
||||
|
||||
struct hvm_info_table {
|
||||
char signature[8]; /* "HVM INFO" */
|
||||
uint32_t length;
|
||||
uint8_t checksum;
|
||||
uint8_t acpi_enabled;
|
||||
uint8_t pad[2];
|
||||
uint32_t nr_vcpus;
|
||||
};
|
||||
|
||||
static struct hvm_info_table *table = NULL;
|
||||
|
||||
/* xc_vmx_builder wrote vcpu block at 0x9F800. Return it. */
|
||||
static int
|
||||
get_vcpu_nr(void)
|
||||
checksum_valid(uint8_t *ptr, int len)
|
||||
{
|
||||
unsigned int *vcpus;
|
||||
uint8_t sum=0;
|
||||
int i;
|
||||
|
||||
vcpus = (unsigned int *)(VCPU_NR_PAGE + VCPU_NR_OFFSET);
|
||||
if (vcpus[0] != VCPU_MAGIC) {
|
||||
puts("Bad vcpus magic, set vcpu number to 1 by default.\n");
|
||||
return 1;
|
||||
for (i = 0; i < len; i++)
|
||||
sum += ptr[i];
|
||||
|
||||
return (sum == 0);
|
||||
}
|
||||
|
||||
/* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
|
||||
static struct hvm_info_table *
|
||||
get_hvm_info_table(void)
|
||||
{
|
||||
struct hvm_info_table *t;
|
||||
char signature[] = "HVM INFO";
|
||||
int i;
|
||||
|
||||
if (table != NULL)
|
||||
return table;
|
||||
|
||||
t = (struct hvm_info_table *)(HVM_INFO_PAGE + HVM_INFO_OFFSET);
|
||||
|
||||
/* strncmp(t->signature, "HVM INFO", 8) */
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (signature[i] != t->signature[i]) {
|
||||
puts("Bad hvm info signature\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return vcpus[1];
|
||||
if (!checksum_valid((uint8_t *)t, t->length)) {
|
||||
puts("Bad hvm info checksum\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
table = t;
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
int
|
||||
get_vcpu_nr(void)
|
||||
{
|
||||
struct hvm_info_table *t = get_hvm_info_table();
|
||||
return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
|
||||
}
|
||||
|
||||
int
|
||||
get_acpi_enabled(void)
|
||||
{
|
||||
struct hvm_info_table *t = get_hvm_info_table();
|
||||
return (t ? t->acpi_enabled : 0); /* default no acpi */
|
||||
}
|
||||
|
||||
static void *
|
||||
|
||||
@@ -24,12 +24,10 @@
|
||||
#include "machine.h"
|
||||
#include "roms.h"
|
||||
|
||||
#ifdef _ACPI_
|
||||
#include "acpi.h"
|
||||
#include "../acpi/acpi2_0.h" // for ACPI_PHYSICAL_ADDRESS
|
||||
int acpi_madt_update(unsigned char* acpi_start);
|
||||
#endif
|
||||
|
||||
int get_acpi_enabled(void);
|
||||
|
||||
/*
|
||||
* C runtime start off
|
||||
@@ -120,18 +118,17 @@ main(void)
|
||||
memcpy((void *)0xC0000,
|
||||
vgabios_stdvga, sizeof(vgabios_stdvga));
|
||||
}
|
||||
#ifdef _ACPI_
|
||||
puts("Loading ACPI ...\n");
|
||||
|
||||
acpi_madt_update(acpi);
|
||||
|
||||
if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
|
||||
/* make sure acpi table does not overlap rombios
|
||||
* currently acpi less than 8K will be OK.
|
||||
*/
|
||||
memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi));
|
||||
if (get_acpi_enabled() != 0) {
|
||||
puts("Loading ACPI ...\n");
|
||||
acpi_madt_update((unsigned char*)acpi);
|
||||
if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
|
||||
/* make sure acpi table does not overlap rombios
|
||||
* currently acpi less than 8K will be OK.
|
||||
*/
|
||||
memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
puts("Loading VMXAssist ...\n");
|
||||
memcpy((void *)TEXTADDR, vmxassist, sizeof(vmxassist));
|
||||
|
||||
+48
-18
@@ -33,8 +33,17 @@
|
||||
#define E820_MAP_NR_OFFSET 0x000001E8
|
||||
#define E820_MAP_OFFSET 0x000002D0
|
||||
|
||||
#define VCPU_NR_PAGE 0x0009F000
|
||||
#define VCPU_NR_OFFSET 0x00000800
|
||||
#define HVM_INFO_PAGE 0x0009F000
|
||||
#define HVM_INFO_OFFSET 0x00000800
|
||||
|
||||
struct hvm_info_table {
|
||||
char signature[8]; /* "HVM INFO" */
|
||||
uint32_t length;
|
||||
uint8_t checksum;
|
||||
uint8_t acpi_enabled;
|
||||
uint8_t pad[2];
|
||||
uint32_t nr_vcpus;
|
||||
};
|
||||
|
||||
struct e820entry {
|
||||
uint64_t addr;
|
||||
@@ -119,26 +128,45 @@ static unsigned char build_e820map(void *e820_page, unsigned long mem_size)
|
||||
return (*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use E820 reserved memory 0x9F800 to pass number of vcpus to vmxloader
|
||||
* vmxloader will use it to config ACPI MADT table
|
||||
*/
|
||||
#define VCPU_MAGIC 0x76637075 /* "vcpu" */
|
||||
static int set_vcpu_nr(int xc_handle, uint32_t dom,
|
||||
unsigned long *pfn_list, unsigned int vcpus)
|
||||
static void
|
||||
set_hvm_info_checksum(struct hvm_info_table *t)
|
||||
{
|
||||
char *va_map;
|
||||
unsigned int *va_vcpus;
|
||||
uint8_t *ptr = (uint8_t *)t, sum = 0;
|
||||
unsigned int i;
|
||||
|
||||
t->checksum = 0;
|
||||
|
||||
for (i = 0; i < t->length; i++)
|
||||
sum += *ptr++;
|
||||
|
||||
t->checksum = -sum;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use E820 reserved memory 0x9F800 to pass HVM info to vmxloader
|
||||
* vmxloader will use this info to set BIOS accordingly
|
||||
*/
|
||||
static int set_hvm_info(int xc_handle, uint32_t dom,
|
||||
unsigned long *pfn_list, unsigned int vcpus,
|
||||
unsigned int acpi)
|
||||
{
|
||||
char *va_map;
|
||||
struct hvm_info_table *va_hvm;
|
||||
|
||||
va_map = xc_map_foreign_range(xc_handle, dom,
|
||||
PAGE_SIZE, PROT_READ|PROT_WRITE,
|
||||
pfn_list[VCPU_NR_PAGE >> PAGE_SHIFT]);
|
||||
pfn_list[HVM_INFO_PAGE >> PAGE_SHIFT]);
|
||||
if ( va_map == NULL )
|
||||
return -1;
|
||||
|
||||
va_vcpus = (unsigned int *)(va_map + VCPU_NR_OFFSET);
|
||||
va_vcpus[0] = VCPU_MAGIC;
|
||||
va_vcpus[1] = vcpus;
|
||||
va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
|
||||
memset(va_hvm, 0, sizeof(*va_hvm));
|
||||
strncpy(va_hvm->signature, "HVM INFO", 8);
|
||||
va_hvm->length = sizeof(struct hvm_info_table);
|
||||
va_hvm->acpi_enabled = acpi;
|
||||
va_hvm->nr_vcpus = vcpus;
|
||||
|
||||
set_hvm_info_checksum(va_hvm);
|
||||
|
||||
munmap(va_map, PAGE_SIZE);
|
||||
|
||||
@@ -281,6 +309,7 @@ static int setup_guest(int xc_handle,
|
||||
unsigned int control_evtchn,
|
||||
unsigned int lapic,
|
||||
unsigned int vcpus,
|
||||
unsigned int acpi,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn)
|
||||
{
|
||||
@@ -490,8 +519,8 @@ static int setup_guest(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if (set_vcpu_nr(xc_handle, dom, page_array, vcpus)) {
|
||||
fprintf(stderr, "Couldn't set vcpu number for VMX guest.\n");
|
||||
if (set_hvm_info(xc_handle, dom, page_array, vcpus, acpi)) {
|
||||
fprintf(stderr, "Couldn't set hvm info for VMX guest.\n");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
@@ -581,6 +610,7 @@ int xc_vmx_build(int xc_handle,
|
||||
unsigned int control_evtchn,
|
||||
unsigned int lapic,
|
||||
unsigned int vcpus,
|
||||
unsigned int acpi,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn)
|
||||
{
|
||||
@@ -644,7 +674,7 @@ int xc_vmx_build(int xc_handle,
|
||||
|
||||
if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
|
||||
ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn,
|
||||
lapic, vcpus, store_evtchn, store_mfn) < 0)
|
||||
lapic, vcpus, acpi, store_evtchn, store_mfn) < 0)
|
||||
{
|
||||
ERROR("Error constructing guest OS");
|
||||
goto error_out;
|
||||
|
||||
@@ -58,6 +58,7 @@ int xc_vmx_build(int xc_handle,
|
||||
unsigned int control_evtchn,
|
||||
unsigned int lapic,
|
||||
unsigned int vcpus,
|
||||
unsigned int acpi,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn);
|
||||
|
||||
|
||||
@@ -364,19 +364,20 @@ static PyObject *pyxc_vmx_build(XcObject *self,
|
||||
int control_evtchn, store_evtchn;
|
||||
int vcpus = 1;
|
||||
int lapic = 0;
|
||||
int acpi = 0;
|
||||
int memsize;
|
||||
unsigned long store_mfn = 0;
|
||||
|
||||
static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
|
||||
"memsize", "image", "lapic", "vcpus", NULL };
|
||||
"memsize", "image", "lapic", "vcpus", "acpi",NULL };
|
||||
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisii", kwd_list,
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisiii", kwd_list,
|
||||
&dom, &control_evtchn, &store_evtchn,
|
||||
&memsize, &image, &lapic, &vcpus) )
|
||||
&memsize, &image, &lapic, &vcpus,&acpi) )
|
||||
return NULL;
|
||||
|
||||
if ( xc_vmx_build(self->xc_handle, dom, memsize, image, control_evtchn,
|
||||
lapic, vcpus, store_evtchn, &store_mfn) != 0 )
|
||||
lapic, vcpus, acpi, store_evtchn, &store_mfn) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
|
||||
|
||||
@@ -214,6 +214,8 @@ class VmxImageHandler(ImageHandler):
|
||||
if not lapic is None:
|
||||
self.lapic = int(lapic)
|
||||
|
||||
self.acpi = int(sxp.child_value(imageConfig, 'acpi', 0))
|
||||
|
||||
def buildDomain(self):
|
||||
# Create an event channel
|
||||
self.device_channel = xc.evtchn_alloc_unbound(dom=self.vm.getDomid(),
|
||||
@@ -229,6 +231,7 @@ class VmxImageHandler(ImageHandler):
|
||||
log.debug("memsize = %d", self.vm.getMemoryTarget() / 1024)
|
||||
log.debug("lapic = %d", self.lapic)
|
||||
log.debug("vcpus = %d", self.vm.getVCpuCount())
|
||||
log.debug("acpi = %d", self.acpi)
|
||||
|
||||
return xc.vmx_build(dom = self.vm.getDomid(),
|
||||
image = self.kernel,
|
||||
@@ -236,9 +239,9 @@ class VmxImageHandler(ImageHandler):
|
||||
store_evtchn = store_evtchn,
|
||||
memsize = self.vm.getMemoryTarget() / 1024,
|
||||
lapic = self.lapic,
|
||||
acpi = self.acpi,
|
||||
vcpus = self.vm.getVCpuCount())
|
||||
|
||||
|
||||
# Return a list of cmd line args to the device models based on the
|
||||
# xm config file
|
||||
def parseDeviceModelArgs(self, imageConfig, deviceConfig):
|
||||
|
||||
@@ -164,6 +164,10 @@ gopts.var('lapic', val='LAPIC',
|
||||
fn=set_int, default=0,
|
||||
use="Disable or enable local APIC of VMX domain.")
|
||||
|
||||
gopts.var('acpi', val='ACPI',
|
||||
fn=set_int, default=0,
|
||||
use="Disable or enable ACPI of VMX domain.")
|
||||
|
||||
gopts.var('vcpus', val='VCPUS',
|
||||
fn=set_int, default=1,
|
||||
use="# of Virtual CPUS in domain.")
|
||||
@@ -531,7 +535,7 @@ def configure_vmx(config_image, vals):
|
||||
args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb',
|
||||
'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'audio',
|
||||
'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic',
|
||||
'xauthority' ]
|
||||
'xauthority', 'acpi' ]
|
||||
for a in args:
|
||||
if (vals.__dict__[a]):
|
||||
config_image.append([a, vals.__dict__[a]])
|
||||
|
||||