ia64/xen-unstable

changeset 9054:b470657718fe

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@xensource.com>
author Ian.Campbell@xensource.com
date Mon Feb 27 17:27:52 2006 +0000 (2006-02-27)
parents 3b74edc512b4
children 5262bd9e9d19
files tools/libxc/xc_linux_build.c tools/libxc/xenguest.h tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/image.py tools/python/xen/xm/create.py
line diff
     1.1 --- a/tools/libxc/xc_linux_build.c	Mon Feb 27 16:56:08 2006 +0000
     1.2 +++ b/tools/libxc/xc_linux_build.c	Mon Feb 27 17:27:52 2006 +0000
     1.3 @@ -46,6 +46,77 @@
     1.4  #define probe_aout9(image,image_size,load_funcs) 1
     1.5  #endif
     1.6  
     1.7 +static const char *feature_names[XENFEAT_NR_SUBMAPS*32] = {
     1.8 +    [XENFEAT_writable_page_tables]       = "writable_page_tables",
     1.9 +    [XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables",
    1.10 +    [XENFEAT_auto_translated_physmap]    = "auto_translated_physmap",
    1.11 +    [XENFEAT_supervisor_mode_kernel]     = "supervisor_mode_kernel",
    1.12 +    [XENFEAT_pae_pgdir_above_4gb]        = "pae_pgdir_above_4gb"
    1.13 +};
    1.14 +
    1.15 +static inline void set_feature_bit (int nr, uint32_t *addr)
    1.16 +{
    1.17 +    addr[nr>>5] |= (1<<(nr&31));
    1.18 +}
    1.19 +
    1.20 +static inline int test_feature_bit(int nr, uint32_t *addr)
    1.21 +{
    1.22 +    return !!(addr[nr>>5] & (1<<(nr&31)));
    1.23 +}
    1.24 +
    1.25 +static int parse_features(
    1.26 +    const char *feats,
    1.27 +    uint32_t supported[XENFEAT_NR_SUBMAPS],
    1.28 +    uint32_t required[XENFEAT_NR_SUBMAPS])
    1.29 +{
    1.30 +    const char *end, *p;
    1.31 +    int i, req;
    1.32 +
    1.33 +    if ( (end = strchr(feats, ',')) == NULL )
    1.34 +        end = feats + strlen(feats);
    1.35 +
    1.36 +    while ( feats < end )
    1.37 +    {
    1.38 +        p = strchr(feats, '|');
    1.39 +        if ( (p == NULL) || (p > end) )
    1.40 +            p = end;
    1.41 +
    1.42 +        req = (*feats == '!');
    1.43 +        if ( req )
    1.44 +            feats++;
    1.45 +
    1.46 +        for ( i = 0; i < XENFEAT_NR_SUBMAPS*32; i++ )
    1.47 +        {
    1.48 +            if ( feature_names[i] == NULL )
    1.49 +                continue;
    1.50 +
    1.51 +            if ( strncmp(feature_names[i], feats, p-feats) == 0 )
    1.52 +            {
    1.53 +                set_feature_bit(i, supported);
    1.54 +                if ( required && req )
    1.55 +                    set_feature_bit(i, required);
    1.56 +                break;
    1.57 +            }
    1.58 +        }
    1.59 +
    1.60 +        if ( i == XENFEAT_NR_SUBMAPS*32 )
    1.61 +        {
    1.62 +            ERROR("Unknown feature \"%.*s\".\n", (int)(p-feats), feats);
    1.63 +            if ( req )
    1.64 +            {
    1.65 +                ERROR("Kernel requires an unknown hypervisor feature.\n");
    1.66 +                return -EINVAL;
    1.67 +            }
    1.68 +        }
    1.69 +
    1.70 +        feats = p;
    1.71 +        if ( *feats == '|' )
    1.72 +            feats++;
    1.73 +    }
    1.74 +
    1.75 +    return -EINVAL;
    1.76 +}
    1.77 +
    1.78  static int probeimageformat(char *image,
    1.79                              unsigned long image_size,
    1.80                              struct load_funcs *load_funcs)
    1.81 @@ -344,7 +415,8 @@ static int setup_guest(int xc_handle,
    1.82                         unsigned long shared_info_frame,
    1.83                         unsigned long flags,
    1.84                         unsigned int store_evtchn, unsigned long *store_mfn,
    1.85 -                       unsigned int console_evtchn, unsigned long *console_mfn)
    1.86 +                       unsigned int console_evtchn, unsigned long *console_mfn,
    1.87 +                       uint32_t required_features[XENFEAT_NR_SUBMAPS])
    1.88  {
    1.89      unsigned long *page_array = NULL;
    1.90      struct load_funcs load_funcs;
    1.91 @@ -483,7 +555,8 @@ static int setup_guest(int xc_handle,
    1.92                         unsigned long shared_info_frame,
    1.93                         unsigned long flags,
    1.94                         unsigned int store_evtchn, unsigned long *store_mfn,
    1.95 -                       unsigned int console_evtchn, unsigned long *console_mfn)
    1.96 +                       unsigned int console_evtchn, unsigned long *console_mfn,
    1.97 +                       uint32_t required_features[XENFEAT_NR_SUBMAPS])
    1.98  {
    1.99      unsigned long *page_array = NULL;
   1.100      unsigned long count, i, hypercall_pfn;
   1.101 @@ -515,8 +588,9 @@ static int setup_guest(int xc_handle,
   1.102      unsigned long vpt_start;
   1.103      unsigned long vpt_end;
   1.104      unsigned long v_end;
   1.105 -    unsigned shadow_mode_enabled;
   1.106      unsigned long guest_store_mfn, guest_console_mfn, guest_shared_info_mfn;
   1.107 +    unsigned long shadow_mode_enabled;
   1.108 +    uint32_t supported_features[XENFEAT_NR_SUBMAPS] = { 0, };
   1.109  
   1.110      rc = probeimageformat(image, image_size, &load_funcs);
   1.111      if ( rc != 0 )
   1.112 @@ -534,8 +608,6 @@ static int setup_guest(int xc_handle,
   1.113          goto error_out;
   1.114      }
   1.115  
   1.116 -    shadow_mode_enabled = !!strstr(dsi.xen_guest_string,
   1.117 -                                   "SHADOW=translate");
   1.118      /*
   1.119       * Why do we need this? The number of page-table frames depends on the 
   1.120       * size of the bootstrap address space. But the size of the address space 
   1.121 @@ -637,6 +709,35 @@ static int setup_guest(int xc_handle,
   1.122      (load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
   1.123                             &dsi);
   1.124  
   1.125 +    /* Parse and validate kernel features. */
   1.126 +    p = strstr(dsi.xen_guest_string, "FEATURES=");
   1.127 +    if ( p != NULL )
   1.128 +    {
   1.129 +        if ( !parse_features(p + strlen("FEATURES="),
   1.130 +                             supported_features,
   1.131 +                             required_features) )
   1.132 +        {
   1.133 +            ERROR("Failed to parse guest kernel features.\n");
   1.134 +            goto error_out;
   1.135 +        }
   1.136 +
   1.137 +        fprintf(stderr, "Supported features  = { %08x }.\n",
   1.138 +                supported_features[0]);
   1.139 +        fprintf(stderr, "Required features   = { %08x }.\n",
   1.140 +                required_features[0]);
   1.141 +    }
   1.142 +
   1.143 +    for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ )
   1.144 +    {
   1.145 +        if ( (supported_features[i]&required_features[i]) != required_features[i] )
   1.146 +        {
   1.147 +            ERROR("Guest kernel does not support a required feature.\n");
   1.148 +            goto error_out;
   1.149 +        }
   1.150 +    }
   1.151 +
   1.152 +    shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap, required_features);
   1.153 +
   1.154      /* Load the initial ramdisk image. */
   1.155      if ( initrd_len != 0 )
   1.156      {
   1.157 @@ -870,6 +971,7 @@ int xc_linux_build(int xc_handle,
   1.158                     const char *image_name,
   1.159                     const char *ramdisk_name,
   1.160                     const char *cmdline,
   1.161 +                   const char *features,
   1.162                     unsigned long flags,
   1.163                     unsigned int store_evtchn,
   1.164                     unsigned long *store_mfn,
   1.165 @@ -886,6 +988,16 @@ int xc_linux_build(int xc_handle,
   1.166      char         *image = NULL;
   1.167      unsigned long image_size, initrd_size=0;
   1.168      unsigned long vstartinfo_start, vkern_entry, vstack_start;
   1.169 +    uint32_t      features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, };
   1.170 +
   1.171 +    if ( features != NULL )
   1.172 +    {
   1.173 +        if ( !parse_features(features, features_bitmap, NULL) )
   1.174 +        {
   1.175 +            PERROR("Failed to parse configured features\n");
   1.176 +            goto error_out;
   1.177 +        }
   1.178 +    }
   1.179  
   1.180      if ( (nr_pages = get_tot_pages(xc_handle, domid)) < 0 )
   1.181      {
   1.182 @@ -940,7 +1052,8 @@ int xc_linux_build(int xc_handle,
   1.183                       &vstack_start, ctxt, cmdline,
   1.184                       op.u.getdomaininfo.shared_info_frame,
   1.185                       flags, store_evtchn, store_mfn,
   1.186 -                     console_evtchn, console_mfn) < 0 )
   1.187 +                     console_evtchn, console_mfn,
   1.188 +                     features_bitmap) < 0 )
   1.189      {
   1.190          ERROR("Error constructing guest OS");
   1.191          goto error_out;
     2.1 --- a/tools/libxc/xenguest.h	Mon Feb 27 16:56:08 2006 +0000
     2.2 +++ b/tools/libxc/xenguest.h	Mon Feb 27 17:27:52 2006 +0000
     2.3 @@ -47,6 +47,7 @@ int xc_linux_build(int xc_handle,
     2.4                     const char *image_name,
     2.5                     const char *ramdisk_name,
     2.6                     const char *cmdline,
     2.7 +                   const char *features,
     2.8                     unsigned long flags,
     2.9                     unsigned int store_evtchn,
    2.10                     unsigned long *store_mfn,
     3.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Mon Feb 27 16:56:08 2006 +0000
     3.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Mon Feb 27 17:27:52 2006 +0000
     3.3 @@ -326,27 +326,29 @@ static PyObject *pyxc_linux_build(XcObje
     3.4                                    PyObject *kwds)
     3.5  {
     3.6      uint32_t dom;
     3.7 -    char *image, *ramdisk = NULL, *cmdline = "";
     3.8 +    char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
     3.9      int flags = 0;
    3.10      int store_evtchn, console_evtchn;
    3.11      unsigned long store_mfn = 0;
    3.12      unsigned long console_mfn = 0;
    3.13  
    3.14 -    static char *kwd_list[] = { "dom", "store_evtchn", 
    3.15 -                                "console_evtchn", "image", 
    3.16 +    static char *kwd_list[] = { "dom", "store_evtchn",
    3.17 +                                "console_evtchn", "image",
    3.18  				/* optional */
    3.19 -				"ramdisk", "cmdline", "flags", NULL };
    3.20 +				"ramdisk", "cmdline", "flags",
    3.21 +				"features", NULL };
    3.22  
    3.23 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssi", kwd_list,
    3.24 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssis", kwd_list,
    3.25                                        &dom, &store_evtchn,
    3.26 -				      &console_evtchn, &image, 
    3.27 +				      &console_evtchn, &image,
    3.28  				      /* optional */
    3.29 -				      &ramdisk, &cmdline, &flags) )
    3.30 +				      &ramdisk, &cmdline, &flags,
    3.31 +				      &features) )
    3.32          return NULL;
    3.33  
    3.34      if ( xc_linux_build(self->xc_handle, dom, image,
    3.35 -                        ramdisk, cmdline, flags,
    3.36 -                        store_evtchn, &store_mfn, 
    3.37 +                        ramdisk, cmdline, features, flags,
    3.38 +                        store_evtchn, &store_mfn,
    3.39  			console_evtchn, &console_mfn) != 0 ) {
    3.40          if (!errno)
    3.41               errno = EINVAL;
     4.1 --- a/tools/python/xen/xend/image.py	Mon Feb 27 16:56:08 2006 +0000
     4.2 +++ b/tools/python/xen/xend/image.py	Mon Feb 27 17:27:52 2006 +0000
     4.3 @@ -68,6 +68,7 @@ class ImageHandler:
     4.4          self.kernel = None
     4.5          self.ramdisk = None
     4.6          self.cmdline = None
     4.7 +        self.features = None
     4.8  
     4.9          self.configure(imageConfig, deviceConfig)
    4.10  
    4.11 @@ -89,6 +90,7 @@ class ImageHandler:
    4.12          if args:
    4.13              self.cmdline += " " + args
    4.14          self.ramdisk = get_cfg("ramdisk", '')
    4.15 +        self.features = get_cfg("features", '')
    4.16          
    4.17          self.vm.storeVm(("image/ostype", self.ostype),
    4.18                          ("image/kernel", self.kernel),
    4.19 @@ -175,13 +177,15 @@ class LinuxImageHandler(ImageHandler):
    4.20          log.debug("cmdline        = %s", self.cmdline)
    4.21          log.debug("ramdisk        = %s", self.ramdisk)
    4.22          log.debug("vcpus          = %d", self.vm.getVCpuCount())
    4.23 +        log.debug("features       = %s", self.features)
    4.24  
    4.25          return xc.linux_build(dom            = self.vm.getDomid(),
    4.26                                image          = self.kernel,
    4.27                                store_evtchn   = store_evtchn,
    4.28                                console_evtchn = console_evtchn,
    4.29                                cmdline        = self.cmdline,
    4.30 -                              ramdisk        = self.ramdisk)
    4.31 +                              ramdisk        = self.ramdisk,
    4.32 +                              features       = self.features)
    4.33  
    4.34  class HVMImageHandler(ImageHandler):
    4.35  
     5.1 --- a/tools/python/xen/xm/create.py	Mon Feb 27 16:56:08 2006 +0000
     5.2 +++ b/tools/python/xen/xm/create.py	Mon Feb 27 17:27:52 2006 +0000
     5.3 @@ -137,6 +137,10 @@ gopts.var('ramdisk', val='FILE',
     5.4            fn=set_value, default='',
     5.5            use="Path to ramdisk.")
     5.6  
     5.7 +gopts.var('features', val='FEATURES',
     5.8 +          fn=set_value, default='',
     5.9 +          use="Features to enable in guest kernel")
    5.10 +
    5.11  gopts.var('builder', val='FUNCTION',
    5.12            fn=set_value, default='linux',
    5.13            use="Function to use to build the domain.")
    5.14 @@ -445,6 +449,8 @@ def configure_image(vals):
    5.15          config_image.append(['root', cmdline_root])
    5.16      if vals.extra:
    5.17          config_image.append(['args', vals.extra])
    5.18 +    if vals.features:
    5.19 +        config_image.append(['features', vals.features])
    5.20  
    5.21      if vals.builder == 'hvm':
    5.22          configure_hvm(config_image, vals)