summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Campbell <ian.campbell@xensource.com>2007-03-16 10:10:24 +0000
committerSimon Horman <horms@verge.net.au>2007-03-19 13:38:50 +0900
commitcdbc9b011fe43407908632d842e3a39e495e48d9 (patch)
tree99ab9065d606c17bfb838c9155c1a03694f929cc
parentefac1da616a211517a4b0eaae098db6ade3bdd26 (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.ac9
-rw-r--r--kexec/crashdump-elf.c2
-rw-r--r--kexec/crashdump-xen.c42
-rw-r--r--kexec/crashdump.c8
-rw-r--r--kexec/crashdump.h3
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);