diff options
-rw-r--r-- | configure.ac | 27 | ||||
-rw-r--r-- | kexec/Makefile | 1 | ||||
-rw-r--r-- | kexec/arch/i386/crashdump-x86.c | 7 | ||||
-rw-r--r-- | kexec/arch/i386/kexec-x86-common.c | 5 | ||||
-rw-r--r-- | kexec/crashdump-xen.c | 6 | ||||
-rw-r--r-- | kexec/kexec-xen.c | 42 | ||||
-rw-r--r-- | kexec/kexec-xen.h | 70 |
7 files changed, 136 insertions, 22 deletions
diff --git a/configure.ac b/configure.ac index 0bd4587..cca2c0c 100644 --- a/configure.ac +++ b/configure.ac @@ -167,12 +167,27 @@ if test "$with_xen" = yes ; then AC_CHECK_HEADER(xenctrl.h, [AC_CHECK_LIB(xenctrl, xc_kexec_load, , AC_MSG_NOTICE([Xen support disabled]))]) - if test "$ac_cv_lib_xenctrl_xc_kexec_load" = yes ; then - AC_CHECK_LIB(xenctrl, xc_kexec_status, - AC_DEFINE(HAVE_KEXEC_CMD_STATUS, 1, - [The kexec_status call is available]), - AC_MSG_NOTICE([The kexec_status call is not available])) - fi +fi + +dnl Link libxenctrl.so at run-time rather than build-time +if test "$with_xen" = dl ; then + AC_CHECK_HEADER(dlfcn.h, + [AC_CHECK_LIB(dl, dlopen, , + AC_MSG_ERROR([Dynamic library linking not available]))], + AC_MSG_ERROR([Dynamic library linking header not available])) + AC_DEFINE(CONFIG_LIBXENCTRL_DL, 1, [Define to 1 to link libxenctrl.so at run-time rather than build-time]) + AC_CHECK_HEADER(xenctrl.h, + [AC_CHECK_LIB(xenctrl, xc_kexec_load, + AC_DEFINE(HAVE_LIBXENCTRL, 1, ), # required define, and prevent -lxenctrl + AC_MSG_NOTICE([Xen support disabled]))]) +fi + +dnl Check for the Xen kexec_status hypercall - reachable from --with-xen=yes|dl +if test "$ac_cv_lib_xenctrl_xc_kexec_load" = yes ; then + AC_CHECK_LIB(xenctrl, xc_kexec_status, + AC_DEFINE(HAVE_KEXEC_CMD_STATUS, 1, + [The kexec_status call is available]), + AC_MSG_NOTICE([The kexec_status call is not available])) fi dnl ---Sanity checks diff --git a/kexec/Makefile b/kexec/Makefile index 2b4fb3d..4db84d8 100644 --- a/kexec/Makefile +++ b/kexec/Makefile @@ -36,6 +36,7 @@ dist += kexec/Makefile \ kexec/kexec-elf-boot.h \ kexec/kexec-elf.h kexec/kexec-sha256.h \ kexec/kexec-zlib.h kexec/kexec-lzma.h \ + kexec/kexec-xen.h \ kexec/kexec-syscall.h kexec/kexec.h kexec/kexec.8 dist += kexec/proc_iomem.c diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c index 69a063a..437e8a8 100644 --- a/kexec/arch/i386/crashdump-x86.c +++ b/kexec/arch/i386/crashdump-x86.c @@ -43,13 +43,8 @@ #include "../../crashdump.h" #include "kexec-x86.h" #include "crashdump-x86.h" - -#ifdef HAVE_LIBXENCTRL -#include <xenctrl.h> -#endif /* HAVE_LIBXENCTRL */ - +#include "../../kexec-xen.h" #include "x86-linux-setup.h" - #include <x86/x86-linux.h> extern struct arch_options_t arch_options; diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c index be03618..de99758 100644 --- a/kexec/arch/i386/kexec-x86-common.c +++ b/kexec/arch/i386/kexec-x86-common.c @@ -39,10 +39,7 @@ #include "../../firmware_memmap.h" #include "../../crashdump.h" #include "kexec-x86.h" - -#ifdef HAVE_LIBXENCTRL -#include <xenctrl.h> -#endif /* HAVE_LIBXENCTRL */ +#include "../../kexec-xen.h" /* Used below but not present in (older?) xenctrl.h */ #ifndef E820_PMEM diff --git a/kexec/crashdump-xen.c b/kexec/crashdump-xen.c index 60594f6..2d6b2f9 100644 --- a/kexec/crashdump-xen.c +++ b/kexec/crashdump-xen.c @@ -15,12 +15,8 @@ #include "kexec.h" #include "crashdump.h" #include "kexec-syscall.h" - #include "config.h" - -#ifdef HAVE_LIBXENCTRL -#include <xenctrl.h> -#endif +#include "kexec-xen.h" struct crash_note_info { unsigned long base; diff --git a/kexec/kexec-xen.c b/kexec/kexec-xen.c index 2b448d3..d42a45a 100644 --- a/kexec/kexec-xen.c +++ b/kexec/kexec-xen.c @@ -10,10 +10,50 @@ #include "config.h" #ifdef HAVE_LIBXENCTRL -#include <xenctrl.h> +#include "kexec-xen.h" #include "crashdump.h" +#ifdef CONFIG_LIBXENCTRL_DL +void *xc_dlhandle; +xc_hypercall_buffer_t XC__HYPERCALL_BUFFER_NAME(HYPERCALL_BUFFER_NULL); +xc_interface *__xc_interface_open(xentoollog_logger *logger, + xentoollog_logger *dombuild_logger, + unsigned open_flags) +{ + xc_interface *xch = NULL; + + if (!xc_dlhandle) + xc_dlhandle = dlopen("libxenctrl.so", RTLD_NOW | RTLD_NODELETE); + + if (xc_dlhandle) { + typedef xc_interface *(*func_t)(xentoollog_logger *logger, + xentoollog_logger *dombuild_logger, + unsigned open_flags); + + func_t func = (func_t)dlsym(xc_dlhandle, "xc_interface_open"); + xch = func(logger, dombuild_logger, open_flags); + } + + return xch; +} + +int __xc_interface_close(xc_interface *xch) +{ + int rc = -1; + + if (xc_dlhandle) { + typedef int (*func_t)(xc_interface *xch); + + func_t func = (func_t)dlsym(xc_dlhandle, "xc_interface_close"); + rc = func(xch); + xc_dlhandle = NULL; + } + + return rc; +} +#endif /* CONFIG_LIBXENCTRL_DL */ + int xen_kexec_load(struct kexec_info *info) { uint32_t nr_segments = info->nr_segments; diff --git a/kexec/kexec-xen.h b/kexec/kexec-xen.h new file mode 100644 index 0000000..ffb8743 --- /dev/null +++ b/kexec/kexec-xen.h @@ -0,0 +1,70 @@ +#ifndef KEXEC_XEN_H +#define KEXEC_XEN_H + +#ifdef HAVE_LIBXENCTRL +#include <xenctrl.h> + +#ifdef CONFIG_LIBXENCTRL_DL +#include <dlfcn.h> + +/* The handle from dlopen(), needed by dlsym(), dlclose() */ +extern void *xc_dlhandle; + +/* Wrappers around xc_interface_open/close() to insert dlopen/dlclose() */ +xc_interface *__xc_interface_open(xentoollog_logger *logger, + xentoollog_logger *dombuild_logger, + unsigned open_flags); +int __xc_interface_close(xc_interface *xch); + +/* GCC expression statements for evaluating dlsym() */ +#define __xc_call(dtype, name, args...) \ +( \ + { dtype value; \ + typedef dtype (*func_t)(xc_interface *, ...); \ + func_t func = dlsym(xc_dlhandle, #name); \ + value = func(args); \ + value; } \ +) +#define __xc_data(dtype, name) \ +( \ + { dtype *value = (dtype *)dlsym(xc_dlhandle, #name); value; } \ +) + +/* The wrappers around utilized xenctrl.h functions */ +#define xc_interface_open(a, b, c) \ + __xc_interface_open(a, b, c) +#define xc_interface_close(a) \ + __xc_interface_close(a) +#define xc_version(args...) \ + __xc_call(int, xc_version, args) +#define xc_get_max_cpus(args...) \ + __xc_call(int, xc_get_max_cpus, args) +#define xc_get_machine_memory_map(args...) \ + __xc_call(int, xc_get_machine_memory_map, args) +#define xc_kexec_get_range(args...) \ + __xc_call(int, xc_kexec_get_range, args) +#define xc_kexec_load(args...) \ + __xc_call(int, xc_kexec_load, args) +#define xc_kexec_unload(args...) \ + __xc_call(int, xc_kexec_unload, args) +#define xc_kexec_status(args...) \ + __xc_call(int, xc_kexec_status, args) +#define xc_kexec_exec(args...) \ + __xc_call(int, xc_kexec_exec, args) +#define xc_hypercall_buffer_array_create(args...) \ + __xc_call(xc_hypercall_buffer_array_t *, xc_hypercall_buffer_array_create, args) +#define xc__hypercall_buffer_alloc_pages(args...) \ + __xc_call(void *, xc__hypercall_buffer_alloc_pages, args) +#define xc__hypercall_buffer_free_pages(args...) \ + __xc_call(void , xc__hypercall_buffer_free_pages, args) +#define xc__hypercall_buffer_array_alloc(args...) \ + __xc_call(void *, xc__hypercall_buffer_array_alloc, args) +#define xc__hypercall_buffer_array_get(args...) \ + __xc_call(void *, xc__hypercall_buffer_array_get, args) +#define xc_hypercall_buffer_array_destroy(args...) \ + __xc_call(void *, xc_hypercall_buffer_array_destroy, args) + +#endif /* CONFIG_LIBXENCTRL_DL */ +#endif /* HAVE_LIBXENCTRL */ + +#endif /* KEXEC_XEN_H */ |