[HVM] Re-introduce the 'apic' configuration option, default to 1.

Also simplify the HVM builder interface by doing more work in
the python wrapper, and fix mapping of shared_info page after the
change to map foreign pages by GMFN rather than MFN.

Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
kfraser@localhost.localdomain committed 2006-11-27 17:49:41 +00:00
1 parent 63e2f0bd68
commit da38d1f64b
14 files changed
+135 -170

No files matched your search

+9 -5
View File
@@ -39,14 +39,18 @@ name = "ExampleHVMDomain"
#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"
#-----------------------------------------------------------------------------
# the number of cpus guest platform has, default=1
# 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 PAE, default=1 (enabled)
#pae=1
# enable/disable HVM guest ACPI, default=0 (disabled)
#acpi=0
# Enable/disable HVM guest ACPI, default=1 (enabled)
#acpi=1
# Enable/disable HVM APIC mode, default=1 (enabled)
# Note that this option is ignored if vcpus > 1
#apic=1
# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = "" # leave to Xen to pick
+8 -5
View File
@@ -119,10 +119,11 @@ int acpi_build_tables(uint8_t *buf)
struct acpi_20_madt *madt = 0;
struct acpi_20_facs *facs;
unsigned char *dsdt;
int offset = 0, nr_vcpus = get_vcpu_nr();
int offset = 0, requires_madt;
requires_madt = ((get_vcpu_nr() > 1) || get_apic_mode());
#define inc_offset(sz) (offset = (offset + (sz) + 15) & ~15)
#define requires_madt() (nr_vcpus > 1)
facs = (struct acpi_20_facs *)&buf[offset];
memcpy(facs, &Facs, sizeof(struct acpi_20_facs));
@@ -143,7 +144,7 @@ int acpi_build_tables(uint8_t *buf)
offsetof(struct acpi_header, checksum),
sizeof(struct acpi_20_fadt));
if ( requires_madt() )
if ( requires_madt )
{
madt = (struct acpi_20_madt *)&buf[offset];
inc_offset(construct_madt(madt));
@@ -154,7 +155,7 @@ int acpi_build_tables(uint8_t *buf)
inc_offset(sizeof(struct acpi_20_xsdt));
xsdt->entry[0] = (unsigned long)fadt;
xsdt->header.length = sizeof(struct acpi_header) + sizeof(uint64_t);
if ( requires_madt() )
if ( requires_madt )
{
xsdt->entry[1] = (unsigned long)madt;
xsdt->header.length += sizeof(uint64_t);
@@ -168,7 +169,7 @@ int acpi_build_tables(uint8_t *buf)
inc_offset(sizeof(struct acpi_20_rsdt));
rsdt->entry[0] = (unsigned long)fadt;
rsdt->header.length = sizeof(struct acpi_header) + sizeof(uint32_t);
if ( requires_madt() )
if ( requires_madt )
{
rsdt->entry[1] = (unsigned long)madt;
rsdt->header.length += sizeof(uint32_t);
@@ -189,6 +190,8 @@ int acpi_build_tables(uint8_t *buf)
offsetof(struct acpi_20_rsdp, extended_checksum),
sizeof(struct acpi_20_rsdp));
#undef inc_offset
return offset;
}
+1 -1
View File
@@ -298,7 +298,7 @@ int main(void)
apic_setup();
pci_setup();
if ( get_vcpu_nr() > 1 )
if ( (get_vcpu_nr() > 1) || get_apic_mode() )
create_mp_tables();
if ( cirrus_check() )
+8 -2
View File
@@ -535,13 +535,19 @@ static struct hvm_info_table *get_hvm_info_table(void)
int get_vcpu_nr(void)
{
struct hvm_info_table *t = get_hvm_info_table();
return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
return (t ? t->nr_vcpus : 1);
}
int get_acpi_enabled(void)
{
struct hvm_info_table *t = get_hvm_info_table();
return (t ? t->acpi_enabled : 0); /* default no acpi */
return (t ? t->acpi_enabled : 1);
}
int get_apic_mode(void)
{
struct hvm_info_table *t = get_hvm_info_table();
return (t ? t->apic_mode : 1);
}
/*
+1
View File
@@ -46,6 +46,7 @@ void cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx,
/* HVM-builder info. */
int get_vcpu_nr(void);
int get_acpi_enabled(void);
int get_apic_mode(void);
/* String and memory functions */
int strcmp(const char *cs, const char *ct);
+49 -119
View File
@@ -15,6 +15,8 @@
#include <xen/hvm/params.h>
#include <xen/hvm/e820.h>
#define SCRATCH_PFN 0xFFFFF
#define HVM_LOADER_ENTR_ADDR 0x00100000
static int
parseelfimage(
@@ -24,8 +26,8 @@ loadelfimage(
char *elfbase, int xch, uint32_t dom, unsigned long *parray,
struct domain_setup_info *dsi);
static void xc_set_hvm_param(int handle,
domid_t dom, int param, unsigned long value)
int xc_set_hvm_param(
int handle, domid_t dom, int param, unsigned long value)
{
DECLARE_HYPERCALL;
xen_hvm_param_t arg;
@@ -38,14 +40,30 @@ static void xc_set_hvm_param(int handle,
arg.index = param;
arg.value = value;
if ( lock_pages(&arg, sizeof(arg)) != 0 )
{
PERROR("Could not lock memory for set parameter");
return;
}
return -1;
rc = do_xen_hypercall(handle, &hypercall);
unlock_pages(&arg, sizeof(arg));
if (rc < 0)
PERROR("set HVM parameter failed (%d)", rc);
return rc;
}
int xc_get_hvm_param(
int handle, domid_t dom, int param, unsigned long *value)
{
DECLARE_HYPERCALL;
xen_hvm_param_t arg;
int rc;
hypercall.op = __HYPERVISOR_hvm_op;
hypercall.arg[0] = HVMOP_get_param;
hypercall.arg[1] = (unsigned long)&arg;
arg.domid = dom;
arg.index = param;
if ( lock_pages(&arg, sizeof(arg)) != 0 )
return -1;
rc = do_xen_hypercall(handle, &hypercall);
unlock_pages(&arg, sizeof(arg));
*value = arg.value;
return rc;
}
static void build_e820map(void *e820_page, unsigned long long mem_size)
@@ -126,67 +144,16 @@ static void build_e820map(void *e820_page, unsigned long long mem_size)
*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map;
}
static void set_hvm_info_checksum(struct hvm_info_table *t)
{
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 hvmloader
* hvmloader will use this info to set BIOS accordingly
*/
static int set_hvm_info(int xc_handle, uint32_t dom,
xen_pfn_t *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[HVM_INFO_PFN]);
if ( va_map == NULL )
return -1;
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);
return 0;
}
static int setup_guest(int xc_handle,
uint32_t dom, int memsize,
char *image, unsigned long image_size,
vcpu_guest_context_t *ctxt,
unsigned long shared_info_frame,
unsigned int vcpus,
unsigned int pae,
unsigned int acpi,
unsigned int store_evtchn,
unsigned long *store_mfn)
vcpu_guest_context_t *ctxt)
{
xen_pfn_t *page_array = NULL;
unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT);
unsigned long shared_page_nr;
shared_info_t *shared_info;
struct xen_add_to_physmap xatp;
struct shared_info *shared_info;
void *e820_page;
struct domain_setup_info dsi;
uint64_t v_end;
@@ -247,29 +214,25 @@ static int setup_guest(int xc_handle,
loadelfimage(image, xc_handle, dom, page_array, &dsi);
if ( set_hvm_info(xc_handle, dom, page_array, vcpus, acpi) )
{
ERROR("Couldn't set hvm info for HVM guest.\n");
goto error_out;
}
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
if ( (e820_page = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
page_array[E820_MAP_PAGE >> PAGE_SHIFT])) == NULL )
E820_MAP_PAGE >> PAGE_SHIFT)) == NULL )
goto error_out;
memset(e820_page, 0, PAGE_SIZE);
build_e820map(e820_page, v_end);
munmap(e820_page, PAGE_SIZE);
/* shared_info page starts its life empty. */
if ( (shared_info = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
shared_info_frame)) == NULL )
/* Map and initialise shared_info page. */
xatp.domid = dom;
xatp.space = XENMAPSPACE_shared_info;
xatp.idx = 0;
xatp.gpfn = SCRATCH_PFN;
if ( (xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp) != 0) ||
((shared_info = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
SCRATCH_PFN)) == NULL) )
goto error_out;
memset(shared_info, 0, PAGE_SIZE);
/* Mask all upcalls... */
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
memset(&shared_info->evtchn_mask[0], 0xff,
@@ -282,14 +245,12 @@ static int setup_guest(int xc_handle,
shared_page_nr = (v_end >> PAGE_SHIFT) - 1;
/* Paranoia: clean pages. */
if ( xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr]) ||
xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr-1]) ||
xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr-2]) )
if ( xc_clear_domain_page(xc_handle, dom, shared_page_nr) ||
xc_clear_domain_page(xc_handle, dom, shared_page_nr-1) ||
xc_clear_domain_page(xc_handle, dom, shared_page_nr-2) )
goto error_out;
*store_mfn = page_array[shared_page_nr - 1];
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, shared_page_nr-1);
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_EVTCHN, store_evtchn);
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN, shared_page_nr-2);
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, shared_page_nr);
@@ -308,14 +269,9 @@ static int xc_hvm_build_internal(int xc_handle,
uint32_t domid,
int memsize,
char *image,
unsigned long image_size,
unsigned int vcpus,
unsigned int pae,
unsigned int acpi,
unsigned int store_evtchn,
unsigned long *store_mfn)
unsigned long image_size)
{
struct xen_domctl launch_domctl, domctl;
struct xen_domctl launch_domctl;
vcpu_guest_context_t ctxt;
int rc;
@@ -325,20 +281,9 @@ static int xc_hvm_build_internal(int xc_handle,
goto error_out;
}
domctl.cmd = XEN_DOMCTL_getdomaininfo;
domctl.domain = (domid_t)domid;
if ( (xc_domctl(xc_handle, &domctl) < 0) ||
((uint16_t)domctl.domain != domid) )
{
PERROR("Could not get info on domain");
goto error_out;
}
memset(&ctxt, 0, sizeof(ctxt));
if ( setup_guest(xc_handle, domid, memsize, image, image_size,
&ctxt, domctl.u.getdomaininfo.shared_info_frame,
vcpus, pae, acpi, store_evtchn, store_mfn) < 0)
if ( setup_guest(xc_handle, domid, memsize, image, image_size, &ctxt) < 0 )
{
ERROR("Error constructing guest OS");
goto error_out;
@@ -500,12 +445,7 @@ loadelfimage(
int xc_hvm_build(int xc_handle,
uint32_t domid,
int memsize,
const char *image_name,
unsigned int vcpus,
unsigned int pae,
unsigned int acpi,
unsigned int store_evtchn,
unsigned long *store_mfn)
const char *image_name)
{
char *image;
int sts;
@@ -515,10 +455,7 @@ int xc_hvm_build(int xc_handle,
((image = xc_read_image(image_name, &image_size)) == NULL) )
return -1;
sts = xc_hvm_build_internal(xc_handle, domid, memsize,
image, image_size,
vcpus, pae, acpi,
store_evtchn, store_mfn);
sts = xc_hvm_build_internal(xc_handle, domid, memsize, image, image_size);
free(image);
@@ -535,12 +472,7 @@ int xc_hvm_build_mem(int xc_handle,
uint32_t domid,
int memsize,
const char *image_buffer,
unsigned long image_size,
unsigned int vcpus,
unsigned int pae,
unsigned int acpi,
unsigned int store_evtchn,
unsigned long *store_mfn)
unsigned long image_size)
{
int sts;
unsigned long img_len;
@@ -562,9 +494,7 @@ int xc_hvm_build_mem(int xc_handle,
}
sts = xc_hvm_build_internal(xc_handle, domid, memsize,
img, img_len,
vcpus, pae, acpi,
store_evtchn, store_mfn);
img, img_len);
/* xc_inflate_buffer may return the original buffer pointer (for
for already inflated buffers), so exercise some care in freeing */
+7 -12
View File
@@ -109,22 +109,17 @@ int xc_linux_build_mem(int xc_handle,
int xc_hvm_build(int xc_handle,
uint32_t domid,
int memsize,
const char *image_name,
unsigned int vcpus,
unsigned int pae,
unsigned int acpi,
unsigned int store_evtchn,
unsigned long *store_mfn);
const char *image_name);
int xc_hvm_build_mem(int xc_handle,
uint32_t domid,
int memsize,
const char *image_buffer,
unsigned long image_size,
unsigned int vcpus,
unsigned int pae,
unsigned int acpi,
unsigned int store_evtchn,
unsigned long *store_mfn);
unsigned long image_size);
int xc_set_hvm_param(
int handle, domid_t dom, int param, unsigned long value);
int xc_get_hvm_param(
int handle, domid_t dom, int param, unsigned long *value);
#endif /* XENGUEST_H */
+1 -6
View File
@@ -192,12 +192,7 @@ __attribute__((weak)) int xc_hvm_build(
int xc_handle,
uint32_t domid,
int memsize,
const char *image_name,
unsigned int vcpus,
unsigned int pae,
unsigned int acpi,
unsigned int store_evtchn,
unsigned long *store_mfn)
const char *image_name)
{
return -ENOSYS;
}
+1
View File
@@ -123,6 +123,7 @@ otherConfig
image.hvm.vncconsole
image.hvm.pae
image.hvm.acpi (also in image.devices)
image.hvm.apic
image.hvm.devices.boot
image.hvm.devices.fda
image.hvm.devices.fdb
+1
View File
@@ -56,6 +56,7 @@ image
- vncconsole
- pae
- acpi
- apic
(parseDeviceModel)
- boot
- fda
+34 -11
View File
@@ -13,10 +13,13 @@
#include <netinet/tcp.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "xenctrl.h"
#include <xen/hvm/hvm_info_table.h>
#include <xen/hvm/params.h>
/* Needed for Python versions earlier than 2.3. */
#ifndef PyMODINIT_FUNC
@@ -371,26 +374,46 @@ static PyObject *pyxc_hvm_build(XcObject *self,
PyObject *kwds)
{
uint32_t dom;
struct hvm_info_table *va_hvm;
uint8_t *va_map, sum;
char *image;
int store_evtchn;
int memsize;
int vcpus = 1;
int pae = 0;
int acpi = 0;
unsigned long store_mfn = 0;
int i, store_evtchn, memsize, vcpus = 1, pae = 0, acpi = 0, apic = 1;
unsigned long store_mfn;
static char *kwd_list[] = { "domid", "store_evtchn",
"memsize", "image", "vcpus", "pae", "acpi",
NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiisiii", kwd_list,
"apic", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|iiii", kwd_list,
&dom, &store_evtchn, &memsize,
&image, &vcpus, &pae, &acpi) )
&image, &vcpus, &pae, &acpi, &apic) )
return NULL;
if ( xc_hvm_build(self->xc_handle, dom, memsize, image,
vcpus, pae, acpi, store_evtchn, &store_mfn) != 0 )
if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
return PyErr_SetFromErrno(xc_error);
/* Set up the HVM info table. */
va_map = xc_map_foreign_range(self->xc_handle, dom, PAGE_SIZE,
PROT_READ | PROT_WRITE,
HVM_INFO_PFN);
if ( va_map == NULL )
return PyErr_SetFromErrno(xc_error);
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->apic_mode = apic;
va_hvm->nr_vcpus = vcpus;
for ( i = 0, sum = 0; i < va_hvm->length; i++ )
sum += ((uint8_t *)va_hvm)[i];
va_hvm->checksum = -sum;
munmap(va_map, PAGE_SIZE);
xc_get_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_PFN, &store_mfn);
xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_EVTCHN,
store_evtchn);
return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
}
+6 -5
View File
@@ -252,7 +252,6 @@ class HVMImageHandler(ImageHandler):
ImageHandler.__init__(self, vm, imageConfig, deviceConfig)
self.shutdownWatch = None
def configure(self, imageConfig, deviceConfig):
ImageHandler.configure(self, imageConfig, deviceConfig)
@@ -277,9 +276,9 @@ 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.pae = int(sxp.child_value(imageConfig, 'pae', 1))
self.acpi = int(sxp.child_value(imageConfig, 'acpi', 1))
self.apic = int(sxp.child_value(imageConfig, 'apic', 1))
def buildDomain(self):
store_evtchn = self.vm.getStorePort()
@@ -293,6 +292,7 @@ class HVMImageHandler(ImageHandler):
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)
self.register_shutdown_watch()
@@ -302,7 +302,8 @@ class HVMImageHandler(ImageHandler):
memsize = mem_mb,
vcpus = self.vm.getVCpuCount(),
pae = self.pae,
acpi = self.acpi)
acpi = self.acpi,
apic = self.apic)
# Return a list of cmd line args to the device models based on the
# xm config file
+8 -4
View File
@@ -174,13 +174,17 @@ gopts.var('cpus', val='CPUS',
use="CPUS to run the domain on.")
gopts.var('pae', val='PAE',
fn=set_int, default=0,
fn=set_int, default=1,
use="Disable or enable PAE of HVM domain.")
gopts.var('acpi', val='ACPI',
fn=set_int, default=0,
fn=set_int, default=1,
use="Disable or enable ACPI of HVM domain.")
gopts.var('apic', val='APIC',
fn=set_int, default=1,
use="Disable or enable APIC mode.")
gopts.var('vcpus', val='VCPUS',
fn=set_int, default=1,
use="# of Virtual CPUS in domain.")
@@ -664,9 +668,9 @@ def configure_hvm(config_image, vals):
'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw',
'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten',
'sdl', 'display', 'xauthority',
'acpi', 'usb', 'usbdevice', 'keymap' ]
'acpi', 'apic', 'usb', 'usbdevice', 'keymap' ]
for a in args:
if (vals.__dict__[a]):
if a in vals.__dict__ and vals.__dict__[a] is not None:
config_image.append([a, vals.__dict__[a]])
config_image.append(['vncpasswd', vals.vncpasswd])
+1
View File
@@ -34,6 +34,7 @@ struct hvm_info_table {
uint32_t length;
uint8_t checksum;
uint8_t acpi_enabled;
uint8_t apic_mode;
uint32_t nr_vcpus;
};
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.