ia64/xen-unstable

changeset 8981:13e4df60caf1

Add XENFEAT feature parsing to the domain 0 builder in Xen.
Fail to boot if domain 0 requires features that Xen does not
understand or support (for domain 0).

Remove stale dom0_translate boot option.

Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Feb 23 15:55:35 2006 +0100 (2006-02-23)
parents b883ef5fad48
children 875e0e96e574
files xen/arch/x86/domain_build.c
line diff
     1.1 --- a/xen/arch/x86/domain_build.c	Thu Feb 23 15:33:08 2006 +0100
     1.2 +++ b/xen/arch/x86/domain_build.c	Thu Feb 23 15:55:35 2006 +0100
     1.3 @@ -17,6 +17,7 @@
     1.4  #include <xen/domain.h>
     1.5  #include <xen/compile.h>
     1.6  #include <xen/iocap.h>
     1.7 +#include <xen/bitops.h>
     1.8  #include <asm/regs.h>
     1.9  #include <asm/system.h>
    1.10  #include <asm/io.h>
    1.11 @@ -25,6 +26,8 @@
    1.12  #include <asm/i387.h>
    1.13  #include <asm/shadow.h>
    1.14  
    1.15 +#include <public/version.h>
    1.16 +
    1.17  static long dom0_nrpages;
    1.18  
    1.19  /*
    1.20 @@ -56,9 +59,6 @@ integer_param("dom0_max_vcpus", opt_dom0
    1.21  static unsigned int opt_dom0_shadow;
    1.22  boolean_param("dom0_shadow", opt_dom0_shadow);
    1.23  
    1.24 -static unsigned int opt_dom0_translate;
    1.25 -boolean_param("dom0_translate", opt_dom0_translate);
    1.26 -
    1.27  static char opt_dom0_ioports_disable[200] = "";
    1.28  string_param("dom0_ioports_disable", opt_dom0_ioports_disable);
    1.29  
    1.30 @@ -134,6 +134,62 @@ static void process_dom0_ioports_disable
    1.31      }
    1.32  }
    1.33  
    1.34 +static const char *feature_names[XENFEAT_NR_SUBMAPS*32] = {
    1.35 +    [XENFEAT_writable_page_tables]       = "writable_page_tables",
    1.36 +    [XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables",
    1.37 +    [XENFEAT_auto_translated_physmap]    = "auto_translated_physmap",
    1.38 +    [XENFEAT_supervisor_mode_kernel]     = "supervisor_mode_kernel",
    1.39 +    [XENFEAT_pae_pgdir_above_4gb]        = "pae_pgdir_above_4gb"
    1.40 +};
    1.41 +
    1.42 +static void parse_features(
    1.43 +    const char *feats,
    1.44 +    uint32_t supported[XENFEAT_NR_SUBMAPS],
    1.45 +    uint32_t required[XENFEAT_NR_SUBMAPS])
    1.46 +{
    1.47 +    const char *end, *p;
    1.48 +    int i, req;
    1.49 +
    1.50 +    if ( (end = strchr(feats, ',')) == NULL )
    1.51 +        end = feats + strlen(feats);
    1.52 +
    1.53 +    while ( feats < end )
    1.54 +    {
    1.55 +        p = strchr(feats, '|');
    1.56 +        if ( (p == NULL) || (p > end) )
    1.57 +            p = end;
    1.58 +
    1.59 +        req = (*feats == '!');
    1.60 +        if ( req )
    1.61 +            feats++;
    1.62 +
    1.63 +        for ( i = 0; i < XENFEAT_NR_SUBMAPS*32; i++ )
    1.64 +        {
    1.65 +            if ( feature_names[i] == NULL )
    1.66 +                continue;
    1.67 +
    1.68 +            if ( strncmp(feature_names[i], feats, p-feats) == 0 )
    1.69 +            {
    1.70 +                set_bit(i, supported);
    1.71 +                if ( req )
    1.72 +                    set_bit(i, required);
    1.73 +                break;
    1.74 +            }
    1.75 +        }
    1.76 +
    1.77 +        if ( i == XENFEAT_NR_SUBMAPS*32 )
    1.78 +        {
    1.79 +            printk("Unknown kernel feature \"%.*s\".\n",
    1.80 +                   (int)(p-feats), feats);
    1.81 +            panic("Domain 0 requires an unknown hypervisor feature.\n");
    1.82 +        }
    1.83 +
    1.84 +        feats = p;
    1.85 +        if ( *feats == '|' )
    1.86 +            feats++;
    1.87 +    }
    1.88 +}
    1.89 +
    1.90  int construct_dom0(struct domain *d,
    1.91                     unsigned long _image_start, unsigned long image_len, 
    1.92                     unsigned long _initrd_start, unsigned long initrd_len,
    1.93 @@ -188,6 +244,10 @@ int construct_dom0(struct domain *d,
    1.94      /* Machine address of next candidate page-table page. */
    1.95      unsigned long mpt_alloc;
    1.96  
    1.97 +    /* Features supported. */
    1.98 +    uint32_t dom0_features_supported[XENFEAT_NR_SUBMAPS] = { 0 };
    1.99 +    uint32_t dom0_features_required[XENFEAT_NR_SUBMAPS] = { 0 };
   1.100 +
   1.101      extern void translate_l2pgtable(
   1.102          struct domain *d, l1_pgentry_t *p2m, unsigned long l2mfn);
   1.103  
   1.104 @@ -245,8 +305,19 @@ int construct_dom0(struct domain *d,
   1.105          return -EINVAL;
   1.106      }
   1.107  
   1.108 -    if ( strstr(dsi.xen_section_string, "SHADOW=translate") )
   1.109 -        opt_dom0_translate = 1;
   1.110 +    if ( (p = strstr(dsi.xen_section_string, "FEATURES=")) != NULL )
   1.111 +    {
   1.112 +        parse_features(
   1.113 +            p + strlen("FEATURES="),
   1.114 +            dom0_features_supported,
   1.115 +            dom0_features_required);
   1.116 +        printk("Domain 0 kernel supports features = { %08x }.\n",
   1.117 +               dom0_features_supported[0]);
   1.118 +        printk("Domain 0 kernel requires features = { %08x }.\n",
   1.119 +               dom0_features_required[0]);
   1.120 +        if ( dom0_features_required[0] )
   1.121 +            panic("Domain 0 requires an unsupported hypervisor feature.\n");
   1.122 +    }
   1.123  
   1.124      /* Align load address to 4MB boundary. */
   1.125      dsi.v_start &= ~((1UL<<22)-1);
   1.126 @@ -650,11 +721,6 @@ int construct_dom0(struct domain *d,
   1.127      si->nr_pages = nr_pages;
   1.128  
   1.129      si->shared_info = virt_to_maddr(d->shared_info);
   1.130 -    if ( opt_dom0_translate )
   1.131 -    {
   1.132 -        si->shared_info  = max_page << PAGE_SHIFT;
   1.133 -        set_gpfn_from_mfn(virt_to_maddr(d->shared_info) >> PAGE_SHIFT, max_page);
   1.134 -    }
   1.135  
   1.136      si->flags        = SIF_PRIVILEGED | SIF_INITDOMAIN;
   1.137      si->pt_base      = vpt_start;
   1.138 @@ -669,7 +735,7 @@ int construct_dom0(struct domain *d,
   1.139          mfn = pfn + alloc_spfn;
   1.140  #ifndef NDEBUG
   1.141  #define REVERSE_START ((v_end - dsi.v_start) >> PAGE_SHIFT)
   1.142 -        if ( !opt_dom0_translate && (pfn > REVERSE_START) )
   1.143 +        if ( pfn > REVERSE_START )
   1.144              mfn = alloc_epfn - (pfn - REVERSE_START);
   1.145  #endif
   1.146          ((unsigned long *)vphysmap_start)[pfn] = mfn;
   1.147 @@ -720,48 +786,10 @@ int construct_dom0(struct domain *d,
   1.148  
   1.149      new_thread(v, dsi.v_kernentry, vstack_end, vstartinfo_start);
   1.150  
   1.151 -    if ( opt_dom0_shadow || opt_dom0_translate )
   1.152 +    if ( opt_dom0_shadow )
   1.153      {
   1.154 -        printk("dom0: shadow enable\n");
   1.155 -        shadow_mode_enable(d, (opt_dom0_translate
   1.156 -                               ? SHM_enable | SHM_refcounts | SHM_translate
   1.157 -                               : SHM_enable));
   1.158 -        if ( opt_dom0_translate )
   1.159 -        {
   1.160 -            printk("dom0: shadow translate\n");
   1.161 -#if defined(__i386__) && defined(CONFIG_X86_PAE)
   1.162 -            printk("FIXME: PAE code needed here: %s:%d (%s)\n",
   1.163 -                   __FILE__, __LINE__, __FUNCTION__);
   1.164 -            for ( ; ; )
   1.165 -                __asm__ __volatile__ ( "hlt" );
   1.166 -#else
   1.167 -            /* Hmm, what does this?
   1.168 -               Looks like isn't portable across 32/64 bit and pae/non-pae ...
   1.169 -               -- kraxel */
   1.170 -
   1.171 -            /* mafetter: This code is mostly a hack in order to be able to
   1.172 -             * test with dom0's which are running with shadow translate.
   1.173 -             * I expect we'll rip this out once we have a stable set of
   1.174 -             * domU clients which use the various shadow modes, but it's
   1.175 -             * useful to leave this here for now...
   1.176 -             */
   1.177 -
   1.178 -            // map this domain's p2m table into current page table,
   1.179 -            // so that we can easily access it.
   1.180 -            //
   1.181 -            ASSERT( root_get_intpte(idle_pg_table[1]) == 0 );
   1.182 -            ASSERT( pagetable_get_paddr(d->arch.phys_table) );
   1.183 -            idle_pg_table[1] = root_from_paddr(
   1.184 -                pagetable_get_paddr(d->arch.phys_table), __PAGE_HYPERVISOR);
   1.185 -            translate_l2pgtable(d, (l1_pgentry_t *)(1u << L2_PAGETABLE_SHIFT),
   1.186 -                                pagetable_get_pfn(v->arch.guest_table));
   1.187 -            idle_pg_table[1] = root_empty();
   1.188 -            local_flush_tlb();
   1.189 -#endif
   1.190 -        }
   1.191 -
   1.192 -        update_pagetables(v); /* XXX SMP */
   1.193 -        printk("dom0: shadow setup done\n");
   1.194 +        shadow_mode_enable(d, SHM_enable);
   1.195 +        update_pagetables(v);
   1.196      }
   1.197  
   1.198      rc = 0;