[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge
# HG changeset patch # User Ian Campbell <ian.campbell@xxxxxxxxxxxxx> # Node ID 551495fa7b3e24823cce62d8cfe257f3fe8a2b7c # Parent 51a98a6c2c054bfc37c90a5a3f29929f2347bda8 # Parent 2eb8efcc70d1744198d729e1caf2a59b046b178b merge --- tools/libxc/xc_load_bin.c | 2 tools/libxc/xc_load_elf.c | 26 ++----- tools/libxc/xg_private.h | 2 xen/arch/x86/domain_build.c | 13 --- xen/common/elf.c | 163 ++++++++++++++++++++++++++++++++++++++++---- xen/include/xen/sched.h | 13 +++ 6 files changed, 178 insertions(+), 41 deletions(-) diff -r 51a98a6c2c05 -r 551495fa7b3e tools/libxc/xc_load_bin.c --- a/tools/libxc/xc_load_bin.c Wed Aug 23 18:38:08 2006 +0100 +++ b/tools/libxc/xc_load_bin.c Wed Aug 23 18:39:17 2006 +0100 @@ -227,7 +227,7 @@ static int parsebinimage(const char *ima dsi->v_kernstart = dsi->v_start; dsi->v_kernend = dsi->v_end; dsi->v_kernentry = image_info->entry_addr; - dsi->__xen_guest_string = ""; + dsi->__xen_guest_string = NULL; return 0; } diff -r 51a98a6c2c05 -r 551495fa7b3e tools/libxc/xc_load_elf.c --- a/tools/libxc/xc_load_elf.c Wed Aug 23 18:38:08 2006 +0100 +++ b/tools/libxc/xc_load_elf.c Wed Aug 23 18:39:17 2006 +0100 @@ -109,15 +109,13 @@ static const char *xen_guest_string(stru { const char *p = xen_guest_lookup(dsi, type); - DPRINTF("found __xen_guest entry for type %#x = \"%s\"\n", - type, p); - /* * We special case this since the __xen_guest_section treats the * mere precense of the BSD_SYMTAB string as true or false. */ if ( type == XEN_ELFNOTE_BSD_SYMTAB ) return p ? "yes" : "no"; + return p; } @@ -140,9 +138,6 @@ static unsigned long long xen_guest_nume */ if (type == XEN_ELFNOTE_HYPERCALL_PAGE) value = dsi->v_start + (value<<PAGE_SHIFT); - - DPRINTF("found __xen_guest entry for type %#x = %#llx\n", - type, value); *defined = 1; return value; @@ -177,6 +172,9 @@ static Elf_Note *xen_elfnote_lookup(stru { Elf_Note *note; + if ( !dsi->__elfnote_section ) + return NULL; + for ( note = (Elf_Note *)dsi->__elfnote_section; note < (Elf_Note *)dsi->__elfnote_section_end; note = ELFNOTE_NEXT(note) ) @@ -188,7 +186,6 @@ static Elf_Note *xen_elfnote_lookup(stru return note; } - DPRINTF("unable to find Xen ELF note with type %#x\n", type); return NULL; } @@ -202,9 +199,6 @@ const char *xen_elfnote_string(struct do note = xen_elfnote_lookup(dsi, type); if ( note == NULL ) return NULL; - - DPRINTF("found Xen ELF note type %#x = \"%s\"\n", - type, (char *)ELFNOTE_DESC(note)); return (const char *)ELFNOTE_DESC(note); } @@ -297,7 +291,6 @@ static int parseelfimage(const char *ima shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize)); if ( !is_xen_elfnote_section(image, shdr) ) continue; - DPRINTF("found note section containing Xen entries\n"); dsi->__elfnote_section = (void *)image + shdr->sh_offset; dsi->__elfnote_section_end = (void *)image + shdr->sh_offset + shdr->sh_size; @@ -312,7 +305,6 @@ static int parseelfimage(const char *ima shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize)); if ( is_xen_guest_section(shdr, shstrtab) ) { - DPRINTF("found a legacy __xen_guest section\n"); dsi->__xen_guest_string = (char *)image + shdr->sh_offset; break; } @@ -343,16 +335,18 @@ static int parseelfimage(const char *ima } else { -#ifdef __ia64__ - dsi->__elfnote_section = NULL; - dsi->__xen_guest_string = ""; -#else +#if defined(__x86_64__) || defined(__i386__) ERROR("Not a Xen-ELF image: " "No ELF notes or '__xen_guest' section found."); return -EINVAL; #endif } + /* + * If we have ELF notes then PAE=yes implies that we must support + * the extended cr3 syntax. Otherwise we need to find the + * [extended-cr3] syntax in the __xen_guest string. + */ dsi->pae_kernel = PAEKERN_no; if ( dsi->__elfnote_section ) { diff -r 51a98a6c2c05 -r 551495fa7b3e tools/libxc/xg_private.h --- a/tools/libxc/xg_private.h Wed Aug 23 18:38:08 2006 +0100 +++ b/tools/libxc/xg_private.h Wed Aug 23 18:39:17 2006 +0100 @@ -159,7 +159,7 @@ struct domain_setup_info * pickup the correct one and retain backwards compatibility. */ void *__elfnote_section, *__elfnote_section_end; - char *__xen_guest_string; + const char *__xen_guest_string; }; typedef int (*parseimagefunc)(const char *image, unsigned long image_size, diff -r 51a98a6c2c05 -r 551495fa7b3e xen/arch/x86/domain_build.c --- a/xen/arch/x86/domain_build.c Wed Aug 23 18:38:08 2006 +0100 +++ b/xen/arch/x86/domain_build.c Wed Aug 23 18:39:17 2006 +0100 @@ -290,14 +290,7 @@ int construct_dom0(struct domain *d, if ( (rc = parseelfimage(&dsi)) != 0 ) return rc; - if ( dsi.__elfnote_section == NULL ) - { - printk("Not a Xen-ELF image: no Xen ELF notes were found.\n"); - return -EINVAL; - } - - p = xen_elfnote_string(&dsi, XEN_ELFNOTE_PAE_MODE); - dom0_pae = !!(p != NULL && strcmp(p, "yes") == 0); + dom0_pae = (dsi.pae_kernel != PAEKERN_no); xen_pae = (CONFIG_PAGING_LEVELS == 3); if ( dom0_pae != xen_pae ) { @@ -306,8 +299,8 @@ int construct_dom0(struct domain *d, return -EINVAL; } - if ( xen_pae ) - set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist); + if ( xen_pae && dsi.pae_kernel == PAEKERN_extended_cr3 ) + set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist); if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL ) { diff -r 51a98a6c2c05 -r 551495fa7b3e xen/common/elf.c --- a/xen/common/elf.c Wed Aug 23 18:38:08 2006 +0100 +++ b/xen/common/elf.c Wed Aug 23 18:39:17 2006 +0100 @@ -23,6 +23,80 @@ static inline int is_loadable_phdr(Elf_P } /* + * Fallback for kernels containing only the legacy __xen_guest string + * and no ELF notes. + */ +static int is_xen_guest_section(Elf_Shdr *shdr, const char *shstrtab) +{ + return strcmp(&shstrtab[shdr->sh_name], "__xen_guest") == 0; +} + +static const char *xen_guest_lookup(struct domain_setup_info *dsi, int type) +{ + const char *xenguest_fallbacks[] = { + [XEN_ELFNOTE_ENTRY] = "VIRT_ENTRY=", + [XEN_ELFNOTE_HYPERCALL_PAGE] = "HYPERCALL_PAGE=", + [XEN_ELFNOTE_VIRT_BASE] = "VIRT_BASE=", + [XEN_ELFNOTE_PADDR_OFFSET] = "ELF_PADDR_OFFSET=", + [XEN_ELFNOTE_XEN_VERSION] = "XEN_VER=", + [XEN_ELFNOTE_GUEST_OS] = "GUEST_OS=", + [XEN_ELFNOTE_GUEST_VERSION] = "GUEST_VER=", + [XEN_ELFNOTE_LOADER] = "LOADER=", + [XEN_ELFNOTE_PAE_MODE] = "PAE=", + [XEN_ELFNOTE_FEATURES] = "FEATURES=", + [XEN_ELFNOTE_BSD_SYMTAB] = "BSD_SYMTAB=", + }; + const char *fallback; + const char *p; + + if ( type > sizeof(xenguest_fallbacks) ) + return NULL; + + if ( (fallback = xenguest_fallbacks[type]) == NULL ) + return NULL; + + if ( (p = strstr(dsi->__xen_guest_string,fallback)) == NULL ) + return NULL; + + return p + strlen(fallback); +} + +static const char *xen_guest_string(struct domain_setup_info *dsi, int type) +{ + const char *p = xen_guest_lookup(dsi, type); + + /* + * We special case this since the __xen_guest_section treats the + * mere precense of the BSD_SYMTAB string as true or false. + */ + if ( type == XEN_ELFNOTE_BSD_SYMTAB ) + return p ? "yes" : "no"; + + return p; +} + +static unsigned long long xen_guest_numeric(struct domain_setup_info *dsi, + int type, int *defined) +{ + const char *p = xen_guest_lookup(dsi, type); + unsigned long long value; + + if ( p == NULL ) + return 0; + + value = simple_strtoull(p, NULL, 0); + + /* We special case this since __xen_guest_section contains a PFN + * for this field not a virtual address. + */ + if (type == XEN_ELFNOTE_HYPERCALL_PAGE) + value = dsi->v_start + (value<<PAGE_SHIFT); + + *defined = 1; + return value; +} + +/* * Interface to the Xen ELF notes. */ #define ELFNOTE_NAME(_n_) ((void*)(_n_) + sizeof(*(_n_))) @@ -65,21 +139,20 @@ static Elf_Note *xen_elfnote_lookup(stru return note; } - DPRINTK("unable to find Xen ELF note with type %#x\n", type); return NULL; } const char *xen_elfnote_string(struct domain_setup_info *dsi, int type) { Elf_Note *note; + + if ( !dsi->__elfnote_section ) + return xen_guest_string(dsi, type); note = xen_elfnote_lookup(dsi, type); if ( note == NULL ) return NULL; - DPRINTK("found Xen ELF note type %#x = \"%s\"\n", - type, (char *)ELFNOTE_DESC(note)); - return (const char *)ELFNOTE_DESC(note); } @@ -89,6 +162,9 @@ unsigned long long xen_elfnote_numeric(s Elf_Note *note; *defined = 0; + + if ( !dsi->__elfnote_section ) + return xen_guest_numeric(dsi, type, defined); note = xen_elfnote_lookup(dsi, type); if ( note == NULL ) @@ -105,6 +181,8 @@ unsigned long long xen_elfnote_numeric(s *defined = 1; return *(uint64_t*)ELFNOTE_DESC(note); default: + printk("ERROR: unknown data size %#x for numeric type note %#x\n", + note->descsz, type); return 0; } } @@ -146,6 +224,7 @@ int parseelfimage(struct domain_setup_in shstrtab = image + shdr->sh_offset; dsi->__elfnote_section = NULL; + dsi->__xen_guest_string = NULL; /* Look for .notes segment containing at least one Xen note */ for ( h = 0; h < ehdr->e_shnum; h++ ) @@ -159,25 +238,71 @@ int parseelfimage(struct domain_setup_in break; } - /* Check the contents of the Xen notes. */ - if ( dsi->__elfnote_section ) + /* Fall back to looking for the special '__xen_guest' section. */ + if ( dsi->__elfnote_section == NULL ) + { + for ( h = 0; h < ehdr->e_shnum; h++ ) + { + shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize)); + if ( is_xen_guest_section(shdr, shstrtab) ) + { + dsi->__xen_guest_string = (char *)image + shdr->sh_offset; + break; + } + } + } + + /* Check the contents of the Xen notes or guest string. */ + if ( dsi->__elfnote_section || dsi->__xen_guest_string ) { const char *loader = xen_elfnote_string(dsi, XEN_ELFNOTE_LOADER); const char *guest_os = xen_elfnote_string(dsi, XEN_ELFNOTE_GUEST_OS); const char *xen_version = xen_elfnote_string(dsi, XEN_ELFNOTE_XEN_VERSION); - if ( ( loader == NULL || strcmp(loader, "generic") ) && - ( guest_os == NULL || strcmp(guest_os, "linux") ) ) + if ( ( loader == NULL || strncmp(loader, "generic", 7) ) && + ( guest_os == NULL || strncmp(guest_os, "linux", 5) ) ) { printk("ERROR: Will only load images built for the generic " "loader or Linux images"); return -EINVAL; } - if ( xen_version == NULL || strcmp(xen_version, "xen-3.0") ) + if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) ) { printk("ERROR: Xen will only load images built for Xen v3.0\n"); + } + } + else + { +#if defined(__x86_64__) || defined(__i386__) + printk("ERROR: Not a Xen-ELF image: " + "No ELF notes or '__xen_guest' section found.\n"); + return -EINVAL; +#endif + } + + /* + * If we have ELF notes then PAE=yes implies that we must support + * the extended cr3 syntax. Otherwise we need to find the + * [extended-cr3] syntax in the __xen_guest string. + */ + dsi->pae_kernel = PAEKERN_no; + if ( dsi->__elfnote_section ) + { + p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE); + if ( p != NULL && strncmp(p, "yes", 3) == 0 ) + dsi->pae_kernel = PAEKERN_extended_cr3; + + } + else + { + p = xen_guest_lookup(dsi, XEN_ELFNOTE_PAE_MODE); + if ( p != NULL && strncmp(p, "yes", 3) == 0 ) + { + dsi->pae_kernel = PAEKERN_yes; + if ( !strncmp(p+4, "[extended-cr3]", 14) ) + dsi->pae_kernel = PAEKERN_extended_cr3; } } @@ -187,11 +312,24 @@ int parseelfimage(struct domain_setup_in if ( !virt_base_defined ) dsi->v_start = 0; - /* We are using the ELF notes interface so the default is 0. */ + /* + * If we are using the legacy __xen_guest section then elf_pa_off + * defaults to v_start in order to maintain compatibility with + * older hypervisors which set padd in the ELF header to + * virt_base. + * + * If we are using the modern ELF notes interface then the default + * is 0. + */ dsi->elf_paddr_offset = xen_elfnote_numeric(dsi, XEN_ELFNOTE_PADDR_OFFSET, &elf_pa_off_defined); if ( !elf_pa_off_defined ) - dsi->elf_paddr_offset = 0; + { + if ( dsi->__elfnote_section ) + dsi->elf_paddr_offset = 0; + else + dsi->elf_paddr_offset = dsi->v_start; + } if ( elf_pa_off_defined && !virt_base_defined ) { @@ -219,6 +357,7 @@ int parseelfimage(struct domain_setup_in } dsi->v_kernentry = ehdr->e_entry; + virt_entry = xen_elfnote_numeric(dsi, XEN_ELFNOTE_ENTRY, &virt_entry_defined); if ( virt_entry_defined ) @@ -234,7 +373,7 @@ int parseelfimage(struct domain_setup_in } p = xen_elfnote_string(dsi, XEN_ELFNOTE_BSD_SYMTAB); - if ( p != NULL && strcmp(p, "yes") == 0 ) + if ( p != NULL && strncmp(p, "yes", 3) == 0 ) dsi->load_symtab = 1; dsi->v_kernstart = kernstart; diff -r 51a98a6c2c05 -r 551495fa7b3e xen/include/xen/sched.h --- a/xen/include/xen/sched.h Wed Aug 23 18:38:08 2006 +0100 +++ b/xen/include/xen/sched.h Wed Aug 23 18:39:17 2006 +0100 @@ -179,13 +179,24 @@ struct domain_setup_info unsigned long v_kernstart; unsigned long v_kernend; unsigned long v_kernentry; +#define PAEKERN_no 0 +#define PAEKERN_yes 1 +#define PAEKERN_extended_cr3 2 + unsigned int pae_kernel; /* Initialised by loader: Private. */ unsigned long elf_paddr_offset; unsigned int load_symtab; unsigned long symtab_addr; unsigned long symtab_len; - /* Indicate whether it's xen specific image */ + /* + * Only one of __elfnote_* or __xen_guest_string will be + * non-NULL. + * + * You should use the xen_elfnote_* accessors below in order to + * pickup the correct one and retain backwards compatibility. + */ void *__elfnote_section, *__elfnote_section_end; + char *__xen_guest_string; }; extern struct vcpu *idle_vcpu[NR_CPUS]; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |