diff options
author | Ian Campbell <ian.campbell@xensource.com> | 2007-03-16 10:10:24 +0000 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2007-03-19 13:38:50 +0900 |
commit | cdbc9b011fe43407908632d842e3a39e495e48d9 (patch) | |
tree | 99ab9065d606c17bfb838c9155c1a03694f929cc | |
parent | efac1da616a211517a4b0eaae098db6ade3bdd26 (diff) |
Set crash dump ELF header e_machine field based on underlying hypervisor architecture.
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 <ian.campbell@xensource.com>
Acked-by: Magnus Damm <magnus@valinux.co.jp>
Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r-- | configure.ac | 9 | ||||
-rw-r--r-- | kexec/crashdump-elf.c | 2 | ||||
-rw-r--r-- | kexec/crashdump-xen.c | 42 | ||||
-rw-r--r-- | kexec/crashdump.c | 8 | ||||
-rw-r--r-- | kexec/crashdump.h | 3 |
5 files changed, 63 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac index 9396d4b..4d1b226 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 gamecube 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); |