# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID ac51e8f371083af035d03321d2e59d42ea080e26
# Parent c09dab67c17855458ee7dbed94e31c263454f217
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@xxxxxxxxxx>
---
tools/libxc/xc_linux_build.c | 16 +++++++++++-----
tools/libxc/xc_load_elf.c | 28 ++++++++++++++++------------
tools/libxc/xg_private.h | 1 +
xen/arch/x86/domain_build.c | 8 ++++++--
xen/common/elf.c | 27 +++++++++++++++------------
xen/include/xen/sched.h | 1 +
6 files changed, 50 insertions(+), 31 deletions(-)
diff -r c09dab67c178 -r ac51e8f37108 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c Wed Dec 13 20:43:47 2006 +0000
+++ b/tools/libxc/xc_linux_build.c Thu Dec 14 10:29:44 2006 +0000
@@ -596,15 +596,21 @@ static int compat_check(int xc_handle, s
}
if (strstr(xen_caps, "xen-3.0-x86_32p")) {
- if (dsi->pae_kernel == PAEKERN_no) {
+ if (dsi->pae_kernel == PAEKERN_bimodal) {
+ dsi->pae_kernel = PAEKERN_extended_cr3;
+ } else if (dsi->pae_kernel == PAEKERN_no) {
xc_set_error(XC_INVALID_KERNEL,
"Non PAE-kernel on PAE host.");
return 0;
}
- } else if (dsi->pae_kernel != PAEKERN_no) {
- xc_set_error(XC_INVALID_KERNEL,
- "PAE-kernel on non-PAE host.");
- return 0;
+ } else {
+ if (dsi->pae_kernel == PAEKERN_bimodal) {
+ dsi->pae_kernel = PAEKERN_no;
+ } else if (dsi->pae_kernel != PAEKERN_no) {
+ xc_set_error(XC_INVALID_KERNEL,
+ "PAE-kernel on non-PAE host.");
+ return 0;
+ }
}
return 1;
diff -r c09dab67c178 -r ac51e8f37108 tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Wed Dec 13 20:43:47 2006 +0000
+++ b/tools/libxc/xc_load_elf.c Thu Dec 14 10:29:44 2006 +0000
@@ -325,17 +325,6 @@ static int parseelfimage(const char *ima
return -EINVAL;
}
- /* Find the section-header strings table. */
- if ( ehdr->e_shstrndx == SHN_UNDEF )
- {
- xc_set_error(XC_INVALID_KERNEL,
- "ELF image has no section-header strings table
(shstrtab).");
- return -EINVAL;
- }
- shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
- (ehdr->e_shstrndx*ehdr->e_shentsize));
- shstrtab = image + shdr->sh_offset;
-
dsi->__elfnote_section = NULL;
dsi->__xen_guest_string = NULL;
@@ -354,6 +343,17 @@ static int parseelfimage(const char *ima
/* Fall back to looking for the special '__xen_guest' section. */
if ( dsi->__elfnote_section == NULL )
{
+ /* Find the section-header strings table. */
+ if ( ehdr->e_shstrndx == SHN_UNDEF )
+ {
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF image has no section-header strings table.");
+ return -EINVAL;
+ }
+ shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
+ (ehdr->e_shstrndx*ehdr->e_shentsize));
+ shstrtab = image + shdr->sh_offset;
+
for ( h = 0; h < ehdr->e_shnum; h++ )
{
shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
@@ -400,6 +400,8 @@ static int parseelfimage(const char *ima
}
/*
+ * A "bimodal" ELF note indicates the kernel will adjust to the
+ * current paging mode, including handling extended cr3 syntax.
* 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.
@@ -408,7 +410,9 @@ static int parseelfimage(const char *ima
if ( dsi->__elfnote_section )
{
p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
- if ( p != NULL && strncmp(p, "yes", 3) == 0 )
+ if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
+ dsi->pae_kernel = PAEKERN_bimodal;
+ else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
dsi->pae_kernel = PAEKERN_extended_cr3;
}
diff -r c09dab67c178 -r ac51e8f37108 tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h Wed Dec 13 20:43:47 2006 +0000
+++ b/tools/libxc/xg_private.h Thu Dec 14 10:29:44 2006 +0000
@@ -132,6 +132,7 @@ struct domain_setup_info
#define PAEKERN_no 0
#define PAEKERN_yes 1
#define PAEKERN_extended_cr3 2
+#define PAEKERN_bimodal 3
unsigned int pae_kernel;
unsigned int load_symtab;
diff -r c09dab67c178 -r ac51e8f37108 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c Wed Dec 13 20:43:47 2006 +0000
+++ b/xen/arch/x86/domain_build.c Thu Dec 14 10:29:44 2006 +0000
@@ -321,8 +321,11 @@ int construct_dom0(struct domain *d,
if ( (rc = parseelfimage(&dsi)) != 0 )
return rc;
- dom0_pae = (dsi.pae_kernel != PAEKERN_no);
xen_pae = (CONFIG_PAGING_LEVELS == 3);
+ if (dsi.pae_kernel == PAEKERN_bimodal)
+ dom0_pae = xen_pae;
+ else
+ dom0_pae = (dsi.pae_kernel != PAEKERN_no);
if ( dom0_pae != xen_pae )
{
printk("PAE mode mismatch between Xen and DOM0 (xen=%s, dom0=%s)\n",
@@ -330,7 +333,8 @@ int construct_dom0(struct domain *d,
return -EINVAL;
}
- if ( xen_pae && dsi.pae_kernel == PAEKERN_extended_cr3 )
+ if ( xen_pae && (dsi.pae_kernel == PAEKERN_extended_cr3 ||
+ dsi.pae_kernel == PAEKERN_bimodal) )
set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist);
if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL )
diff -r c09dab67c178 -r ac51e8f37108 xen/common/elf.c
--- a/xen/common/elf.c Wed Dec 13 20:43:47 2006 +0000
+++ b/xen/common/elf.c Thu Dec 14 10:29:44 2006 +0000
@@ -216,16 +216,6 @@ int parseelfimage(struct domain_setup_in
return -EINVAL;
}
- /* Find the section-header strings table. */
- if ( ehdr->e_shstrndx == SHN_UNDEF )
- {
- printk("ELF image has no section-header strings table (shstrtab).\n");
- return -EINVAL;
- }
- shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
- (ehdr->e_shstrndx*ehdr->e_shentsize));
- shstrtab = image + shdr->sh_offset;
-
dsi->__elfnote_section = NULL;
dsi->__xen_guest_string = NULL;
@@ -244,6 +234,16 @@ int parseelfimage(struct domain_setup_in
/* Fall back to looking for the special '__xen_guest' section. */
if ( dsi->__elfnote_section == NULL )
{
+ /* Find the section-header strings table. */
+ if ( ehdr->e_shstrndx == SHN_UNDEF )
+ {
+ printk("ELF image has no section-header strings table.\n");
+ return -EINVAL;
+ }
+ shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
+ (ehdr->e_shstrndx*ehdr->e_shentsize));
+ shstrtab = image + shdr->sh_offset;
+
for ( h = 0; h < ehdr->e_shnum; h++ )
{
shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
@@ -286,6 +286,8 @@ int parseelfimage(struct domain_setup_in
}
/*
+ * A "bimodal" ELF note indicates the kernel will adjust to the
+ * current paging mode, including handling extended cr3 syntax.
* 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.
@@ -294,9 +296,10 @@ int parseelfimage(struct domain_setup_in
if ( dsi->__elfnote_section )
{
p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
- if ( p != NULL && strncmp(p, "yes", 3) == 0 )
+ if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
+ dsi->pae_kernel = PAEKERN_bimodal;
+ else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
dsi->pae_kernel = PAEKERN_extended_cr3;
-
}
else
{
diff -r c09dab67c178 -r ac51e8f37108 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Wed Dec 13 20:43:47 2006 +0000
+++ b/xen/include/xen/sched.h Thu Dec 14 10:29:44 2006 +0000
@@ -188,6 +188,7 @@ struct domain_setup_info
#define PAEKERN_no 0
#define PAEKERN_yes 1
#define PAEKERN_extended_cr3 2
+#define PAEKERN_bimodal 3
unsigned int pae_kernel;
/* Initialised by loader: Private. */
unsigned long elf_paddr_offset;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|