direct-io.hg

changeset 11238:faadbf5ba8d6

[XEN/LINUX] Define Xen ELF notes in kernel header and update dom0 builder.

ELF notes provide a cleaner interface for passing Xen specific
information from the kernel to the domain builder than the existing
__xen_guest section string. The __xen_guest string is retained in
kernels built with 3.0.2 compatability for domU however dom0 requires
the new interface.

Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author Ian Campbell <ian.campbell@xensource.com>
date Wed Aug 23 14:41:05 2006 +0100 (2006-08-23)
parents d57b174adfd6
children 58b5141c8309
files linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S xen/arch/x86/domain_build.c xen/common/elf.c xen/include/xen/elf.h xen/include/xen/sched.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S	Wed Aug 23 14:37:39 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S	Wed Aug 23 14:41:05 2006 +0100
     1.3 @@ -2,6 +2,7 @@
     1.4  
     1.5  .text
     1.6  #include <linux/config.h>
     1.7 +#include <linux/elfnote.h>
     1.8  #include <linux/threads.h>
     1.9  #include <linux/linkage.h>
    1.10  #include <asm/segment.h>
    1.11 @@ -9,6 +10,7 @@
    1.12  #include <asm/thread_info.h>
    1.13  #include <asm/asm-offsets.h>
    1.14  #include <xen/interface/arch-x86_32.h>
    1.15 +#include <xen/interface/elfnote.h>
    1.16  
    1.17  /*
    1.18   * References to members of the new_cpu_data structure.
    1.19 @@ -138,6 +140,7 @@ ENTRY(cpu_gdt_table)
    1.20  	.quad 0x0000000000000000	/* 0xf0 - unused */
    1.21  	.quad 0x0000000000000000	/* 0xf8 - GDT entry 31: double-fault TSS */
    1.22  
    1.23 +#ifdef CONFIG_XEN_COMPAT_030002
    1.24  /*
    1.25   * __xen_guest information
    1.26   */
    1.27 @@ -157,12 +160,8 @@ ENTRY(cpu_gdt_table)
    1.28  	.ascii	",XEN_VER=xen-3.0"
    1.29  	.ascii	",VIRT_BASE=0x"
    1.30  		utoa __PAGE_OFFSET
    1.31 -#ifdef CONFIG_XEN_COMPAT_030002
    1.32  	.ascii	",ELF_PADDR_OFFSET=0x"
    1.33  		utoa __PAGE_OFFSET
    1.34 -#else
    1.35 -	.ascii	",ELF_PADDR_OFFSET=0x0"
    1.36 -#endif /* !CONFIG_XEN_COMPAT_030002 */
    1.37  	.ascii	",VIRT_ENTRY=0x"
    1.38  		utoa (__PAGE_OFFSET + __PHYSICAL_START + VIRT_ENTRY_OFFSET)
    1.39  	.ascii	",HYPERCALL_PAGE=0x"
    1.40 @@ -179,3 +178,24 @@ ENTRY(cpu_gdt_table)
    1.41  #endif
    1.42  	.ascii	",LOADER=generic"
    1.43  	.byte	0
    1.44 +#endif /* CONFIG_XEN_COMPAT_030002 */
    1.45 +
    1.46 +
    1.47 +	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz, "linux")	
    1.48 +	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz, "2.6")
    1.49 +	ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz, "xen-3.0")
    1.50 +	ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .long,  __PAGE_OFFSET)
    1.51 +#ifdef CONFIG_XEN_COMPAT_030002
    1.52 +	ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long,  __PAGE_OFFSET)
    1.53 +#else
    1.54 +	ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long,  0)
    1.55 +#endif /* !CONFIG_XEN_COMPAT_030002 */
    1.56 +	ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .long,  startup_32)
    1.57 +	ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long,  hypercall_page)
    1.58 +	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
    1.59 +#ifdef CONFIG_X86_PAE
    1.60 +	ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "yes")
    1.61 +#else
    1.62 +	ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "no")
    1.63 +#endif
    1.64 +	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")
     2.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S	Wed Aug 23 14:37:39 2006 +0100
     2.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S	Wed Aug 23 14:41:05 2006 +0100
     2.3 @@ -16,12 +16,15 @@
     2.4  #include <linux/linkage.h>
     2.5  #include <linux/threads.h>
     2.6  #include <linux/init.h>
     2.7 +#include <linux/elfnote.h>
     2.8  #include <asm/desc.h>
     2.9  #include <asm/segment.h>
    2.10  #include <asm/page.h>
    2.11  #include <asm/msr.h>
    2.12  #include <asm/cache.h>
    2.13  
    2.14 +#include <xen/interface/elfnote.h>
    2.15 +
    2.16  	.text
    2.17  	.code64
    2.18  #define VIRT_ENTRY_OFFSET 0x0
    2.19 @@ -131,6 +134,7 @@ gdt_end:
    2.20  	/* zero the remaining page */
    2.21  	.fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
    2.22  
    2.23 +#ifdef CONFIG_XEN_COMPAT_030002
    2.24  /*
    2.25   * __xen_guest information
    2.26   */
    2.27 @@ -150,12 +154,8 @@ gdt_end:
    2.28  	.ascii	",XEN_VER=xen-3.0"
    2.29  	.ascii	",VIRT_BASE=0x"
    2.30  		utoh __START_KERNEL_map
    2.31 -#ifdef CONFIG_XEN_COMPAT_030002
    2.32  	.ascii	",ELF_PADDR_OFFSET=0x"
    2.33  		utoh __START_KERNEL_map
    2.34 -#else
    2.35 -	.ascii	",ELF_PADDR_OFFSET=0x0"
    2.36 -#endif /* !CONFIG_XEN_COMPAT_030002 */
    2.37  	.ascii	",VIRT_ENTRY=0x"
    2.38  		utoh (__START_KERNEL_map + __PHYSICAL_START + VIRT_ENTRY_OFFSET)
    2.39  	.ascii	",HYPERCALL_PAGE=0x"
    2.40 @@ -166,3 +166,18 @@ gdt_end:
    2.41  	.ascii	         "|supervisor_mode_kernel"
    2.42  	.ascii	",LOADER=generic"
    2.43  	.byte	0
    2.44 +#endif /* CONFIG_XEN_COMPAT_030002 */
    2.45 +	
    2.46 +	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz, "linux")
    2.47 +	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz, "2.6")
    2.48 +	ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz, "xen-3.0")
    2.49 +	ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .quad,  __START_KERNEL_map)
    2.50 +#ifdef CONFIG_XEN_COMPAT_030002
    2.51 +	ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .quad,  __START_KERNEL_map)
    2.52 +#else
    2.53 +	ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .quad,  0)
    2.54 +#endif /* !CONFIG_XEN_COMPAT_030002 */
    2.55 +	ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .quad,  startup_64)
    2.56 +	ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad,  hypercall_page)
    2.57 +	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
    2.58 +	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")
     3.1 --- a/xen/arch/x86/domain_build.c	Wed Aug 23 14:37:39 2006 +0100
     3.2 +++ b/xen/arch/x86/domain_build.c	Wed Aug 23 14:41:05 2006 +0100
     3.3 @@ -28,6 +28,7 @@
     3.4  #include <asm/shadow.h>
     3.5  
     3.6  #include <public/version.h>
     3.7 +#include <public/elfnote.h>
     3.8  
     3.9  extern unsigned long initial_images_nrpages(void);
    3.10  extern void discard_initial_images(void);
    3.11 @@ -210,8 +211,9 @@ int construct_dom0(struct domain *d,
    3.12      struct page_info *page = NULL;
    3.13      start_info_t *si;
    3.14      struct vcpu *v = d->vcpu[0];
    3.15 -    char *p;
    3.16 +    const char *p;
    3.17      unsigned long hypercall_page;
    3.18 +    int hypercall_page_defined;
    3.19  #if defined(__i386__)
    3.20      char *image_start  = (char *)_image_start;  /* use lowmem mappings */
    3.21      char *initrd_start = (char *)_initrd_start; /* use lowmem mappings */
    3.22 @@ -288,13 +290,14 @@ int construct_dom0(struct domain *d,
    3.23      if ( (rc = parseelfimage(&dsi)) != 0 )
    3.24          return rc;
    3.25  
    3.26 -    if ( dsi.xen_section_string == NULL )
    3.27 +    if ( dsi.__elfnote_section == NULL )
    3.28      {
    3.29 -        printk("Not a Xen-ELF image: '__xen_guest' section not found.\n");
    3.30 +        printk("Not a Xen-ELF image: no Xen ELF notes were found.\n");
    3.31          return -EINVAL;
    3.32      }
    3.33  
    3.34 -    dom0_pae = !!strstr(dsi.xen_section_string, "PAE=yes");
    3.35 +    p = xen_elfnote_string(&dsi, XEN_ELFNOTE_PAE_MODE);
    3.36 +    dom0_pae = !!(p != NULL && strcmp(p, "yes") == 0);
    3.37      xen_pae  = (CONFIG_PAGING_LEVELS == 3);
    3.38      if ( dom0_pae != xen_pae )
    3.39      {
    3.40 @@ -303,15 +306,14 @@ int construct_dom0(struct domain *d,
    3.41          return -EINVAL;
    3.42      }
    3.43  
    3.44 -    if ( xen_pae && !!strstr(dsi.xen_section_string, "PAE=yes[extended-cr3]") )
    3.45 +    if ( xen_pae )
    3.46          set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist);
    3.47  
    3.48 -    if ( (p = strstr(dsi.xen_section_string, "FEATURES=")) != NULL )
    3.49 +    if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL )
    3.50      {
    3.51 -        parse_features(
    3.52 -            p + strlen("FEATURES="),
    3.53 -            dom0_features_supported,
    3.54 -            dom0_features_required);
    3.55 +        parse_features(p,
    3.56 +                       dom0_features_supported,
    3.57 +                       dom0_features_required);
    3.58          printk("Domain 0 kernel supports features = { %08x }.\n",
    3.59                 dom0_features_supported[0]);
    3.60          printk("Domain 0 kernel requires features = { %08x }.\n",
    3.61 @@ -696,20 +698,17 @@ int construct_dom0(struct domain *d,
    3.62      /* Copy the OS image and free temporary buffer. */
    3.63      (void)loadelfimage(&dsi);
    3.64  
    3.65 -    p = strstr(dsi.xen_section_string, "HYPERCALL_PAGE=");
    3.66 -    if ( p != NULL )
    3.67 +    hypercall_page =
    3.68 +        xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined);
    3.69 +    if ( hypercall_page_defined )
    3.70      {
    3.71 -        p += strlen("HYPERCALL_PAGE=");
    3.72 -        hypercall_page = simple_strtoul(p, NULL, 16);
    3.73 -        hypercall_page = dsi.v_start + (hypercall_page << PAGE_SHIFT);
    3.74          if ( (hypercall_page < dsi.v_start) || (hypercall_page >= v_end) )
    3.75          {
    3.76              write_ptbase(current);
    3.77              local_irq_enable();
    3.78 -            printk("Invalid HYPERCALL_PAGE field in guest header.\n");
    3.79 +            printk("Invalid HYPERCALL_PAGE field in ELF notes.\n");
    3.80              return -1;
    3.81          }
    3.82 -
    3.83          hypercall_page_initialise(d, (void *)hypercall_page);
    3.84      }
    3.85  
     4.1 --- a/xen/common/elf.c	Wed Aug 23 14:37:39 2006 +0100
     4.2 +++ b/xen/common/elf.c	Wed Aug 23 14:41:05 2006 +0100
     4.3 @@ -11,6 +11,9 @@
     4.4  #include <xen/elf.h>
     4.5  #include <xen/sched.h>
     4.6  #include <xen/errno.h>
     4.7 +#include <xen/inttypes.h>
     4.8 +
     4.9 +#include <public/elfnote.h>
    4.10  
    4.11  static void loadelfsymtab(struct domain_setup_info *dsi, int doload);
    4.12  static inline int is_loadable_phdr(Elf_Phdr *phdr)
    4.13 @@ -19,26 +22,114 @@ static inline int is_loadable_phdr(Elf_P
    4.14              ((phdr->p_flags & (PF_W|PF_X)) != 0));
    4.15  }
    4.16  
    4.17 +/*
    4.18 + * Interface to the Xen ELF notes.
    4.19 + */
    4.20 +#define ELFNOTE_NAME(_n_)   ((void*)(_n_) + sizeof(*(_n_)))
    4.21 +#define ELFNOTE_DESC(_n_)   (ELFNOTE_NAME(_n_) + (((_n_)->namesz+3)&~3))
    4.22 +#define ELFNOTE_NEXT(_n_)   (ELFNOTE_DESC(_n_) + (((_n_)->descsz+3)&~3))
    4.23 +
    4.24 +static int is_xen_elfnote_section(const char *image, Elf_Shdr *shdr)
    4.25 +{
    4.26 +    Elf_Note *note;
    4.27 +
    4.28 +    if ( shdr->sh_type != SHT_NOTE )
    4.29 +        return 0;
    4.30 +
    4.31 +    for ( note = (Elf_Note *)(image + shdr->sh_offset);
    4.32 +          note < (Elf_Note *)(image + shdr->sh_offset + shdr->sh_size);
    4.33 +          note = ELFNOTE_NEXT(note) )
    4.34 +    {
    4.35 +        if ( !strncmp(ELFNOTE_NAME(note), "Xen", 4) )
    4.36 +            return 1;
    4.37 +    }
    4.38 +
    4.39 +    return 0;
    4.40 +}
    4.41 +
    4.42 +static Elf_Note *xen_elfnote_lookup(struct domain_setup_info *dsi, int type)
    4.43 +{
    4.44 +    Elf_Note *note;
    4.45 +
    4.46 +    if ( !dsi->__elfnote_section )
    4.47 +        return NULL;
    4.48 +
    4.49 +    for ( note = (Elf_Note *)dsi->__elfnote_section;
    4.50 +          note < (Elf_Note *)dsi->__elfnote_section_end;
    4.51 +          note = ELFNOTE_NEXT(note) )
    4.52 +    {
    4.53 +        if ( strncmp(ELFNOTE_NAME(note), "Xen", 4) )
    4.54 +            continue;
    4.55 +
    4.56 +        if ( note->type == type )
    4.57 +            return note;
    4.58 +    }
    4.59 +
    4.60 +    DPRINTK("unable to find Xen ELF note with type %#x\n", type);
    4.61 +    return NULL;
    4.62 +}
    4.63 +
    4.64 +const char *xen_elfnote_string(struct domain_setup_info *dsi, int type)
    4.65 +{
    4.66 +    Elf_Note *note;
    4.67 +
    4.68 +    note = xen_elfnote_lookup(dsi, type);
    4.69 +    if ( note == NULL )
    4.70 +        return NULL;
    4.71 +
    4.72 +    DPRINTK("found Xen ELF note type %#x = \"%s\"\n",
    4.73 +            type, (char *)ELFNOTE_DESC(note));
    4.74 +
    4.75 +    return (const char *)ELFNOTE_DESC(note);
    4.76 +}
    4.77 +
    4.78 +unsigned long long xen_elfnote_numeric(struct domain_setup_info *dsi,
    4.79 +                                       int type, int *defined)
    4.80 +{
    4.81 +    Elf_Note *note;
    4.82 +
    4.83 +    *defined = 0;
    4.84 +
    4.85 +    note = xen_elfnote_lookup(dsi, type);
    4.86 +    if ( note == NULL )
    4.87 +    {
    4.88 +        return 0;
    4.89 +    }
    4.90 +
    4.91 +    switch ( note->descsz )
    4.92 +    {
    4.93 +    case 4:
    4.94 +        *defined = 1;
    4.95 +        return *(uint32_t*)ELFNOTE_DESC(note);
    4.96 +    case 8:
    4.97 +        *defined = 1;
    4.98 +        return *(uint64_t*)ELFNOTE_DESC(note);
    4.99 +    default:
   4.100 +        return 0;
   4.101 +    }
   4.102 +}
   4.103 +
   4.104  int parseelfimage(struct domain_setup_info *dsi)
   4.105  {
   4.106      Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr;
   4.107      Elf_Phdr *phdr;
   4.108      Elf_Shdr *shdr;
   4.109 -    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_base, elf_pa_off;
   4.110 -    char *shstrtab, *guestinfo=NULL, *p;
   4.111 -    char *elfbase = (char *)dsi->image_addr;
   4.112 -    int h, virt_base_defined, elf_pa_off_defined;
   4.113 +    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_entry;
   4.114 +    const char *shstrtab, *p;
   4.115 +    const char *image = (char *)dsi->image_addr;
   4.116 +    const unsigned long image_len = dsi->image_len;
   4.117 +    int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined;
   4.118  
   4.119      if ( !elf_sanity_check(ehdr) )
   4.120          return -EINVAL;
   4.121  
   4.122 -    if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > dsi->image_len )
   4.123 +    if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len )
   4.124      {
   4.125          printk("ELF program headers extend beyond end of image.\n");
   4.126          return -EINVAL;
   4.127      }
   4.128  
   4.129 -    if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > dsi->image_len )
   4.130 +    if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len )
   4.131      {
   4.132          printk("ELF section headers extend beyond end of image.\n");
   4.133          return -EINVAL;
   4.134 @@ -50,64 +141,71 @@ int parseelfimage(struct domain_setup_in
   4.135          printk("ELF image has no section-header strings table (shstrtab).\n");
   4.136          return -EINVAL;
   4.137      }
   4.138 -    shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff + 
   4.139 +    shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
   4.140                          (ehdr->e_shstrndx*ehdr->e_shentsize));
   4.141 -    shstrtab = elfbase + shdr->sh_offset;
   4.142 -    
   4.143 -    /* Find the special '__xen_guest' section and check its contents. */
   4.144 +    shstrtab = image + shdr->sh_offset;
   4.145 +
   4.146 +    dsi->__elfnote_section = NULL;
   4.147 +
   4.148 +    /* Look for .notes segment containing at least one Xen note */
   4.149      for ( h = 0; h < ehdr->e_shnum; h++ )
   4.150      {
   4.151 -        shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff + (h*ehdr->e_shentsize));
   4.152 -        if ( strcmp(&shstrtab[shdr->sh_name], "__xen_guest") != 0 )
   4.153 +        shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
   4.154 +        if ( !is_xen_elfnote_section(image, shdr) )
   4.155              continue;
   4.156 -
   4.157 -        guestinfo = elfbase + shdr->sh_offset;
   4.158 +        dsi->__elfnote_section = (void *)image + shdr->sh_offset;
   4.159 +        dsi->__elfnote_section_end =
   4.160 +            (void *)image + shdr->sh_offset + shdr->sh_size;
   4.161 +        break;
   4.162 +    }
   4.163  
   4.164 -        if ( (strstr(guestinfo, "LOADER=generic") == NULL) &&
   4.165 -             (strstr(guestinfo, "GUEST_OS=linux") == NULL) )
   4.166 +    /* Check the contents of the Xen notes. */
   4.167 +    if ( dsi->__elfnote_section )
   4.168 +    {
   4.169 +        const char *loader = xen_elfnote_string(dsi, XEN_ELFNOTE_LOADER);
   4.170 +        const char *guest_os = xen_elfnote_string(dsi, XEN_ELFNOTE_GUEST_OS);
   4.171 +        const char *xen_version =
   4.172 +            xen_elfnote_string(dsi, XEN_ELFNOTE_XEN_VERSION);
   4.173 +
   4.174 +        if ( ( loader == NULL || strcmp(loader, "generic") ) &&
   4.175 +             ( guest_os == NULL || strcmp(guest_os, "linux") ) )
   4.176          {
   4.177 -            printk("ERROR: Xen will only load images built for the generic "
   4.178 -                   "loader or Linux images\n");
   4.179 +            printk("ERROR: Will only load images built for the generic "
   4.180 +                   "loader or Linux images");
   4.181              return -EINVAL;
   4.182          }
   4.183  
   4.184 -        if ( (strstr(guestinfo, "XEN_VER=xen-3.0") == NULL) )
   4.185 +        if ( xen_version == NULL || strcmp(xen_version, "xen-3.0") )
   4.186          {
   4.187              printk("ERROR: Xen will only load images built for Xen v3.0\n");
   4.188 -            return -EINVAL;
   4.189          }
   4.190 -
   4.191 -        break;
   4.192      }
   4.193  
   4.194 -    dsi->xen_section_string = guestinfo;
   4.195 -
   4.196 -    if ( guestinfo == NULL )
   4.197 -        guestinfo = "";
   4.198 +    /* Initial guess for v_start is 0 if it is not explicitly defined. */
   4.199 +    dsi->v_start =
   4.200 +        xen_elfnote_numeric(dsi, XEN_ELFNOTE_VIRT_BASE, &virt_base_defined);
   4.201 +    if ( !virt_base_defined )
   4.202 +        dsi->v_start = 0;
   4.203  
   4.204 -    /* Initial guess for virt_base is 0 if it is not explicitly defined. */
   4.205 -    p = strstr(guestinfo, "VIRT_BASE=");
   4.206 -    virt_base_defined = (p != NULL);
   4.207 -    virt_base = virt_base_defined ? simple_strtoul(p+10, &p, 0) : 0;
   4.208 -
   4.209 -    /* Initial guess for elf_pa_off is virt_base if not explicitly defined. */
   4.210 -    p = strstr(guestinfo, "ELF_PADDR_OFFSET=");
   4.211 -    elf_pa_off_defined = (p != NULL);
   4.212 -    elf_pa_off = elf_pa_off_defined ? simple_strtoul(p+17, &p, 0) : virt_base;
   4.213 +    /* We are using the ELF notes interface so the default is 0. */
   4.214 +    dsi->elf_paddr_offset =
   4.215 +        xen_elfnote_numeric(dsi, XEN_ELFNOTE_PADDR_OFFSET, &elf_pa_off_defined);
   4.216 +    if ( !elf_pa_off_defined )
   4.217 +        dsi->elf_paddr_offset = 0;
   4.218  
   4.219      if ( elf_pa_off_defined && !virt_base_defined )
   4.220      {
   4.221          printk("ERROR: Neither ELF_PADDR_OFFSET nor VIRT_BASE found in"
   4.222 -               " __xen_guest section.\n");
   4.223 +               " Xen ELF notes.\n");
   4.224          return -EINVAL;
   4.225      }
   4.226  
   4.227      for ( h = 0; h < ehdr->e_phnum; h++ )
   4.228      {
   4.229 -        phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
   4.230 +        phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize));
   4.231          if ( !is_loadable_phdr(phdr) )
   4.232              continue;
   4.233 -        vaddr = phdr->p_paddr - elf_pa_off + virt_base;
   4.234 +        vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start;
   4.235          if ( (vaddr + phdr->p_memsz) < vaddr )
   4.236          {
   4.237              printk("ERROR: ELF program header %d is too large.\n", h);
   4.238 @@ -120,19 +218,13 @@ int parseelfimage(struct domain_setup_in
   4.239              kernend = vaddr + phdr->p_memsz;
   4.240      }
   4.241  
   4.242 -    /*
   4.243 -     * Legacy compatibility and images with no __xen_guest section: assume
   4.244 -     * header addresses are virtual addresses, and that guest memory should be
   4.245 -     * mapped starting at kernel load address.
   4.246 -     */
   4.247 -    dsi->v_start          = virt_base_defined  ? virt_base  : kernstart;
   4.248 -    dsi->elf_paddr_offset = elf_pa_off_defined ? elf_pa_off : dsi->v_start;
   4.249 +    dsi->v_kernentry = ehdr->e_entry;
   4.250 +    virt_entry =
   4.251 +        xen_elfnote_numeric(dsi, XEN_ELFNOTE_ENTRY, &virt_entry_defined);
   4.252 +    if ( virt_entry_defined )
   4.253 +        dsi->v_kernentry = virt_entry;
   4.254  
   4.255 -    dsi->v_kernentry = ehdr->e_entry;
   4.256 -    if ( (p = strstr(guestinfo, "VIRT_ENTRY=")) != NULL )
   4.257 -        dsi->v_kernentry = simple_strtoul(p+11, &p, 0);
   4.258 -
   4.259 -    if ( (kernstart > kernend) || 
   4.260 +    if ( (kernstart > kernend) ||
   4.261           (dsi->v_kernentry < kernstart) ||
   4.262           (dsi->v_kernentry > kernend) ||
   4.263           (dsi->v_start > kernstart) )
   4.264 @@ -141,8 +233,9 @@ int parseelfimage(struct domain_setup_in
   4.265          return -EINVAL;
   4.266      }
   4.267  
   4.268 -    if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
   4.269 -            dsi->load_symtab = 1;
   4.270 +    p = xen_elfnote_string(dsi, XEN_ELFNOTE_BSD_SYMTAB);
   4.271 +    if ( p != NULL && strcmp(p, "yes") == 0 )
   4.272 +        dsi->load_symtab = 1;
   4.273  
   4.274      dsi->v_kernstart = kernstart;
   4.275      dsi->v_kernend   = kernend;
   4.276 @@ -155,7 +248,7 @@ int parseelfimage(struct domain_setup_in
   4.277  
   4.278  int loadelfimage(struct domain_setup_info *dsi)
   4.279  {
   4.280 -    char *elfbase = (char *)dsi->image_addr;
   4.281 +    char *image = (char *)dsi->image_addr;
   4.282      Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr;
   4.283      Elf_Phdr *phdr;
   4.284      unsigned long vaddr;
   4.285 @@ -163,12 +256,12 @@ int loadelfimage(struct domain_setup_inf
   4.286    
   4.287      for ( h = 0; h < ehdr->e_phnum; h++ )
   4.288      {
   4.289 -        phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
   4.290 +        phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize));
   4.291          if ( !is_loadable_phdr(phdr) )
   4.292              continue;
   4.293          vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start;
   4.294          if ( phdr->p_filesz != 0 )
   4.295 -            memcpy((char *)vaddr, elfbase + phdr->p_offset, phdr->p_filesz);
   4.296 +            memcpy((char *)vaddr, image + phdr->p_offset, phdr->p_filesz);
   4.297          if ( phdr->p_memsz > phdr->p_filesz )
   4.298              memset((char *)vaddr + phdr->p_filesz, 0,
   4.299                     phdr->p_memsz - phdr->p_filesz);
   4.300 @@ -186,7 +279,7 @@ static void loadelfsymtab(struct domain_
   4.301      Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr, *sym_ehdr;
   4.302      Elf_Shdr *shdr;
   4.303      unsigned long maxva, symva;
   4.304 -    char *p, *elfbase = (char *)dsi->image_addr;
   4.305 +    char *p, *image = (char *)dsi->image_addr;
   4.306      int h, i;
   4.307  
   4.308      if ( !dsi->load_symtab )
   4.309 @@ -203,12 +296,12 @@ static void loadelfsymtab(struct domain_
   4.310      {
   4.311          p = (void *)symva;
   4.312          shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr));
   4.313 -        memcpy(shdr, elfbase + ehdr->e_shoff, ehdr->e_shnum*sizeof(Elf_Shdr));
   4.314 +        memcpy(shdr, image + ehdr->e_shoff, ehdr->e_shnum*sizeof(Elf_Shdr));
   4.315      } 
   4.316      else
   4.317      {
   4.318          p = NULL;
   4.319 -        shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff);
   4.320 +        shdr = (Elf_Shdr *)(image + ehdr->e_shoff);
   4.321      }
   4.322  
   4.323      for ( h = 0; h < ehdr->e_shnum; h++ ) 
   4.324 @@ -234,7 +327,7 @@ static void loadelfsymtab(struct domain_
   4.325               (shdr[h].sh_type == SHT_SYMTAB) )
   4.326          {
   4.327              if (doload) {
   4.328 -                memcpy((void *)maxva, elfbase + shdr[h].sh_offset,
   4.329 +                memcpy((void *)maxva, image + shdr[h].sh_offset,
   4.330                         shdr[h].sh_size);
   4.331  
   4.332                  /* Mangled to be based on ELF header location. */
     5.1 --- a/xen/include/xen/elf.h	Wed Aug 23 14:37:39 2006 +0100
     5.2 +++ b/xen/include/xen/elf.h	Wed Aug 23 14:41:05 2006 +0100
     5.3 @@ -529,6 +529,10 @@ struct domain_setup_info;
     5.4  extern int loadelfimage(struct domain_setup_info *);
     5.5  extern int parseelfimage(struct domain_setup_info *);
     5.6  
     5.7 +extern unsigned long long xen_elfnote_numeric(struct domain_setup_info *dsi,
     5.8 +					      int type, int *defined);
     5.9 +extern const char *xen_elfnote_string(struct domain_setup_info *dsi, int type);
    5.10 +
    5.11  #ifdef Elf_Ehdr
    5.12  extern int elf_sanity_check(Elf_Ehdr *ehdr);
    5.13  #endif
     6.1 --- a/xen/include/xen/sched.h	Wed Aug 23 14:37:39 2006 +0100
     6.2 +++ b/xen/include/xen/sched.h	Wed Aug 23 14:41:05 2006 +0100
     6.3 @@ -185,7 +185,7 @@ struct domain_setup_info
     6.4      unsigned long symtab_addr;
     6.5      unsigned long symtab_len;
     6.6      /* Indicate whether it's xen specific image */
     6.7 -    char *xen_section_string;
     6.8 +    void *__elfnote_section, *__elfnote_section_end;
     6.9  };
    6.10  
    6.11  extern struct vcpu *idle_vcpu[NR_CPUS];