ia64/xen-unstable

changeset 11285:551495fa7b3e

merge
author Ian Campbell <ian.campbell@xensource.com>
date Wed Aug 23 18:39:17 2006 +0100 (2006-08-23)
parents 51a98a6c2c05 2eb8efcc70d1
children 45ce6a654a41
files
line diff
     1.1 --- a/tools/libxc/xc_load_bin.c	Wed Aug 23 18:38:08 2006 +0100
     1.2 +++ b/tools/libxc/xc_load_bin.c	Wed Aug 23 18:39:17 2006 +0100
     1.3 @@ -227,7 +227,7 @@ static int parsebinimage(const char *ima
     1.4      dsi->v_kernstart = dsi->v_start;
     1.5      dsi->v_kernend = dsi->v_end;
     1.6      dsi->v_kernentry = image_info->entry_addr;
     1.7 -    dsi->__xen_guest_string = "";
     1.8 +    dsi->__xen_guest_string = NULL;
     1.9  
    1.10      return 0;
    1.11  }
     2.1 --- a/tools/libxc/xc_load_elf.c	Wed Aug 23 18:38:08 2006 +0100
     2.2 +++ b/tools/libxc/xc_load_elf.c	Wed Aug 23 18:39:17 2006 +0100
     2.3 @@ -109,15 +109,13 @@ static const char *xen_guest_string(stru
     2.4  {
     2.5      const char *p = xen_guest_lookup(dsi, type);
     2.6  
     2.7 -    DPRINTF("found __xen_guest entry for type %#x = \"%s\"\n",
     2.8 -            type, p);
     2.9 -
    2.10      /*
    2.11       * We special case this since the __xen_guest_section treats the
    2.12       * mere precense of the BSD_SYMTAB string as true or false.
    2.13       */
    2.14      if ( type == XEN_ELFNOTE_BSD_SYMTAB )
    2.15          return p ? "yes" : "no";
    2.16 +
    2.17      return p;
    2.18  }
    2.19  
    2.20 @@ -141,9 +139,6 @@ static unsigned long long xen_guest_nume
    2.21      if (type == XEN_ELFNOTE_HYPERCALL_PAGE)
    2.22          value = dsi->v_start + (value<<PAGE_SHIFT);
    2.23  
    2.24 -    DPRINTF("found __xen_guest entry for type %#x = %#llx\n",
    2.25 -            type, value);
    2.26 -
    2.27      *defined = 1;
    2.28      return value;
    2.29  }
    2.30 @@ -177,6 +172,9 @@ static Elf_Note *xen_elfnote_lookup(stru
    2.31  {
    2.32      Elf_Note *note;
    2.33  
    2.34 +    if ( !dsi->__elfnote_section )
    2.35 +        return NULL;
    2.36 +
    2.37      for ( note = (Elf_Note *)dsi->__elfnote_section;
    2.38            note < (Elf_Note *)dsi->__elfnote_section_end;
    2.39            note = ELFNOTE_NEXT(note) )
    2.40 @@ -188,7 +186,6 @@ static Elf_Note *xen_elfnote_lookup(stru
    2.41              return note;
    2.42      }
    2.43  
    2.44 -    DPRINTF("unable to find Xen ELF note with type %#x\n", type);
    2.45      return NULL;
    2.46  }
    2.47  
    2.48 @@ -203,9 +200,6 @@ const char *xen_elfnote_string(struct do
    2.49      if ( note == NULL )
    2.50          return NULL;
    2.51  
    2.52 -    DPRINTF("found Xen ELF note type %#x = \"%s\"\n",
    2.53 -            type, (char *)ELFNOTE_DESC(note));
    2.54 -
    2.55      return (const char *)ELFNOTE_DESC(note);
    2.56  }
    2.57  
    2.58 @@ -297,7 +291,6 @@ static int parseelfimage(const char *ima
    2.59          shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
    2.60          if ( !is_xen_elfnote_section(image, shdr) )
    2.61              continue;
    2.62 -        DPRINTF("found note section containing Xen entries\n");
    2.63          dsi->__elfnote_section = (void *)image + shdr->sh_offset;
    2.64          dsi->__elfnote_section_end =
    2.65              (void *)image + shdr->sh_offset + shdr->sh_size;
    2.66 @@ -312,7 +305,6 @@ static int parseelfimage(const char *ima
    2.67              shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
    2.68              if ( is_xen_guest_section(shdr, shstrtab) )
    2.69              {
    2.70 -                DPRINTF("found a legacy __xen_guest section\n");
    2.71                  dsi->__xen_guest_string = (char *)image + shdr->sh_offset;
    2.72                  break;
    2.73              }
    2.74 @@ -343,16 +335,18 @@ static int parseelfimage(const char *ima
    2.75      }
    2.76      else
    2.77      {
    2.78 -#ifdef __ia64__
    2.79 -        dsi->__elfnote_section = NULL;
    2.80 -        dsi->__xen_guest_string = "";
    2.81 -#else
    2.82 +#if defined(__x86_64__) || defined(__i386__)
    2.83          ERROR("Not a Xen-ELF image: "
    2.84                "No ELF notes or '__xen_guest' section found.");
    2.85          return -EINVAL;
    2.86  #endif
    2.87      }
    2.88  
    2.89 +    /*
    2.90 +     * If we have ELF notes then PAE=yes implies that we must support
    2.91 +     * the extended cr3 syntax. Otherwise we need to find the
    2.92 +     * [extended-cr3] syntax in the __xen_guest string.
    2.93 +     */
    2.94      dsi->pae_kernel = PAEKERN_no;
    2.95      if ( dsi->__elfnote_section )
    2.96      {
     3.1 --- a/tools/libxc/xg_private.h	Wed Aug 23 18:38:08 2006 +0100
     3.2 +++ b/tools/libxc/xg_private.h	Wed Aug 23 18:39:17 2006 +0100
     3.3 @@ -159,7 +159,7 @@ struct domain_setup_info
     3.4       * pickup the correct one and retain backwards compatibility.
     3.5       */
     3.6      void *__elfnote_section, *__elfnote_section_end;
     3.7 -    char *__xen_guest_string;
     3.8 +    const char *__xen_guest_string;
     3.9  };
    3.10  
    3.11  typedef int (*parseimagefunc)(const char *image, unsigned long image_size,
     4.1 --- a/xen/arch/x86/domain_build.c	Wed Aug 23 18:38:08 2006 +0100
     4.2 +++ b/xen/arch/x86/domain_build.c	Wed Aug 23 18:39:17 2006 +0100
     4.3 @@ -290,14 +290,7 @@ int construct_dom0(struct domain *d,
     4.4      if ( (rc = parseelfimage(&dsi)) != 0 )
     4.5          return rc;
     4.6  
     4.7 -    if ( dsi.__elfnote_section == NULL )
     4.8 -    {
     4.9 -        printk("Not a Xen-ELF image: no Xen ELF notes were found.\n");
    4.10 -        return -EINVAL;
    4.11 -    }
    4.12 -
    4.13 -    p = xen_elfnote_string(&dsi, XEN_ELFNOTE_PAE_MODE);
    4.14 -    dom0_pae = !!(p != NULL && strcmp(p, "yes") == 0);
    4.15 +    dom0_pae = (dsi.pae_kernel != PAEKERN_no);
    4.16      xen_pae  = (CONFIG_PAGING_LEVELS == 3);
    4.17      if ( dom0_pae != xen_pae )
    4.18      {
    4.19 @@ -306,8 +299,8 @@ int construct_dom0(struct domain *d,
    4.20          return -EINVAL;
    4.21      }
    4.22  
    4.23 -    if ( xen_pae )
    4.24 -        set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist);
    4.25 +    if ( xen_pae && dsi.pae_kernel == PAEKERN_extended_cr3 )
    4.26 +            set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist);
    4.27  
    4.28      if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL )
    4.29      {
     5.1 --- a/xen/common/elf.c	Wed Aug 23 18:38:08 2006 +0100
     5.2 +++ b/xen/common/elf.c	Wed Aug 23 18:39:17 2006 +0100
     5.3 @@ -23,6 +23,80 @@ static inline int is_loadable_phdr(Elf_P
     5.4  }
     5.5  
     5.6  /*
     5.7 + * Fallback for kernels containing only the legacy __xen_guest string
     5.8 + * and no ELF notes.
     5.9 + */
    5.10 +static int is_xen_guest_section(Elf_Shdr *shdr, const char *shstrtab)
    5.11 +{
    5.12 +    return strcmp(&shstrtab[shdr->sh_name], "__xen_guest") == 0;
    5.13 +}
    5.14 +
    5.15 +static const char *xen_guest_lookup(struct domain_setup_info *dsi, int type)
    5.16 +{
    5.17 +    const char *xenguest_fallbacks[] = {
    5.18 +        [XEN_ELFNOTE_ENTRY] = "VIRT_ENTRY=",
    5.19 +        [XEN_ELFNOTE_HYPERCALL_PAGE] = "HYPERCALL_PAGE=",
    5.20 +        [XEN_ELFNOTE_VIRT_BASE] = "VIRT_BASE=",
    5.21 +        [XEN_ELFNOTE_PADDR_OFFSET] = "ELF_PADDR_OFFSET=",
    5.22 +        [XEN_ELFNOTE_XEN_VERSION] = "XEN_VER=",
    5.23 +        [XEN_ELFNOTE_GUEST_OS] = "GUEST_OS=",
    5.24 +        [XEN_ELFNOTE_GUEST_VERSION] = "GUEST_VER=",
    5.25 +        [XEN_ELFNOTE_LOADER] = "LOADER=",
    5.26 +        [XEN_ELFNOTE_PAE_MODE] = "PAE=",
    5.27 +        [XEN_ELFNOTE_FEATURES] = "FEATURES=",
    5.28 +        [XEN_ELFNOTE_BSD_SYMTAB] = "BSD_SYMTAB=",
    5.29 +    };
    5.30 +    const char *fallback;
    5.31 +    const char *p;
    5.32 +
    5.33 +    if ( type > sizeof(xenguest_fallbacks) )
    5.34 +        return NULL;
    5.35 +
    5.36 +    if ( (fallback = xenguest_fallbacks[type]) == NULL )
    5.37 +        return NULL;
    5.38 +
    5.39 +    if ( (p = strstr(dsi->__xen_guest_string,fallback)) == NULL )
    5.40 +        return NULL;
    5.41 +
    5.42 +    return p + strlen(fallback);
    5.43 +}
    5.44 +
    5.45 +static const char *xen_guest_string(struct domain_setup_info *dsi, int type)
    5.46 +{
    5.47 +    const char *p = xen_guest_lookup(dsi, type);
    5.48 +
    5.49 +    /*
    5.50 +     * We special case this since the __xen_guest_section treats the
    5.51 +     * mere precense of the BSD_SYMTAB string as true or false.
    5.52 +     */
    5.53 +    if ( type == XEN_ELFNOTE_BSD_SYMTAB )
    5.54 +        return p ? "yes" : "no";
    5.55 +
    5.56 +    return p;
    5.57 +}
    5.58 +
    5.59 +static unsigned long long xen_guest_numeric(struct domain_setup_info *dsi,
    5.60 +                                                   int type, int *defined)
    5.61 +{
    5.62 +    const char *p = xen_guest_lookup(dsi, type);
    5.63 +    unsigned long long value;
    5.64 +
    5.65 +    if ( p == NULL )
    5.66 +        return 0;
    5.67 +
    5.68 +    value = simple_strtoull(p, NULL, 0);
    5.69 +
    5.70 +    /* We special case this since __xen_guest_section contains a PFN
    5.71 +     * for this field not a virtual address.
    5.72 +     */
    5.73 +    if (type == XEN_ELFNOTE_HYPERCALL_PAGE)
    5.74 +        value = dsi->v_start + (value<<PAGE_SHIFT);
    5.75 +
    5.76 +    *defined = 1;
    5.77 +    return value;
    5.78 +}
    5.79 +
    5.80 +/*
    5.81   * Interface to the Xen ELF notes.
    5.82   */
    5.83  #define ELFNOTE_NAME(_n_)   ((void*)(_n_) + sizeof(*(_n_)))
    5.84 @@ -65,7 +139,6 @@ static Elf_Note *xen_elfnote_lookup(stru
    5.85              return note;
    5.86      }
    5.87  
    5.88 -    DPRINTK("unable to find Xen ELF note with type %#x\n", type);
    5.89      return NULL;
    5.90  }
    5.91  
    5.92 @@ -73,13 +146,13 @@ const char *xen_elfnote_string(struct do
    5.93  {
    5.94      Elf_Note *note;
    5.95  
    5.96 +    if ( !dsi->__elfnote_section )
    5.97 +        return xen_guest_string(dsi, type);
    5.98 +
    5.99      note = xen_elfnote_lookup(dsi, type);
   5.100      if ( note == NULL )
   5.101          return NULL;
   5.102  
   5.103 -    DPRINTK("found Xen ELF note type %#x = \"%s\"\n",
   5.104 -            type, (char *)ELFNOTE_DESC(note));
   5.105 -
   5.106      return (const char *)ELFNOTE_DESC(note);
   5.107  }
   5.108  
   5.109 @@ -90,6 +163,9 @@ unsigned long long xen_elfnote_numeric(s
   5.110  
   5.111      *defined = 0;
   5.112  
   5.113 +    if ( !dsi->__elfnote_section )
   5.114 +        return xen_guest_numeric(dsi, type, defined);
   5.115 +
   5.116      note = xen_elfnote_lookup(dsi, type);
   5.117      if ( note == NULL )
   5.118      {
   5.119 @@ -105,6 +181,8 @@ unsigned long long xen_elfnote_numeric(s
   5.120          *defined = 1;
   5.121          return *(uint64_t*)ELFNOTE_DESC(note);
   5.122      default:
   5.123 +        printk("ERROR: unknown data size %#x for numeric type note %#x\n",
   5.124 +               note->descsz, type);
   5.125          return 0;
   5.126      }
   5.127  }
   5.128 @@ -146,6 +224,7 @@ int parseelfimage(struct domain_setup_in
   5.129      shstrtab = image + shdr->sh_offset;
   5.130  
   5.131      dsi->__elfnote_section = NULL;
   5.132 +    dsi->__xen_guest_string = NULL;
   5.133  
   5.134      /* Look for .notes segment containing at least one Xen note */
   5.135      for ( h = 0; h < ehdr->e_shnum; h++ )
   5.136 @@ -159,27 +238,73 @@ int parseelfimage(struct domain_setup_in
   5.137          break;
   5.138      }
   5.139  
   5.140 -    /* Check the contents of the Xen notes. */
   5.141 -    if ( dsi->__elfnote_section )
   5.142 +    /* Fall back to looking for the special '__xen_guest' section. */
   5.143 +    if ( dsi->__elfnote_section == NULL )
   5.144 +    {
   5.145 +        for ( h = 0; h < ehdr->e_shnum; h++ )
   5.146 +        {
   5.147 +            shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
   5.148 +            if ( is_xen_guest_section(shdr, shstrtab) )
   5.149 +            {
   5.150 +                dsi->__xen_guest_string = (char *)image + shdr->sh_offset;
   5.151 +                break;
   5.152 +            }
   5.153 +        }
   5.154 +    }
   5.155 +
   5.156 +    /* Check the contents of the Xen notes or guest string. */
   5.157 +    if ( dsi->__elfnote_section || dsi->__xen_guest_string )
   5.158      {
   5.159          const char *loader = xen_elfnote_string(dsi, XEN_ELFNOTE_LOADER);
   5.160          const char *guest_os = xen_elfnote_string(dsi, XEN_ELFNOTE_GUEST_OS);
   5.161          const char *xen_version =
   5.162              xen_elfnote_string(dsi, XEN_ELFNOTE_XEN_VERSION);
   5.163  
   5.164 -        if ( ( loader == NULL || strcmp(loader, "generic") ) &&
   5.165 -             ( guest_os == NULL || strcmp(guest_os, "linux") ) )
   5.166 +        if ( ( loader == NULL || strncmp(loader, "generic", 7) ) &&
   5.167 +             ( guest_os == NULL || strncmp(guest_os, "linux", 5) ) )
   5.168          {
   5.169              printk("ERROR: Will only load images built for the generic "
   5.170                     "loader or Linux images");
   5.171              return -EINVAL;
   5.172          }
   5.173  
   5.174 -        if ( xen_version == NULL || strcmp(xen_version, "xen-3.0") )
   5.175 +        if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) )
   5.176          {
   5.177              printk("ERROR: Xen will only load images built for Xen v3.0\n");
   5.178          }
   5.179      }
   5.180 +    else
   5.181 +    {
   5.182 +#if defined(__x86_64__) || defined(__i386__)
   5.183 +        printk("ERROR: Not a Xen-ELF image: "
   5.184 +               "No ELF notes or '__xen_guest' section found.\n");
   5.185 +        return -EINVAL;
   5.186 +#endif
   5.187 +    }
   5.188 +
   5.189 +    /*
   5.190 +     * If we have ELF notes then PAE=yes implies that we must support
   5.191 +     * the extended cr3 syntax. Otherwise we need to find the
   5.192 +     * [extended-cr3] syntax in the __xen_guest string.
   5.193 +     */
   5.194 +    dsi->pae_kernel = PAEKERN_no;
   5.195 +    if ( dsi->__elfnote_section )
   5.196 +    {
   5.197 +        p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
   5.198 +        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   5.199 +            dsi->pae_kernel = PAEKERN_extended_cr3;
   5.200 +
   5.201 +    }
   5.202 +    else
   5.203 +    {
   5.204 +        p = xen_guest_lookup(dsi, XEN_ELFNOTE_PAE_MODE);
   5.205 +        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   5.206 +        {
   5.207 +            dsi->pae_kernel = PAEKERN_yes;
   5.208 +            if ( !strncmp(p+4, "[extended-cr3]", 14) )
   5.209 +                dsi->pae_kernel = PAEKERN_extended_cr3;
   5.210 +        }
   5.211 +    }
   5.212  
   5.213      /* Initial guess for v_start is 0 if it is not explicitly defined. */
   5.214      dsi->v_start =
   5.215 @@ -187,11 +312,24 @@ int parseelfimage(struct domain_setup_in
   5.216      if ( !virt_base_defined )
   5.217          dsi->v_start = 0;
   5.218  
   5.219 -    /* We are using the ELF notes interface so the default is 0. */
   5.220 +    /*
   5.221 +     * If we are using the legacy __xen_guest section then elf_pa_off
   5.222 +     * defaults to v_start in order to maintain compatibility with
   5.223 +     * older hypervisors which set padd in the ELF header to
   5.224 +     * virt_base.
   5.225 +     *
   5.226 +     * If we are using the modern ELF notes interface then the default
   5.227 +     * is 0.
   5.228 +     */
   5.229      dsi->elf_paddr_offset =
   5.230          xen_elfnote_numeric(dsi, XEN_ELFNOTE_PADDR_OFFSET, &elf_pa_off_defined);
   5.231      if ( !elf_pa_off_defined )
   5.232 -        dsi->elf_paddr_offset = 0;
   5.233 +    {
   5.234 +        if ( dsi->__elfnote_section )
   5.235 +            dsi->elf_paddr_offset = 0;
   5.236 +        else
   5.237 +            dsi->elf_paddr_offset = dsi->v_start;
   5.238 +    }
   5.239  
   5.240      if ( elf_pa_off_defined && !virt_base_defined )
   5.241      {
   5.242 @@ -219,6 +357,7 @@ int parseelfimage(struct domain_setup_in
   5.243      }
   5.244  
   5.245      dsi->v_kernentry = ehdr->e_entry;
   5.246 +
   5.247      virt_entry =
   5.248          xen_elfnote_numeric(dsi, XEN_ELFNOTE_ENTRY, &virt_entry_defined);
   5.249      if ( virt_entry_defined )
   5.250 @@ -234,7 +373,7 @@ int parseelfimage(struct domain_setup_in
   5.251      }
   5.252  
   5.253      p = xen_elfnote_string(dsi, XEN_ELFNOTE_BSD_SYMTAB);
   5.254 -    if ( p != NULL && strcmp(p, "yes") == 0 )
   5.255 +    if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   5.256          dsi->load_symtab = 1;
   5.257  
   5.258      dsi->v_kernstart = kernstart;
     6.1 --- a/xen/include/xen/sched.h	Wed Aug 23 18:38:08 2006 +0100
     6.2 +++ b/xen/include/xen/sched.h	Wed Aug 23 18:39:17 2006 +0100
     6.3 @@ -179,13 +179,24 @@ struct domain_setup_info
     6.4      unsigned long v_kernstart;
     6.5      unsigned long v_kernend;
     6.6      unsigned long v_kernentry;
     6.7 +#define PAEKERN_no           0
     6.8 +#define PAEKERN_yes          1
     6.9 +#define PAEKERN_extended_cr3 2
    6.10 +    unsigned int  pae_kernel;
    6.11      /* Initialised by loader: Private. */
    6.12      unsigned long elf_paddr_offset;
    6.13      unsigned int  load_symtab;
    6.14      unsigned long symtab_addr;
    6.15      unsigned long symtab_len;
    6.16 -    /* Indicate whether it's xen specific image */
    6.17 +    /*
    6.18 +     * Only one of __elfnote_* or __xen_guest_string will be
    6.19 +     * non-NULL.
    6.20 +     *
    6.21 +     * You should use the xen_elfnote_* accessors below in order to
    6.22 +     * pickup the correct one and retain backwards compatibility.
    6.23 +     */
    6.24      void *__elfnote_section, *__elfnote_section_end;
    6.25 +    char *__xen_guest_string;
    6.26  };
    6.27  
    6.28  extern struct vcpu *idle_vcpu[NR_CPUS];