WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [XEN] Restore backwards compatibility by

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [XEN] Restore backwards compatibility by supporting __xen_guest
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 23 Aug 2006 20:10:13 +0000
Delivery-date: Wed, 23 Aug 2006 13:10:37 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
# Node ID 2eb8efcc70d1744198d729e1caf2a59b046b178b
# Parent  cc006f78cbe20d0b84f7e80c2b1fac6c9eb7dc29
[XEN] Restore backwards compatibility by supporting __xen_guest
section in dom0 loader.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
---
 xen/arch/x86/domain_build.c |   13 ---
 xen/common/elf.c            |  163 ++++++++++++++++++++++++++++++++++++++++----
 xen/include/xen/sched.h     |   13 +++
 3 files changed, 166 insertions(+), 23 deletions(-)

diff -r cc006f78cbe2 -r 2eb8efcc70d1 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Wed Aug 23 18:35:21 2006 +0100
+++ b/xen/arch/x86/domain_build.c       Wed Aug 23 18:38:49 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 cc006f78cbe2 -r 2eb8efcc70d1 xen/common/elf.c
--- a/xen/common/elf.c  Wed Aug 23 18:35:21 2006 +0100
+++ b/xen/common/elf.c  Wed Aug 23 18:38:49 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 cc006f78cbe2 -r 2eb8efcc70d1 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Wed Aug 23 18:35:21 2006 +0100
+++ b/xen/include/xen/sched.h   Wed Aug 23 18:38:49 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [XEN] Restore backwards compatibility by supporting __xen_guest, Xen patchbot-unstable <=