This is necessary when running Xen with a 64 bit hypervisor and 32 bit
domain 0 since the CPU crash notes will be 64 bit.

Detecting the hypervisor archiecture requires libxenctrl and therefore this
support is optional and disabled by default.

Signed-off-by: Ian Campbell <[EMAIL PROTECTED]>
---

 configure.ac          |    9 +++++++++
 kexec/crashdump-elf.c |    2 +-
 kexec/crashdump-xen.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 kexec/crashdump.c     |    8 ++++++++
 kexec/crashdump.h     |    3 +++
 5 files changed, 63 insertions(+), 1 deletions(-)

diff --git a/configure.ac b/configure.ac
index 98afd5e..df8dfa3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -72,6 +72,9 @@ AC_ARG_WITH([gamecube], 
AC_HELP_STRING([--with-gamecube],[enable gamecube suppor
 AC_ARG_WITH([zlib], AC_HELP_STRING([--without-zlib],[disable zlib support]),
        [ with_zlib="$withval"], [ with_zlib=yes ] )
 
+AC_ARG_WITH([xen], AC_HELP_STRING([--with-xen],[enable extended xen support]),
+       [ with_xen="$withval"], [ with_xen=no ] )
+
 dnl ---Programs
 dnl To specify a different compiler, just 'export CC=/path/to/compiler'
 
@@ -109,6 +112,12 @@ if test "$with_zlib" = yes ; then
        AC_CHECK_HEADER(zlib.h, AC_CHECK_LIB(z, inflateInit_, 
[AC_DEFINE(HAVE_ZLIB_H, 1) LIBS="$LIBS -lz"]))
 fi
 
+dnl find Xen control stack libraries
+if test "$with_xen" = yes ; then
+       AC_CHECK_HEADER(xenctrl.h, AC_CHECK_LIB(xenctrl, xc_version,
+               [AC_DEFINE(HAVE_XENCTRL_H, 1) LIBS="$LIBS -lxenctrl"]))
+fi
+
 dnl ---Sanity checks
 if test "$CC"      = "no"; then AC_MSG_ERROR([cc not found]) fi
 if test "$CPP"     = "no"; then AC_MSG_ERROR([cpp not found]) fi
diff --git a/kexec/crashdump-elf.c b/kexec/crashdump-elf.c
index dd89180..ba570eb 100644
--- a/kexec/crashdump-elf.c
+++ b/kexec/crashdump-elf.c
@@ -103,7 +103,7 @@ int FUNC(struct kexec_info *info,
        elf->e_ident[EI_OSABI] = ELFOSABI_NONE;
        memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
        elf->e_type     = ET_CORE;
-       elf->e_machine  = elf_info->machine;
+       elf->e_machine  = crash_architecture(elf_info);
        elf->e_version  = EV_CURRENT;
        elf->e_entry    = 0;
        elf->e_phoff    = sizeof(EHDR);
diff --git a/kexec/crashdump-xen.c b/kexec/crashdump-xen.c
index aa096e6..30506e2 100644
--- a/kexec/crashdump-xen.c
+++ b/kexec/crashdump-xen.c
@@ -3,6 +3,7 @@
 #include <stdarg.h>
 #include <string.h>
 #include <stdlib.h>
+#include <elf.h>
 #include <errno.h>
 #include <limits.h>
 #include <sys/types.h>
@@ -12,6 +13,10 @@
 #include "kexec.h"
 #include "crashdump.h"
 
+#ifdef HAVE_XENCTRL_H
+#include <xenctrl.h>
+#endif
+
 struct crash_note_info {
        unsigned long base;
        unsigned long length;
@@ -27,6 +32,43 @@ int xen_present(void)
        return stat("/proc/xen", &buf) == 0;
 }
 
+unsigned long xen_architecture(struct crash_elf_info *elf_info)
+{
+       unsigned long machine = elf_info->machine;
+#ifdef HAVE_XENCTRL_H
+       int xc, rc;
+       xen_capabilities_info_t capabilities;
+
+       if (!xen_present())
+               goto out;
+
+       memset(capabilities, '0', XEN_CAPABILITIES_INFO_LEN);
+
+       xc = xc_interface_open();
+       if ( xc == -1 ) {
+               fprintf(stderr, "failed to open xen control interface.\n");
+               goto out;
+       }
+
+       rc = xc_version(xc, XENVER_capabilities, &capabilities[0]);
+       if ( rc == -1 ) {
+               fprintf(stderr, "failed to make Xen version hypercall.\n");
+               goto out_close;
+       }
+
+       if (strstr(capabilities, "xen-3.0-x86_64"))
+               machine = EM_X86_64;
+        else if (strstr(capabilities, "xen-3.0-x86_32"))
+               machine = EM_386;
+
+ out_close:
+       xc_interface_close(xc);
+
+ out:
+#endif
+       return machine;
+}
+
 static int xen_crash_note_callback(void *data, int nr,
                                   char *str,
                                   unsigned long base,
diff --git a/kexec/crashdump.c b/kexec/crashdump.c
index f6fd911..1c08606 100644
--- a/kexec/crashdump.c
+++ b/kexec/crashdump.c
@@ -51,6 +51,14 @@
 #undef EHDR
 #undef FUNC
 
+unsigned long crash_architecture(struct crash_elf_info *elf_info)
+{
+       if (xen_present())
+               return xen_architecture(elf_info);
+       else
+               return elf_info->machine;
+}
+
 /* Returns the physical address of start of crash notes buffer for a cpu. */
 int get_crash_notes_per_cpu(int cpu, uint64_t *addr, uint64_t *len)
 {
diff --git a/kexec/crashdump.h b/kexec/crashdump.h
index 2e9c7cc..e99bdd2 100644
--- a/kexec/crashdump.h
+++ b/kexec/crashdump.h
@@ -42,7 +42,10 @@ int crash_create_elf64_headers(struct kexec_info *info,
                               void **buf, unsigned long *size,
                               unsigned long align);
 
+unsigned long crash_architecture(struct crash_elf_info *elf_info);
+
 int xen_present(void);
+unsigned long xen_architecture(struct crash_elf_info *elf_info);
 int xen_get_nr_phys_cpus(void);
 int xen_get_note(int cpu, uint64_t *addr, uint64_t *len);
 
_______________________________________________
fastboot mailing list
[email protected]
https://lists.osdl.org/mailman/listinfo/fastboot

Reply via email to