# HG changeset patch
# User Ian.Campbell@xxxxxxxxxxxxx
# Node ID b470657718fec949adbaa9cdba6a202f8314dd4b
# Parent 3b74edc512b48d90ae12a000d0b16e94dd9bbcf4
Add support for configuring feature flags when starting guests.
Guest configuration files may now contain a features= declaration
listing the features which should be enabled in a | separated
list.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
diff -r 3b74edc512b4 -r b470657718fe tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c Mon Feb 27 16:56:08 2006
+++ b/tools/libxc/xc_linux_build.c Mon Feb 27 17:27:52 2006
@@ -45,6 +45,77 @@
#ifdef __ia64__
#define probe_aout9(image,image_size,load_funcs) 1
#endif
+
+static const char *feature_names[XENFEAT_NR_SUBMAPS*32] = {
+ [XENFEAT_writable_page_tables] = "writable_page_tables",
+ [XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables",
+ [XENFEAT_auto_translated_physmap] = "auto_translated_physmap",
+ [XENFEAT_supervisor_mode_kernel] = "supervisor_mode_kernel",
+ [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb"
+};
+
+static inline void set_feature_bit (int nr, uint32_t *addr)
+{
+ addr[nr>>5] |= (1<<(nr&31));
+}
+
+static inline int test_feature_bit(int nr, uint32_t *addr)
+{
+ return !!(addr[nr>>5] & (1<<(nr&31)));
+}
+
+static int parse_features(
+ const char *feats,
+ uint32_t supported[XENFEAT_NR_SUBMAPS],
+ uint32_t required[XENFEAT_NR_SUBMAPS])
+{
+ const char *end, *p;
+ int i, req;
+
+ if ( (end = strchr(feats, ',')) == NULL )
+ end = feats + strlen(feats);
+
+ while ( feats < end )
+ {
+ p = strchr(feats, '|');
+ if ( (p == NULL) || (p > end) )
+ p = end;
+
+ req = (*feats == '!');
+ if ( req )
+ feats++;
+
+ for ( i = 0; i < XENFEAT_NR_SUBMAPS*32; i++ )
+ {
+ if ( feature_names[i] == NULL )
+ continue;
+
+ if ( strncmp(feature_names[i], feats, p-feats) == 0 )
+ {
+ set_feature_bit(i, supported);
+ if ( required && req )
+ set_feature_bit(i, required);
+ break;
+ }
+ }
+
+ if ( i == XENFEAT_NR_SUBMAPS*32 )
+ {
+ ERROR("Unknown feature \"%.*s\".\n", (int)(p-feats), feats);
+ if ( req )
+ {
+ ERROR("Kernel requires an unknown hypervisor feature.\n");
+ return -EINVAL;
+ }
+ }
+
+ feats = p;
+ if ( *feats == '|' )
+ feats++;
+ }
+
+ return -EINVAL;
+}
static int probeimageformat(char *image,
unsigned long image_size,
@@ -344,7 +415,8 @@
unsigned long shared_info_frame,
unsigned long flags,
unsigned int store_evtchn, unsigned long *store_mfn,
- unsigned int console_evtchn, unsigned long *console_mfn)
+ unsigned int console_evtchn, unsigned long *console_mfn,
+ uint32_t required_features[XENFEAT_NR_SUBMAPS])
{
unsigned long *page_array = NULL;
struct load_funcs load_funcs;
@@ -483,7 +555,8 @@
unsigned long shared_info_frame,
unsigned long flags,
unsigned int store_evtchn, unsigned long *store_mfn,
- unsigned int console_evtchn, unsigned long *console_mfn)
+ unsigned int console_evtchn, unsigned long *console_mfn,
+ uint32_t required_features[XENFEAT_NR_SUBMAPS])
{
unsigned long *page_array = NULL;
unsigned long count, i, hypercall_pfn;
@@ -515,8 +588,9 @@
unsigned long vpt_start;
unsigned long vpt_end;
unsigned long v_end;
- unsigned shadow_mode_enabled;
unsigned long guest_store_mfn, guest_console_mfn, guest_shared_info_mfn;
+ unsigned long shadow_mode_enabled;
+ uint32_t supported_features[XENFEAT_NR_SUBMAPS] = { 0, };
rc = probeimageformat(image, image_size, &load_funcs);
if ( rc != 0 )
@@ -534,8 +608,6 @@
goto error_out;
}
- shadow_mode_enabled = !!strstr(dsi.xen_guest_string,
- "SHADOW=translate");
/*
* Why do we need this? The number of page-table frames depends on the
* size of the bootstrap address space. But the size of the address space
@@ -637,6 +709,35 @@
(load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
&dsi);
+ /* Parse and validate kernel features. */
+ p = strstr(dsi.xen_guest_string, "FEATURES=");
+ if ( p != NULL )
+ {
+ if ( !parse_features(p + strlen("FEATURES="),
+ supported_features,
+ required_features) )
+ {
+ ERROR("Failed to parse guest kernel features.\n");
+ goto error_out;
+ }
+
+ fprintf(stderr, "Supported features = { %08x }.\n",
+ supported_features[0]);
+ fprintf(stderr, "Required features = { %08x }.\n",
+ required_features[0]);
+ }
+
+ for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ )
+ {
+ if ( (supported_features[i]&required_features[i]) !=
required_features[i] )
+ {
+ ERROR("Guest kernel does not support a required feature.\n");
+ goto error_out;
+ }
+ }
+
+ shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap,
required_features);
+
/* Load the initial ramdisk image. */
if ( initrd_len != 0 )
{
@@ -870,6 +971,7 @@
const char *image_name,
const char *ramdisk_name,
const char *cmdline,
+ const char *features,
unsigned long flags,
unsigned int store_evtchn,
unsigned long *store_mfn,
@@ -886,6 +988,16 @@
char *image = NULL;
unsigned long image_size, initrd_size=0;
unsigned long vstartinfo_start, vkern_entry, vstack_start;
+ uint32_t features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, };
+
+ if ( features != NULL )
+ {
+ if ( !parse_features(features, features_bitmap, NULL) )
+ {
+ PERROR("Failed to parse configured features\n");
+ goto error_out;
+ }
+ }
if ( (nr_pages = get_tot_pages(xc_handle, domid)) < 0 )
{
@@ -940,7 +1052,8 @@
&vstack_start, ctxt, cmdline,
op.u.getdomaininfo.shared_info_frame,
flags, store_evtchn, store_mfn,
- console_evtchn, console_mfn) < 0 )
+ console_evtchn, console_mfn,
+ features_bitmap) < 0 )
{
ERROR("Error constructing guest OS");
goto error_out;
diff -r 3b74edc512b4 -r b470657718fe tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h Mon Feb 27 16:56:08 2006
+++ b/tools/libxc/xenguest.h Mon Feb 27 17:27:52 2006
@@ -47,6 +47,7 @@
const char *image_name,
const char *ramdisk_name,
const char *cmdline,
+ const char *features,
unsigned long flags,
unsigned int store_evtchn,
unsigned long *store_mfn,
diff -r 3b74edc512b4 -r b470657718fe tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Mon Feb 27 16:56:08 2006
+++ b/tools/python/xen/lowlevel/xc/xc.c Mon Feb 27 17:27:52 2006
@@ -326,27 +326,29 @@
PyObject *kwds)
{
uint32_t dom;
- char *image, *ramdisk = NULL, *cmdline = "";
+ char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
int flags = 0;
int store_evtchn, console_evtchn;
unsigned long store_mfn = 0;
unsigned long console_mfn = 0;
- static char *kwd_list[] = { "dom", "store_evtchn",
- "console_evtchn", "image",
+ static char *kwd_list[] = { "dom", "store_evtchn",
+ "console_evtchn", "image",
/* optional */
- "ramdisk", "cmdline", "flags", NULL };
-
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssi", kwd_list,
+ "ramdisk", "cmdline", "flags",
+ "features", NULL };
+
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssis", kwd_list,
&dom, &store_evtchn,
- &console_evtchn, &image,
+ &console_evtchn, &image,
/* optional */
- &ramdisk, &cmdline, &flags) )
+ &ramdisk, &cmdline, &flags,
+ &features) )
return NULL;
if ( xc_linux_build(self->xc_handle, dom, image,
- ramdisk, cmdline, flags,
- store_evtchn, &store_mfn,
+ ramdisk, cmdline, features, flags,
+ store_evtchn, &store_mfn,
console_evtchn, &console_mfn) != 0 ) {
if (!errno)
errno = EINVAL;
diff -r 3b74edc512b4 -r b470657718fe tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Mon Feb 27 16:56:08 2006
+++ b/tools/python/xen/xend/image.py Mon Feb 27 17:27:52 2006
@@ -68,6 +68,7 @@
self.kernel = None
self.ramdisk = None
self.cmdline = None
+ self.features = None
self.configure(imageConfig, deviceConfig)
@@ -89,6 +90,7 @@
if args:
self.cmdline += " " + args
self.ramdisk = get_cfg("ramdisk", '')
+ self.features = get_cfg("features", '')
self.vm.storeVm(("image/ostype", self.ostype),
("image/kernel", self.kernel),
@@ -175,13 +177,15 @@
log.debug("cmdline = %s", self.cmdline)
log.debug("ramdisk = %s", self.ramdisk)
log.debug("vcpus = %d", self.vm.getVCpuCount())
+ log.debug("features = %s", self.features)
return xc.linux_build(dom = self.vm.getDomid(),
image = self.kernel,
store_evtchn = store_evtchn,
console_evtchn = console_evtchn,
cmdline = self.cmdline,
- ramdisk = self.ramdisk)
+ ramdisk = self.ramdisk,
+ features = self.features)
class HVMImageHandler(ImageHandler):
diff -r 3b74edc512b4 -r b470657718fe tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Mon Feb 27 16:56:08 2006
+++ b/tools/python/xen/xm/create.py Mon Feb 27 17:27:52 2006
@@ -137,6 +137,10 @@
fn=set_value, default='',
use="Path to ramdisk.")
+gopts.var('features', val='FEATURES',
+ fn=set_value, default='',
+ use="Features to enable in guest kernel")
+
gopts.var('builder', val='FUNCTION',
fn=set_value, default='linux',
use="Function to use to build the domain.")
@@ -445,6 +449,8 @@
config_image.append(['root', cmdline_root])
if vals.extra:
config_image.append(['args', vals.extra])
+ if vals.features:
+ config_image.append(['features', vals.features])
if vals.builder == 'hvm':
configure_hvm(config_image, vals)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|