summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac27
-rw-r--r--kexec/Makefile1
-rw-r--r--kexec/arch/i386/crashdump-x86.c7
-rw-r--r--kexec/arch/i386/kexec-x86-common.c5
-rw-r--r--kexec/crashdump-xen.c6
-rw-r--r--kexec/kexec-xen.c42
-rw-r--r--kexec/kexec-xen.h70
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 */