[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Add support for configuring feature flags when starting guests.
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |