[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.