ia64/xen-unstable

changeset 13016:ac51e8f37108

Allow loading of ELF kernel images that support both PAE and non-PAE.
Also change the elf loader to not look for a strings section unless it
is needed.
Signed-off-by: Bruce Rogers <brogers@novell.com>
author kfraser@localhost.localdomain
date Thu Dec 14 10:29:44 2006 +0000 (2006-12-14)
parents c09dab67c178
children d2f12edc10ee
files tools/libxc/xc_linux_build.c tools/libxc/xc_load_elf.c tools/libxc/xg_private.h xen/arch/x86/domain_build.c xen/common/elf.c xen/include/xen/sched.h
line diff
     1.1 --- a/tools/libxc/xc_linux_build.c	Wed Dec 13 20:43:47 2006 +0000
     1.2 +++ b/tools/libxc/xc_linux_build.c	Thu Dec 14 10:29:44 2006 +0000
     1.3 @@ -596,15 +596,21 @@ static int compat_check(int xc_handle, s
     1.4      }
     1.5  
     1.6      if (strstr(xen_caps, "xen-3.0-x86_32p")) {
     1.7 -        if (dsi->pae_kernel == PAEKERN_no) {
     1.8 +        if (dsi->pae_kernel == PAEKERN_bimodal) {
     1.9 +            dsi->pae_kernel = PAEKERN_extended_cr3;
    1.10 +        } else if (dsi->pae_kernel == PAEKERN_no) {
    1.11              xc_set_error(XC_INVALID_KERNEL,
    1.12                           "Non PAE-kernel on PAE host.");
    1.13              return 0;
    1.14          }
    1.15 -    } else if (dsi->pae_kernel != PAEKERN_no) {
    1.16 -        xc_set_error(XC_INVALID_KERNEL,
    1.17 -                     "PAE-kernel on non-PAE host.");
    1.18 -        return 0;
    1.19 +    } else {
    1.20 +        if (dsi->pae_kernel == PAEKERN_bimodal) {
    1.21 +            dsi->pae_kernel = PAEKERN_no;
    1.22 +        } else if (dsi->pae_kernel != PAEKERN_no) {
    1.23 +            xc_set_error(XC_INVALID_KERNEL,
    1.24 +                         "PAE-kernel on non-PAE host.");
    1.25 +            return 0;
    1.26 +        }
    1.27      }
    1.28  
    1.29      return 1;
     2.1 --- a/tools/libxc/xc_load_elf.c	Wed Dec 13 20:43:47 2006 +0000
     2.2 +++ b/tools/libxc/xc_load_elf.c	Thu Dec 14 10:29:44 2006 +0000
     2.3 @@ -325,17 +325,6 @@ static int parseelfimage(const char *ima
     2.4          return -EINVAL;
     2.5      }
     2.6  
     2.7 -    /* Find the section-header strings table. */
     2.8 -    if ( ehdr->e_shstrndx == SHN_UNDEF )
     2.9 -    {
    2.10 -        xc_set_error(XC_INVALID_KERNEL,
    2.11 -                     "ELF image has no section-header strings table (shstrtab).");
    2.12 -        return -EINVAL;
    2.13 -    }
    2.14 -    shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
    2.15 -                        (ehdr->e_shstrndx*ehdr->e_shentsize));
    2.16 -    shstrtab = image + shdr->sh_offset;
    2.17 -
    2.18      dsi->__elfnote_section = NULL;
    2.19      dsi->__xen_guest_string = NULL;
    2.20  
    2.21 @@ -354,6 +343,17 @@ static int parseelfimage(const char *ima
    2.22      /* Fall back to looking for the special '__xen_guest' section. */
    2.23      if ( dsi->__elfnote_section == NULL )
    2.24      {
    2.25 +        /* Find the section-header strings table. */
    2.26 +        if ( ehdr->e_shstrndx == SHN_UNDEF )
    2.27 +        {
    2.28 +            xc_set_error(XC_INVALID_KERNEL,
    2.29 +                         "ELF image has no section-header strings table.");
    2.30 +            return -EINVAL;
    2.31 +        }
    2.32 +        shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
    2.33 +                            (ehdr->e_shstrndx*ehdr->e_shentsize));
    2.34 +        shstrtab = image + shdr->sh_offset;
    2.35 +
    2.36          for ( h = 0; h < ehdr->e_shnum; h++ )
    2.37          {
    2.38              shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
    2.39 @@ -400,6 +400,8 @@ static int parseelfimage(const char *ima
    2.40      }
    2.41  
    2.42      /*
    2.43 +     * A "bimodal" ELF note indicates the kernel will adjust to the
    2.44 +     * current paging mode, including handling extended cr3 syntax.
    2.45       * If we have ELF notes then PAE=yes implies that we must support
    2.46       * the extended cr3 syntax. Otherwise we need to find the
    2.47       * [extended-cr3] syntax in the __xen_guest string.
    2.48 @@ -408,7 +410,9 @@ static int parseelfimage(const char *ima
    2.49      if ( dsi->__elfnote_section )
    2.50      {
    2.51          p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
    2.52 -        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
    2.53 +        if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
    2.54 +            dsi->pae_kernel = PAEKERN_bimodal;
    2.55 +        else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
    2.56              dsi->pae_kernel = PAEKERN_extended_cr3;
    2.57  
    2.58      }
     3.1 --- a/tools/libxc/xg_private.h	Wed Dec 13 20:43:47 2006 +0000
     3.2 +++ b/tools/libxc/xg_private.h	Thu Dec 14 10:29:44 2006 +0000
     3.3 @@ -132,6 +132,7 @@ struct domain_setup_info
     3.4  #define PAEKERN_no           0
     3.5  #define PAEKERN_yes          1
     3.6  #define PAEKERN_extended_cr3 2
     3.7 +#define PAEKERN_bimodal      3
     3.8      unsigned int  pae_kernel;
     3.9  
    3.10      unsigned int  load_symtab;
     4.1 --- a/xen/arch/x86/domain_build.c	Wed Dec 13 20:43:47 2006 +0000
     4.2 +++ b/xen/arch/x86/domain_build.c	Thu Dec 14 10:29:44 2006 +0000
     4.3 @@ -321,8 +321,11 @@ int construct_dom0(struct domain *d,
     4.4      if ( (rc = parseelfimage(&dsi)) != 0 )
     4.5          return rc;
     4.6  
     4.7 -    dom0_pae = (dsi.pae_kernel != PAEKERN_no);
     4.8      xen_pae  = (CONFIG_PAGING_LEVELS == 3);
     4.9 +    if (dsi.pae_kernel == PAEKERN_bimodal)
    4.10 +        dom0_pae = xen_pae; 
    4.11 +    else
    4.12 +        dom0_pae = (dsi.pae_kernel != PAEKERN_no);
    4.13      if ( dom0_pae != xen_pae )
    4.14      {
    4.15          printk("PAE mode mismatch between Xen and DOM0 (xen=%s, dom0=%s)\n",
    4.16 @@ -330,7 +333,8 @@ int construct_dom0(struct domain *d,
    4.17          return -EINVAL;
    4.18      }
    4.19  
    4.20 -    if ( xen_pae && dsi.pae_kernel == PAEKERN_extended_cr3 )
    4.21 +    if ( xen_pae && (dsi.pae_kernel == PAEKERN_extended_cr3 ||
    4.22 +            dsi.pae_kernel == PAEKERN_bimodal) )
    4.23              set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist);
    4.24  
    4.25      if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL )
     5.1 --- a/xen/common/elf.c	Wed Dec 13 20:43:47 2006 +0000
     5.2 +++ b/xen/common/elf.c	Thu Dec 14 10:29:44 2006 +0000
     5.3 @@ -216,16 +216,6 @@ int parseelfimage(struct domain_setup_in
     5.4          return -EINVAL;
     5.5      }
     5.6  
     5.7 -    /* Find the section-header strings table. */
     5.8 -    if ( ehdr->e_shstrndx == SHN_UNDEF )
     5.9 -    {
    5.10 -        printk("ELF image has no section-header strings table (shstrtab).\n");
    5.11 -        return -EINVAL;
    5.12 -    }
    5.13 -    shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
    5.14 -                        (ehdr->e_shstrndx*ehdr->e_shentsize));
    5.15 -    shstrtab = image + shdr->sh_offset;
    5.16 -
    5.17      dsi->__elfnote_section = NULL;
    5.18      dsi->__xen_guest_string = NULL;
    5.19  
    5.20 @@ -244,6 +234,16 @@ int parseelfimage(struct domain_setup_in
    5.21      /* Fall back to looking for the special '__xen_guest' section. */
    5.22      if ( dsi->__elfnote_section == NULL )
    5.23      {
    5.24 +        /* Find the section-header strings table. */
    5.25 +        if ( ehdr->e_shstrndx == SHN_UNDEF )
    5.26 +        {
    5.27 +            printk("ELF image has no section-header strings table.\n");
    5.28 +            return -EINVAL;
    5.29 +        }
    5.30 +        shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
    5.31 +                            (ehdr->e_shstrndx*ehdr->e_shentsize));
    5.32 +        shstrtab = image + shdr->sh_offset;
    5.33 +
    5.34          for ( h = 0; h < ehdr->e_shnum; h++ )
    5.35          {
    5.36              shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
    5.37 @@ -286,6 +286,8 @@ int parseelfimage(struct domain_setup_in
    5.38      }
    5.39  
    5.40      /*
    5.41 +     * A "bimodal" ELF note indicates the kernel will adjust to the
    5.42 +     * current paging mode, including handling extended cr3 syntax.
    5.43       * If we have ELF notes then PAE=yes implies that we must support
    5.44       * the extended cr3 syntax. Otherwise we need to find the
    5.45       * [extended-cr3] syntax in the __xen_guest string.
    5.46 @@ -294,9 +296,10 @@ int parseelfimage(struct domain_setup_in
    5.47      if ( dsi->__elfnote_section )
    5.48      {
    5.49          p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
    5.50 -        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
    5.51 +        if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
    5.52 +            dsi->pae_kernel = PAEKERN_bimodal;
    5.53 +        else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
    5.54              dsi->pae_kernel = PAEKERN_extended_cr3;
    5.55 -
    5.56      }
    5.57      else
    5.58      {
     6.1 --- a/xen/include/xen/sched.h	Wed Dec 13 20:43:47 2006 +0000
     6.2 +++ b/xen/include/xen/sched.h	Thu Dec 14 10:29:44 2006 +0000
     6.3 @@ -188,6 +188,7 @@ struct domain_setup_info
     6.4  #define PAEKERN_no           0
     6.5  #define PAEKERN_yes          1
     6.6  #define PAEKERN_extended_cr3 2
     6.7 +#define PAEKERN_bimodal      3
     6.8      unsigned int  pae_kernel;
     6.9      /* Initialised by loader: Private. */
    6.10      unsigned long elf_paddr_offset;