The series adds support for the new hypercall ABI which should be provided by Xen 4.4. Images are loaded into Xen directly with no kernel involvement. Please do not apply until the hypervisor side patches are applied to Xen. Patch 1 makes libxc 4.4 mandatory for Xen support. Patch 2-3 remove uses of /proc/iomem in favour of libxc. Patch 4 adds the support for loading, unloading, and exec''ing an image in Xen. This series explicitly drops support for older version of libxc/Xen as supporting kexec on these hypervisors requires kernel support that will never be available upstream. Changes in v7: - extend extra segment to 0-1 MiB so the VGA memory is accesible by the image. Changes in v6: - Close libxc handle a few error paths. Changes in v5: - Dropped the purgatory patch. Changes in v4: - KEXEC_ARCH_DEFAULT => EM_386 - add segment in the crash case for the backup src. Changes in v3 (not posted): - Rebased Changes in v2: - Patch from Don Sultz: use libxc for vmcoreinfo. - Use xc_get_max_cpus() to get number of PCPUs. - Enable unload and exec of images. David
From: David Vrabel <david.vrabel@citrix.com> libxc from Xen 4.4 added xc_kexec_load() which will be required to load images into Xen in the future. Remove all the #ifdef''ery for older versions of libxc. Signed-off-by: David Vrabel <david.vrabel@citrix.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> --- configure.ac | 5 +- kexec/arch/i386/crashdump-x86.c | 110 ------------------------------------ kexec/arch/i386/kexec-x86-common.c | 103 --------------------------------- kexec/crashdump-xen.c | 12 ---- 4 files changed, 1 insertions(+), 229 deletions(-) diff --git a/configure.ac b/configure.ac index 7b61dbf..50b706a 100644 --- a/configure.ac +++ b/configure.ac @@ -161,11 +161,8 @@ 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_CHECK_LIB(xenctrl, xc_kexec_load, , AC_MSG_NOTICE([Xen support disabled]))) - if test "$ac_cv_lib_xenctrl_xc_version" = yes ; then - AC_CHECK_FUNCS(xc_get_machine_memory_map) - fi fi dnl ---Sanity checks diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c index e44fceb..7aa5a12 100644 --- a/kexec/arch/i386/crashdump-x86.c +++ b/kexec/arch/i386/crashdump-x86.c @@ -43,14 +43,7 @@ #include "crashdump-x86.h" #ifdef HAVE_LIBXENCTRL -#ifdef HAVE_XC_GET_MACHINE_MEMORY_MAP #include <xenctrl.h> -#else -#define __XEN_TOOLS__ 1 -#include <xen/xen.h> -#include <xen/memory.h> -#include <xen/sys/privcmd.h> -#endif /* HAVE_XC_GET_MACHINE_MEMORY_MAP */ #endif /* HAVE_LIBXENCTRL */ #include <x86/x86-linux.h> @@ -300,34 +293,20 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges, } #ifdef HAVE_LIBXENCTRL -#ifdef HAVE_XC_GET_MACHINE_MEMORY_MAP static int get_crash_memory_ranges_xen(struct memory_range **range, int *ranges, unsigned long lowmem_limit) { int j, rc, ret = -1; struct e820entry e820entries[CRASH_MAX_MEMORY_RANGES]; unsigned int i; -#ifdef XENCTRL_HAS_XC_INTERFACE xc_interface *xc; -#else - int xc; -#endif -#ifdef XENCTRL_HAS_XC_INTERFACE xc = xc_interface_open(NULL, NULL, 0); if (!xc) { fprintf(stderr, "%s: Failed to open Xen control interface\n", __func__); goto err; } -#else - xc = xc_interface_open(); - - if (xc == -1) { - fprintf(stderr, "%s: Failed to open Xen control interface\n", __func__); - goto err; - } -#endif rc = xc_get_machine_memory_map(xc, e820entries, CRASH_MAX_MEMORY_RANGES); @@ -364,95 +343,6 @@ err: static int get_crash_memory_ranges_xen(struct memory_range **range, int *ranges, unsigned long lowmem_limit) { - int fd, j, rc, ret = -1; - privcmd_hypercall_t hypercall; - struct e820entry *e820entries = NULL; - struct xen_memory_map *xen_memory_map = NULL; - unsigned int i; - - fd = open("/proc/xen/privcmd", O_RDWR); - - if (fd == -1) { - fprintf(stderr, "%s: open(/proc/xen/privcmd): %m\n", __func__); - goto err; - } - - rc = posix_memalign((void **)&e820entries, getpagesize(), - sizeof(struct e820entry) * CRASH_MAX_MEMORY_RANGES); - - if (rc) { - fprintf(stderr, "%s: posix_memalign(e820entries): %s\n", __func__, strerror(rc)); - e820entries = NULL; - goto err; - } - - rc = posix_memalign((void **)&xen_memory_map, getpagesize(), - sizeof(struct xen_memory_map)); - - if (rc) { - fprintf(stderr, "%s: posix_memalign(xen_memory_map): %s\n", __func__, strerror(rc)); - xen_memory_map = NULL; - goto err; - } - - if (mlock(e820entries, sizeof(struct e820entry) * CRASH_MAX_MEMORY_RANGES) == -1) { - fprintf(stderr, "%s: mlock(e820entries): %m\n", __func__); - goto err; - } - - if (mlock(xen_memory_map, sizeof(struct xen_memory_map)) == -1) { - fprintf(stderr, "%s: mlock(xen_memory_map): %m\n", __func__); - goto err; - } - - xen_memory_map->nr_entries = CRASH_MAX_MEMORY_RANGES; - set_xen_guest_handle(xen_memory_map->buffer, e820entries); - - hypercall.op = __HYPERVISOR_memory_op; - hypercall.arg[0] = XENMEM_machine_memory_map; - hypercall.arg[1] = (__u64)xen_memory_map; - - rc = ioctl(fd, IOCTL_PRIVCMD_HYPERCALL, &hypercall); - - if (rc == -1) { - fprintf(stderr, "%s: ioctl(IOCTL_PRIVCMD_HYPERCALL): %m\n", __func__); - goto err; - } - - for (i = 0, j = 0; i < xen_memory_map->nr_entries && - j < CRASH_MAX_MEMORY_RANGES; ++i, ++j) { - crash_memory_range[j].start = e820entries[i].addr; - crash_memory_range[j].end = e820entries[i].addr + e820entries[i].size - 1; - crash_memory_range[j].type = xen_e820_to_kexec_type(e820entries[i].type); - segregate_lowmem_region(&j, lowmem_limit); - } - - *range = crash_memory_range; - *ranges = j; - - qsort(*range, *ranges, sizeof(struct memory_range), compare_ranges); - - for (i = 0; i < crash_reserved_mem_nr; i++) - if (exclude_region(ranges, crash_reserved_mem[i].start, - crash_reserved_mem[i].end) < 0) - goto err; - - ret = 0; - -err: - munlock(xen_memory_map, sizeof(struct xen_memory_map)); - munlock(e820entries, sizeof(struct e820entry) * CRASH_MAX_MEMORY_RANGES); - free(xen_memory_map); - free(e820entries); - close(fd); - - return ret; -} -#endif /* HAVE_XC_GET_MACHINE_MEMORY_MAP */ -#else -static int get_crash_memory_ranges_xen(struct memory_range **range, - int *ranges, unsigned long lowmem_limit) -{ return 0; } #endif /* HAVE_LIBXENCTRL */ diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c index ed6c950..bf58f53 100644 --- a/kexec/arch/i386/kexec-x86-common.c +++ b/kexec/arch/i386/kexec-x86-common.c @@ -40,15 +40,7 @@ #include "kexec-x86.h" #ifdef HAVE_LIBXENCTRL -#ifdef HAVE_XC_GET_MACHINE_MEMORY_MAP #include <xenctrl.h> -#else -#define __XEN_TOOLS__ 1 -#include <x86/x86-linux.h> -#include <xen/xen.h> -#include <xen/memory.h> -#include <xen/sys/privcmd.h> -#endif /* HAVE_XC_GET_MACHINE_MEMORY_MAP */ #endif /* HAVE_LIBXENCTRL */ static struct memory_range memory_range[MAX_MEMORY_RANGES]; @@ -173,33 +165,19 @@ unsigned xen_e820_to_kexec_type(uint32_t type) * * @return 0 on success, any other value on failure. */ -#ifdef HAVE_XC_GET_MACHINE_MEMORY_MAP static int get_memory_ranges_xen(struct memory_range **range, int *ranges) { int rc, ret = -1; struct e820entry e820entries[MAX_MEMORY_RANGES]; unsigned int i; -#ifdef XENCTRL_HAS_XC_INTERFACE xc_interface *xc; -#else - int xc; -#endif -#ifdef XENCTRL_HAS_XC_INTERFACE xc = xc_interface_open(NULL, NULL, 0); if (!xc) { fprintf(stderr, "%s: Failed to open Xen control interface\n", __func__); goto err; } -#else - xc = xc_interface_open(); - - if (xc == -1) { - fprintf(stderr, "%s: Failed to open Xen control interface\n", __func__); - goto err; - } -#endif rc = xc_get_machine_memory_map(xc, e820entries, MAX_MEMORY_RANGES); @@ -229,87 +207,6 @@ err: #else static int get_memory_ranges_xen(struct memory_range **range, int *ranges) { - int fd, rc, ret = -1; - privcmd_hypercall_t hypercall; - struct e820entry *e820entries = NULL; - struct xen_memory_map *xen_memory_map = NULL; - unsigned int i; - - fd = open("/proc/xen/privcmd", O_RDWR); - - if (fd == -1) { - fprintf(stderr, "%s: open(/proc/xen/privcmd): %m\n", __func__); - goto err; - } - - rc = posix_memalign((void **)&e820entries, sysconf(_SC_PAGESIZE), - sizeof(struct e820entry) * MAX_MEMORY_RANGES); - - if (rc) { - fprintf(stderr, "%s: posix_memalign(e820entries): %s\n", __func__, strerror(rc)); - e820entries = NULL; - goto err; - } - - rc = posix_memalign((void **)&xen_memory_map, sysconf(_SC_PAGESIZE), - sizeof(struct xen_memory_map)); - - if (rc) { - fprintf(stderr, "%s: posix_memalign(xen_memory_map): %s\n", __func__, strerror(rc)); - xen_memory_map = NULL; - goto err; - } - - if (mlock(e820entries, sizeof(struct e820entry) * MAX_MEMORY_RANGES) == -1) { - fprintf(stderr, "%s: mlock(e820entries): %m\n", __func__); - goto err; - } - - if (mlock(xen_memory_map, sizeof(struct xen_memory_map)) == -1) { - fprintf(stderr, "%s: mlock(xen_memory_map): %m\n", __func__); - goto err; - } - - xen_memory_map->nr_entries = MAX_MEMORY_RANGES; - set_xen_guest_handle(xen_memory_map->buffer, e820entries); - - hypercall.op = __HYPERVISOR_memory_op; - hypercall.arg[0] = XENMEM_machine_memory_map; - hypercall.arg[1] = (__u64)xen_memory_map; - - rc = ioctl(fd, IOCTL_PRIVCMD_HYPERCALL, &hypercall); - - if (rc == -1) { - fprintf(stderr, "%s: ioctl(IOCTL_PRIVCMD_HYPERCALL): %m\n", __func__); - goto err; - } - - for (i = 0; i < xen_memory_map->nr_entries; ++i) { - memory_range[i].start = e820entries[i].addr; - memory_range[i].end = e820entries[i].addr + e820entries[i].size; - memory_range[i].type = xen_e820_to_kexec_type(e820entries[i].type); - } - - qsort(memory_range, xen_memory_map->nr_entries, sizeof(struct memory_range), compare_ranges); - - *range = memory_range; - *ranges = xen_memory_map->nr_entries; - - ret = 0; - -err: - munlock(xen_memory_map, sizeof(struct xen_memory_map)); - munlock(e820entries, sizeof(struct e820entry) * MAX_MEMORY_RANGES); - free(xen_memory_map); - free(e820entries); - close(fd); - - return ret; -} -#endif /* HAVE_XC_GET_MACHINE_MEMORY_MAP */ -#else -static int get_memory_ranges_xen(struct memory_range **range, int *ranges) -{ return 0; } #endif /* HAVE_LIBXENCTRL */ diff --git a/kexec/crashdump-xen.c b/kexec/crashdump-xen.c index d8bd0f4..ff4706c 100644 --- a/kexec/crashdump-xen.c +++ b/kexec/crashdump-xen.c @@ -131,30 +131,18 @@ unsigned long xen_architecture(struct crash_elf_info *elf_info) #ifdef HAVE_LIBXENCTRL int rc; xen_capabilities_info_t capabilities; -#ifdef XENCTRL_HAS_XC_INTERFACE xc_interface *xc; -#else - int xc; -#endif if (!xen_present()) goto out; memset(capabilities, ''0'', XEN_CAPABILITIES_INFO_LEN); -#ifdef XENCTRL_HAS_XC_INTERFACE xc = xc_interface_open(NULL, NULL, 0); if ( !xc ) { fprintf(stderr, "failed to open xen control interface.\n"); goto out; } -#else - xc = xc_interface_open(); - if ( xc == -1 ) { - fprintf(stderr, "failed to open xen control interface.\n"); - goto out; - } -#endif rc = xc_version(xc, XENVER_capabilities, &capabilities[0]); if ( rc == -1 ) { -- 1.7.2.5
David Vrabel
2013-Nov-06 14:55 UTC
[PATCH 2/4] kexec/xen: use libxc to get location of crash notes
From: David Vrabel <david.vrabel@citrix.com> Use xc_kexec_get_range(KEXEC_RANGE_MA_CPU) instead of parsing /proc/iomem (which is only populated by non-upstream ("classic") Xen kernels). Signed-off-by: David Vrabel <david.vrabel@citrix.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> --- kexec/crashdump-xen.c | 67 +++++++++++++++++++++++++++++------------------- 1 files changed, 40 insertions(+), 27 deletions(-) diff --git a/kexec/crashdump-xen.c b/kexec/crashdump-xen.c index ff4706c..8185423 100644 --- a/kexec/crashdump-xen.c +++ b/kexec/crashdump-xen.c @@ -163,42 +163,55 @@ unsigned long xen_architecture(struct crash_elf_info *elf_info) return machine; } -static int xen_crash_note_callback(void *UNUSED(data), int nr, - char *UNUSED(str), - unsigned long base, - unsigned long length) -{ - struct crash_note_info *note = xen_phys_notes + nr; - - note->base = base; - note->length = length; - - return 0; -} - +#ifdef HAVE_LIBXENCTRL int xen_get_nr_phys_cpus(void) { - char *match = "Crash note\n"; - int cpus, n; + xc_interface *xc; + int max_cpus; + int cpu = -1; if (xen_phys_cpus) return xen_phys_cpus; - if ((cpus = kexec_iomem_for_each_line(match, NULL, NULL))) { - n = sizeof(struct crash_note_info) * cpus; - xen_phys_notes = malloc(n); - if (!xen_phys_notes) { - fprintf(stderr, "failed to allocate xen_phys_notes.\n"); - return -1; - } - memset(xen_phys_notes, 0, n); - kexec_iomem_for_each_line(match, - xen_crash_note_callback, NULL); - xen_phys_cpus = cpus; + xc = xc_interface_open(NULL, NULL, 0); + if (!xc) { + fprintf(stderr, "failed to open xen control interface.\n"); + return -1; } - return cpus; + max_cpus = xc_get_max_cpus(xc); + if (max_cpus <= 0) + goto out; + + xen_phys_notes = calloc(max_cpus, sizeof(*xen_phys_notes)); + if (xen_phys_notes == NULL) + goto out; + + for (cpu = 0; cpu < max_cpus; cpu++) { + uint64_t size, start; + int ret; + + ret = xc_kexec_get_range(xc, KEXEC_RANGE_MA_CPU, cpu, &size, &start); + if (ret < 0) + break; + + xen_phys_notes[cpu].base = start; + xen_phys_notes[cpu].length = size; + } + + xen_phys_cpus = cpu; + +out: + xc_interface_close(xc); + return cpu; } +#else +int xen_get_nr_phys_cpus(void) +{ + return -1; +} +#endif + int xen_get_note(int cpu, uint64_t *addr, uint64_t *len) { -- 1.7.2.5
David Vrabel
2013-Nov-06 14:55 UTC
[PATCH 3/4] kexec/xen: switch to use xc_kexec_get_range for get_xen_vmcoreinfo.
From: Don Slutz <Don@CloudSwitch.com> Signed-off-by: Don Slutz <Don@CloudSwitch.com> Signed-off-by: David Vrabel <david.vrabel@citrix.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> --- kexec/crashdump-xen.c | 25 +++++++++++++++++++++++++ kexec/crashdump.c | 5 ----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/kexec/crashdump-xen.c b/kexec/crashdump-xen.c index 8185423..79b68e0 100644 --- a/kexec/crashdump-xen.c +++ b/kexec/crashdump-xen.c @@ -164,6 +164,26 @@ unsigned long xen_architecture(struct crash_elf_info *elf_info) } #ifdef HAVE_LIBXENCTRL +int get_xen_vmcoreinfo(uint64_t *addr, uint64_t *len) +{ + xc_interface *xc; + int ret = 0; + + xc = xc_interface_open(NULL, NULL, 0); + if (!xc) { + fprintf(stderr, "failed to open xen control interface.\n"); + return -1; + } + + ret = xc_kexec_get_range(xc, KEXEC_RANGE_MA_VMCOREINFO, 0, len, addr); + + xc_interface_close(xc); + + if (ret < 0) + return -1; + return 0; +} + int xen_get_nr_phys_cpus(void) { xc_interface *xc; @@ -206,6 +226,11 @@ out: return cpu; } #else +int get_xen_vmcoreinfo(uint64_t *addr, uint64_t *len) +{ + return -1; +} + int xen_get_nr_phys_cpus(void) { return -1; diff --git a/kexec/crashdump.c b/kexec/crashdump.c index 8d88fdf..131e624 100644 --- a/kexec/crashdump.c +++ b/kexec/crashdump.c @@ -157,8 +157,3 @@ int get_kernel_vmcoreinfo(uint64_t *addr, uint64_t *len) { return get_vmcoreinfo("/sys/kernel/vmcoreinfo", addr, len); } - -int get_xen_vmcoreinfo(uint64_t *addr, uint64_t *len) -{ - return get_vmcoreinfo("/sys/hypervisor/vmcoreinfo", addr, len); -} -- 1.7.2.5
David Vrabel
2013-Nov-06 14:55 UTC
[PATCH 4/4] kexec/xen: directly load images images into Xen
From: David Vrabel <david.vrabel@citrix.com> Xen 4.4 has an improvided kexec hypercall ABI that allows images to be loaded and executed without any kernel involvement. Use the API provided by libxc to load images when running in a Xen guest. Support for loading images via the kexec_load syscall in non-upstream ("classic") Xen kernels is no longer supported. Signed-off-by: David Vrabel <david.vrabel@citrix.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> --- kexec/Makefile | 1 + kexec/arch/i386/crashdump-x86.c | 20 +++++- kexec/crashdump-xen.c | 34 ++++++++++ kexec/crashdump.h | 3 +- kexec/kexec-xen.c | 139 +++++++++++++++++++++++++++++++++++++++ kexec/kexec.c | 24 +++++-- kexec/kexec.h | 5 ++ 7 files changed, 218 insertions(+), 8 deletions(-) create mode 100644 kexec/kexec-xen.c diff --git a/kexec/Makefile b/kexec/Makefile index 8a6138d..dc9dab1 100644 --- a/kexec/Makefile +++ b/kexec/Makefile @@ -25,6 +25,7 @@ KEXEC_SRCS_base += kexec/phys_arch.c KEXEC_SRCS_base += kexec/kernel_version.c KEXEC_SRCS_base += kexec/lzma.c KEXEC_SRCS_base += kexec/zlib.c +KEXEC_SRCS_base += kexec/kexec-xen.c KEXEC_GENERATED_SRCS += $(PURGATORY_HEX_C) diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c index 7aa5a12..85f3a87 100644 --- a/kexec/arch/i386/crashdump-x86.c +++ b/kexec/arch/i386/crashdump-x86.c @@ -990,8 +990,24 @@ static int crashkernel_mem_callback(void *UNUSED(data), int nr, int is_crashkernel_mem_reserved(void) { - crash_reserved_mem_nr = kexec_iomem_for_each_line("Crash kernel\n", - crashkernel_mem_callback, NULL); + int ret; + + if (xen_present()) { + uint64_t start, end; + + ret = xen_get_crashkernel_region(&start, &end); + if (ret < 0) + return 0; + + crash_reserved_mem[0].start = start; + crash_reserved_mem[0].end = end; + crash_reserved_mem[0].type = RANGE_RAM; + crash_reserved_mem_nr = 1; + } else { + ret = kexec_iomem_for_each_line("Crash kernel\n", + crashkernel_mem_callback, NULL); + crash_reserved_mem_nr = ret; + } return !!crash_reserved_mem_nr; } diff --git a/kexec/crashdump-xen.c b/kexec/crashdump-xen.c index 79b68e0..60594f6 100644 --- a/kexec/crashdump-xen.c +++ b/kexec/crashdump-xen.c @@ -252,3 +252,37 @@ int xen_get_note(int cpu, uint64_t *addr, uint64_t *len) return 0; } + +#ifdef HAVE_LIBXENCTRL +int xen_get_crashkernel_region(uint64_t *start, uint64_t *end) +{ + uint64_t size; + xc_interface *xc; + int rc = -1; + + xc = xc_interface_open(NULL, NULL, 0); + if (!xc) { + fprintf(stderr, "failed to open xen control interface.\n"); + goto out; + } + + rc = xc_kexec_get_range(xc, KEXEC_RANGE_MA_CRASH, 0, &size, start); + if (rc < 0) { + fprintf(stderr, "failed to get crash region from hypervisor.\n"); + goto out_close; + } + + *end = *start + size - 1; + +out_close: + xc_interface_close(xc); + +out: + return rc; +} +#else +int xen_get_crashkernel_region(uint64_t *start, uint64_t *end) +{ + return -1; +} +#endif diff --git a/kexec/crashdump.h b/kexec/crashdump.h index 0f7c2ea..95f1f0c 100644 --- a/kexec/crashdump.h +++ b/kexec/crashdump.h @@ -1,6 +1,7 @@ #ifndef CRASHDUMP_H #define CRASHDUMP_H +int get_crashkernel_region(uint64_t *start, uint64_t *end); extern int get_crash_notes_per_cpu(int cpu, uint64_t *addr, uint64_t *len); extern int get_kernel_vmcoreinfo(uint64_t *addr, uint64_t *len); extern int get_xen_vmcoreinfo(uint64_t *addr, uint64_t *len); @@ -56,9 +57,9 @@ unsigned long crash_architecture(struct crash_elf_info *elf_info); unsigned long phys_to_virt(struct crash_elf_info *elf_info, unsigned long paddr); -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); +int xen_get_crashkernel_region(uint64_t *start, uint64_t *end); #endif /* CRASHDUMP_H */ diff --git a/kexec/kexec-xen.c b/kexec/kexec-xen.c new file mode 100644 index 0000000..77f65c0 --- /dev/null +++ b/kexec/kexec-xen.c @@ -0,0 +1,139 @@ +#define _GNU_SOURCE +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <elf.h> +#include "kexec.h" +#include "kexec-syscall.h" +#include "crashdump.h" + +#include "config.h" + +#ifdef HAVE_LIBXENCTRL +#include <xenctrl.h> + +#include "crashdump.h" + +int xen_kexec_load(struct kexec_info *info) +{ + uint32_t nr_segments = info->nr_segments; + struct kexec_segment *segments = info->segment; + xc_interface *xch; + xc_hypercall_buffer_array_t *array = NULL; + uint8_t type; + uint8_t arch; + xen_kexec_segment_t *xen_segs; + int s; + int ret = -1; + + xch = xc_interface_open(NULL, NULL, 0); + if (!xch) + return -1; + + xen_segs = calloc(nr_segments + 1, sizeof(*xen_segs)); + if (!xen_segs) + goto out; + + array = xc_hypercall_buffer_array_create(xch, nr_segments); + if (array == NULL) + goto out; + + for (s = 0; s < nr_segments; s++) { + DECLARE_HYPERCALL_BUFFER(void, seg_buf); + + seg_buf = xc_hypercall_buffer_array_alloc(xch, array, s, + seg_buf, segments[s].bufsz); + if (seg_buf == NULL) + goto out; + memcpy(seg_buf, segments[s].buf, segments[s].bufsz); + + set_xen_guest_handle(xen_segs[s].buf.h, seg_buf); + xen_segs[s].buf_size = segments[s].bufsz; + xen_segs[s].dest_maddr = (uint64_t)segments[s].mem; + xen_segs[s].dest_size = segments[s].memsz; + } + + /* + * Ensure 0 - 1 MiB is mapped and accessible by the image. + * + * This allows access to the VGA memory and the region + * purgatory copies in the crash case. + */ + set_xen_guest_handle(xen_segs[s].buf.h, HYPERCALL_BUFFER_NULL); + xen_segs[s].buf_size = 0; + xen_segs[s].dest_maddr = 0; + xen_segs[s].dest_size = 1 * 1024 * 1024; + nr_segments++; + + type = (info->kexec_flags & KEXEC_ON_CRASH) ? KEXEC_TYPE_CRASH + : KEXEC_TYPE_DEFAULT; + + arch = (info->kexec_flags & KEXEC_ARCH_MASK) >> 16; +#if defined(_i386__) || defined(__x86_64__) + if (!arch) + arch = EM_386; +#endif + + ret = xc_kexec_load(xch, type, arch, (uint64_t)info->entry, + nr_segments, xen_segs); + +out: + xc_hypercall_buffer_array_destroy(xch, array); + free(xen_segs); + xc_interface_close(xch); + + return ret; +} + +int xen_kexec_unload(uint64_t kexec_flags) +{ + xc_interface *xch; + uint8_t type; + int ret; + + xch = xc_interface_open(NULL, NULL, 0); + if (!xch) + return -1; + + type = (kexec_flags & KEXEC_ON_CRASH) ? KEXEC_TYPE_CRASH + : KEXEC_TYPE_DEFAULT; + + ret = xc_kexec_unload(xch, type); + + xc_interface_close(xch); + + return ret; +} + +void xen_kexec_exec(void) +{ + xc_interface *xch; + + xch = xc_interface_open(NULL, NULL, 0); + if (!xch) + return; + + xc_kexec_exec(xch, KEXEC_TYPE_DEFAULT); + + xc_interface_close(xch); +} + +#else /* ! HAVE_LIBXENCTRL */ + +int xen_kexec_load(uint64_t entry, + uint32_t nr_segments, struct kexec_segment *segments, + uint64_t kexec_flags) +{ + return -1; +} + +int xen_kexec_unload(uin64_t kexec_flags); +{ + return -1; +} + +void xen_kexec_exec(void) +{ +} + +#endif diff --git a/kexec/kexec.c b/kexec/kexec.c index 2ce570f..9dc3fa4 100644 --- a/kexec/kexec.c +++ b/kexec/kexec.c @@ -764,8 +764,12 @@ static int my_load(const char *type, int fileind, int argc, char **argv, if (kexec_debug) print_segments(stderr, &info); - result = kexec_load( - info.entry, info.nr_segments, info.segment, info.kexec_flags); + if (xen_present()) + result = xen_kexec_load(&info); + else + result = kexec_load(info.entry, + info.nr_segments, info.segment, + info.kexec_flags); if (result != 0) { /* The load failed, print some debugging information */ fprintf(stderr, "kexec_load failed: %s\n", @@ -789,10 +793,13 @@ static int k_unload (unsigned long kexec_flags) } kexec_flags |= native_arch; - result = kexec_load(NULL, 0, NULL, kexec_flags); + if (xen_present()) + result = xen_kexec_unload(kexec_flags); + else + result = kexec_load(NULL, 0, NULL, kexec_flags); if (result != 0) { /* The unload failed, print some debugging information */ - fprintf(stderr, "kexec_load (0 segments) failed: %s\n", + fprintf(stderr, "kexec unload failed: %s\n", strerror(errno)); } return result; @@ -823,7 +830,10 @@ static int my_shutdown(void) */ static int my_exec(void) { - reboot(LINUX_REBOOT_CMD_KEXEC); + if (xen_present()) + xen_kexec_exec(); + else + reboot(LINUX_REBOOT_CMD_KEXEC); /* I have failed if I make it here */ fprintf(stderr, "kexec failed: %s\n", strerror(errno)); @@ -928,6 +938,10 @@ static int kexec_loaded(void) char *p; char line[3]; + /* No way to tell if an image is loaded under Xen, assume it is. */ + if (xen_present()) + return 1; + fp = fopen("/sys/kernel/kexec_loaded", "r"); if (fp == NULL) return -1; diff --git a/kexec/kexec.h b/kexec/kexec.h index 2904e03..c8be4a5 100644 --- a/kexec/kexec.h +++ b/kexec/kexec.h @@ -289,4 +289,9 @@ const char * proc_iomem(void); char *concat_cmdline(const char *base, const char *append); +int xen_present(void); +int xen_kexec_load(struct kexec_info *info); +int xen_kexec_unload(uint64_t kexec_flags); +void xen_kexec_exec(void); + #endif /* KEXEC_H */ -- 1.7.2.5
For what it is worth. Reviewed-by: Don Slutz <dslutz@verizon.com> -Don Slutz On 11/06/13 09:55, David Vrabel wrote:> From: David Vrabel <david.vrabel@citrix.com> > > libxc from Xen 4.4 added xc_kexec_load() which will be required to > load images into Xen in the future. > > Remove all the #ifdef''ery for older versions of libxc. > > Signed-off-by: David Vrabel <david.vrabel@citrix.com> > Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > --- > configure.ac | 5 +- > kexec/arch/i386/crashdump-x86.c | 110 ------------------------------------ > kexec/arch/i386/kexec-x86-common.c | 103 --------------------------------- > kexec/crashdump-xen.c | 12 ---- > 4 files changed, 1 insertions(+), 229 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 7b61dbf..50b706a 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -161,11 +161,8 @@ 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_CHECK_LIB(xenctrl, xc_kexec_load, , > AC_MSG_NOTICE([Xen support disabled]))) > - if test "$ac_cv_lib_xenctrl_xc_version" = yes ; then > - AC_CHECK_FUNCS(xc_get_machine_memory_map) > - fi > fi > > dnl ---Sanity checks > diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c > index e44fceb..7aa5a12 100644 > --- a/kexec/arch/i386/crashdump-x86.c > +++ b/kexec/arch/i386/crashdump-x86.c > @@ -43,14 +43,7 @@ > #include "crashdump-x86.h" > > #ifdef HAVE_LIBXENCTRL > -#ifdef HAVE_XC_GET_MACHINE_MEMORY_MAP > #include <xenctrl.h> > -#else > -#define __XEN_TOOLS__ 1 > -#include <xen/xen.h> > -#include <xen/memory.h> > -#include <xen/sys/privcmd.h> > -#endif /* HAVE_XC_GET_MACHINE_MEMORY_MAP */ > #endif /* HAVE_LIBXENCTRL */ > > #include <x86/x86-linux.h> > @@ -300,34 +293,20 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges, > } > > #ifdef HAVE_LIBXENCTRL > -#ifdef HAVE_XC_GET_MACHINE_MEMORY_MAP > static int get_crash_memory_ranges_xen(struct memory_range **range, > int *ranges, unsigned long lowmem_limit) > { > int j, rc, ret = -1; > struct e820entry e820entries[CRASH_MAX_MEMORY_RANGES]; > unsigned int i; > -#ifdef XENCTRL_HAS_XC_INTERFACE > xc_interface *xc; > -#else > - int xc; > -#endif > > -#ifdef XENCTRL_HAS_XC_INTERFACE > xc = xc_interface_open(NULL, NULL, 0); > > if (!xc) { > fprintf(stderr, "%s: Failed to open Xen control interface\n", __func__); > goto err; > } > -#else > - xc = xc_interface_open(); > - > - if (xc == -1) { > - fprintf(stderr, "%s: Failed to open Xen control interface\n", __func__); > - goto err; > - } > -#endif > > rc = xc_get_machine_memory_map(xc, e820entries, CRASH_MAX_MEMORY_RANGES); > > @@ -364,95 +343,6 @@ err: > static int get_crash_memory_ranges_xen(struct memory_range **range, > int *ranges, unsigned long lowmem_limit) > { > - int fd, j, rc, ret = -1; > - privcmd_hypercall_t hypercall; > - struct e820entry *e820entries = NULL; > - struct xen_memory_map *xen_memory_map = NULL; > - unsigned int i; > - > - fd = open("/proc/xen/privcmd", O_RDWR); > - > - if (fd == -1) { > - fprintf(stderr, "%s: open(/proc/xen/privcmd): %m\n", __func__); > - goto err; > - } > - > - rc = posix_memalign((void **)&e820entries, getpagesize(), > - sizeof(struct e820entry) * CRASH_MAX_MEMORY_RANGES); > - > - if (rc) { > - fprintf(stderr, "%s: posix_memalign(e820entries): %s\n", __func__, strerror(rc)); > - e820entries = NULL; > - goto err; > - } > - > - rc = posix_memalign((void **)&xen_memory_map, getpagesize(), > - sizeof(struct xen_memory_map)); > - > - if (rc) { > - fprintf(stderr, "%s: posix_memalign(xen_memory_map): %s\n", __func__, strerror(rc)); > - xen_memory_map = NULL; > - goto err; > - } > - > - if (mlock(e820entries, sizeof(struct e820entry) * CRASH_MAX_MEMORY_RANGES) == -1) { > - fprintf(stderr, "%s: mlock(e820entries): %m\n", __func__); > - goto err; > - } > - > - if (mlock(xen_memory_map, sizeof(struct xen_memory_map)) == -1) { > - fprintf(stderr, "%s: mlock(xen_memory_map): %m\n", __func__); > - goto err; > - } > - > - xen_memory_map->nr_entries = CRASH_MAX_MEMORY_RANGES; > - set_xen_guest_handle(xen_memory_map->buffer, e820entries); > - > - hypercall.op = __HYPERVISOR_memory_op; > - hypercall.arg[0] = XENMEM_machine_memory_map; > - hypercall.arg[1] = (__u64)xen_memory_map; > - > - rc = ioctl(fd, IOCTL_PRIVCMD_HYPERCALL, &hypercall); > - > - if (rc == -1) { > - fprintf(stderr, "%s: ioctl(IOCTL_PRIVCMD_HYPERCALL): %m\n", __func__); > - goto err; > - } > - > - for (i = 0, j = 0; i < xen_memory_map->nr_entries && > - j < CRASH_MAX_MEMORY_RANGES; ++i, ++j) { > - crash_memory_range[j].start = e820entries[i].addr; > - crash_memory_range[j].end = e820entries[i].addr + e820entries[i].size - 1; > - crash_memory_range[j].type = xen_e820_to_kexec_type(e820entries[i].type); > - segregate_lowmem_region(&j, lowmem_limit); > - } > - > - *range = crash_memory_range; > - *ranges = j; > - > - qsort(*range, *ranges, sizeof(struct memory_range), compare_ranges); > - > - for (i = 0; i < crash_reserved_mem_nr; i++) > - if (exclude_region(ranges, crash_reserved_mem[i].start, > - crash_reserved_mem[i].end) < 0) > - goto err; > - > - ret = 0; > - > -err: > - munlock(xen_memory_map, sizeof(struct xen_memory_map)); > - munlock(e820entries, sizeof(struct e820entry) * CRASH_MAX_MEMORY_RANGES); > - free(xen_memory_map); > - free(e820entries); > - close(fd); > - > - return ret; > -} > -#endif /* HAVE_XC_GET_MACHINE_MEMORY_MAP */ > -#else > -static int get_crash_memory_ranges_xen(struct memory_range **range, > - int *ranges, unsigned long lowmem_limit) > -{ > return 0; > } > #endif /* HAVE_LIBXENCTRL */ > diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c > index ed6c950..bf58f53 100644 > --- a/kexec/arch/i386/kexec-x86-common.c > +++ b/kexec/arch/i386/kexec-x86-common.c > @@ -40,15 +40,7 @@ > #include "kexec-x86.h" > > #ifdef HAVE_LIBXENCTRL > -#ifdef HAVE_XC_GET_MACHINE_MEMORY_MAP > #include <xenctrl.h> > -#else > -#define __XEN_TOOLS__ 1 > -#include <x86/x86-linux.h> > -#include <xen/xen.h> > -#include <xen/memory.h> > -#include <xen/sys/privcmd.h> > -#endif /* HAVE_XC_GET_MACHINE_MEMORY_MAP */ > #endif /* HAVE_LIBXENCTRL */ > > static struct memory_range memory_range[MAX_MEMORY_RANGES]; > @@ -173,33 +165,19 @@ unsigned xen_e820_to_kexec_type(uint32_t type) > * > * @return 0 on success, any other value on failure. > */ > -#ifdef HAVE_XC_GET_MACHINE_MEMORY_MAP > static int get_memory_ranges_xen(struct memory_range **range, int *ranges) > { > int rc, ret = -1; > struct e820entry e820entries[MAX_MEMORY_RANGES]; > unsigned int i; > -#ifdef XENCTRL_HAS_XC_INTERFACE > xc_interface *xc; > -#else > - int xc; > -#endif > > -#ifdef XENCTRL_HAS_XC_INTERFACE > xc = xc_interface_open(NULL, NULL, 0); > > if (!xc) { > fprintf(stderr, "%s: Failed to open Xen control interface\n", __func__); > goto err; > } > -#else > - xc = xc_interface_open(); > - > - if (xc == -1) { > - fprintf(stderr, "%s: Failed to open Xen control interface\n", __func__); > - goto err; > - } > -#endif > > rc = xc_get_machine_memory_map(xc, e820entries, MAX_MEMORY_RANGES); > > @@ -229,87 +207,6 @@ err: > #else > static int get_memory_ranges_xen(struct memory_range **range, int *ranges) > { > - int fd, rc, ret = -1; > - privcmd_hypercall_t hypercall; > - struct e820entry *e820entries = NULL; > - struct xen_memory_map *xen_memory_map = NULL; > - unsigned int i; > - > - fd = open("/proc/xen/privcmd", O_RDWR); > - > - if (fd == -1) { > - fprintf(stderr, "%s: open(/proc/xen/privcmd): %m\n", __func__); > - goto err; > - } > - > - rc = posix_memalign((void **)&e820entries, sysconf(_SC_PAGESIZE), > - sizeof(struct e820entry) * MAX_MEMORY_RANGES); > - > - if (rc) { > - fprintf(stderr, "%s: posix_memalign(e820entries): %s\n", __func__, strerror(rc)); > - e820entries = NULL; > - goto err; > - } > - > - rc = posix_memalign((void **)&xen_memory_map, sysconf(_SC_PAGESIZE), > - sizeof(struct xen_memory_map)); > - > - if (rc) { > - fprintf(stderr, "%s: posix_memalign(xen_memory_map): %s\n", __func__, strerror(rc)); > - xen_memory_map = NULL; > - goto err; > - } > - > - if (mlock(e820entries, sizeof(struct e820entry) * MAX_MEMORY_RANGES) == -1) { > - fprintf(stderr, "%s: mlock(e820entries): %m\n", __func__); > - goto err; > - } > - > - if (mlock(xen_memory_map, sizeof(struct xen_memory_map)) == -1) { > - fprintf(stderr, "%s: mlock(xen_memory_map): %m\n", __func__); > - goto err; > - } > - > - xen_memory_map->nr_entries = MAX_MEMORY_RANGES; > - set_xen_guest_handle(xen_memory_map->buffer, e820entries); > - > - hypercall.op = __HYPERVISOR_memory_op; > - hypercall.arg[0] = XENMEM_machine_memory_map; > - hypercall.arg[1] = (__u64)xen_memory_map; > - > - rc = ioctl(fd, IOCTL_PRIVCMD_HYPERCALL, &hypercall); > - > - if (rc == -1) { > - fprintf(stderr, "%s: ioctl(IOCTL_PRIVCMD_HYPERCALL): %m\n", __func__); > - goto err; > - } > - > - for (i = 0; i < xen_memory_map->nr_entries; ++i) { > - memory_range[i].start = e820entries[i].addr; > - memory_range[i].end = e820entries[i].addr + e820entries[i].size; > - memory_range[i].type = xen_e820_to_kexec_type(e820entries[i].type); > - } > - > - qsort(memory_range, xen_memory_map->nr_entries, sizeof(struct memory_range), compare_ranges); > - > - *range = memory_range; > - *ranges = xen_memory_map->nr_entries; > - > - ret = 0; > - > -err: > - munlock(xen_memory_map, sizeof(struct xen_memory_map)); > - munlock(e820entries, sizeof(struct e820entry) * MAX_MEMORY_RANGES); > - free(xen_memory_map); > - free(e820entries); > - close(fd); > - > - return ret; > -} > -#endif /* HAVE_XC_GET_MACHINE_MEMORY_MAP */ > -#else > -static int get_memory_ranges_xen(struct memory_range **range, int *ranges) > -{ > return 0; > } > #endif /* HAVE_LIBXENCTRL */ > diff --git a/kexec/crashdump-xen.c b/kexec/crashdump-xen.c > index d8bd0f4..ff4706c 100644 > --- a/kexec/crashdump-xen.c > +++ b/kexec/crashdump-xen.c > @@ -131,30 +131,18 @@ unsigned long xen_architecture(struct crash_elf_info *elf_info) > #ifdef HAVE_LIBXENCTRL > int rc; > xen_capabilities_info_t capabilities; > -#ifdef XENCTRL_HAS_XC_INTERFACE > xc_interface *xc; > -#else > - int xc; > -#endif > > if (!xen_present()) > goto out; > > memset(capabilities, ''0'', XEN_CAPABILITIES_INFO_LEN); > > -#ifdef XENCTRL_HAS_XC_INTERFACE > xc = xc_interface_open(NULL, NULL, 0); > if ( !xc ) { > fprintf(stderr, "failed to open xen control interface.\n"); > goto out; > } > -#else > - xc = xc_interface_open(); > - if ( xc == -1 ) { > - fprintf(stderr, "failed to open xen control interface.\n"); > - goto out; > - } > -#endif > > rc = xc_version(xc, XENVER_capabilities, &capabilities[0]); > if ( rc == -1 ) {
Don Slutz
2013-Nov-07 20:36 UTC
Re: [PATCH 2/4] kexec/xen: use libxc to get location of crash notes
For what it is worth. Reviewed-by: Don Slutz <dslutz@verizon.com> -Don Slutz On 11/06/13 09:55, David Vrabel wrote:> From: David Vrabel <david.vrabel@citrix.com> > > Use xc_kexec_get_range(KEXEC_RANGE_MA_CPU) instead of parsing > /proc/iomem (which is only populated by non-upstream ("classic") Xen > kernels). > > Signed-off-by: David Vrabel <david.vrabel@citrix.com> > Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > --- > kexec/crashdump-xen.c | 67 +++++++++++++++++++++++++++++------------------- > 1 files changed, 40 insertions(+), 27 deletions(-) > > diff --git a/kexec/crashdump-xen.c b/kexec/crashdump-xen.c > index ff4706c..8185423 100644 > --- a/kexec/crashdump-xen.c > +++ b/kexec/crashdump-xen.c > @@ -163,42 +163,55 @@ unsigned long xen_architecture(struct crash_elf_info *elf_info) > return machine; > } > > -static int xen_crash_note_callback(void *UNUSED(data), int nr, > - char *UNUSED(str), > - unsigned long base, > - unsigned long length) > -{ > - struct crash_note_info *note = xen_phys_notes + nr; > - > - note->base = base; > - note->length = length; > - > - return 0; > -} > - > +#ifdef HAVE_LIBXENCTRL > int xen_get_nr_phys_cpus(void) > { > - char *match = "Crash note\n"; > - int cpus, n; > + xc_interface *xc; > + int max_cpus; > + int cpu = -1; > > if (xen_phys_cpus) > return xen_phys_cpus; > > - if ((cpus = kexec_iomem_for_each_line(match, NULL, NULL))) { > - n = sizeof(struct crash_note_info) * cpus; > - xen_phys_notes = malloc(n); > - if (!xen_phys_notes) { > - fprintf(stderr, "failed to allocate xen_phys_notes.\n"); > - return -1; > - } > - memset(xen_phys_notes, 0, n); > - kexec_iomem_for_each_line(match, > - xen_crash_note_callback, NULL); > - xen_phys_cpus = cpus; > + xc = xc_interface_open(NULL, NULL, 0); > + if (!xc) { > + fprintf(stderr, "failed to open xen control interface.\n"); > + return -1; > } > > - return cpus; > + max_cpus = xc_get_max_cpus(xc); > + if (max_cpus <= 0) > + goto out; > + > + xen_phys_notes = calloc(max_cpus, sizeof(*xen_phys_notes)); > + if (xen_phys_notes == NULL) > + goto out; > + > + for (cpu = 0; cpu < max_cpus; cpu++) { > + uint64_t size, start; > + int ret; > + > + ret = xc_kexec_get_range(xc, KEXEC_RANGE_MA_CPU, cpu, &size, &start); > + if (ret < 0) > + break; > + > + xen_phys_notes[cpu].base = start; > + xen_phys_notes[cpu].length = size; > + } > + > + xen_phys_cpus = cpu; > + > +out: > + xc_interface_close(xc); > + return cpu; > } > +#else > +int xen_get_nr_phys_cpus(void) > +{ > + return -1; > +} > +#endif > + > > int xen_get_note(int cpu, uint64_t *addr, uint64_t *len) > {
Don Slutz
2013-Nov-07 20:36 UTC
Re: [PATCH 4/4] kexec/xen: directly load images images into Xen
For what it is worth. Reviewed-by: Don Slutz <dslutz@verizon.com> -Don Slutz On 11/06/13 09:55, David Vrabel wrote:> From: David Vrabel <david.vrabel@citrix.com> > > Xen 4.4 has an improvided kexec hypercall ABI that allows images to be > loaded and executed without any kernel involvement. Use the API > provided by libxc to load images when running in a Xen guest. > > Support for loading images via the kexec_load syscall in non-upstream > ("classic") Xen kernels is no longer supported. > > Signed-off-by: David Vrabel <david.vrabel@citrix.com> > Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > --- > kexec/Makefile | 1 + > kexec/arch/i386/crashdump-x86.c | 20 +++++- > kexec/crashdump-xen.c | 34 ++++++++++ > kexec/crashdump.h | 3 +- > kexec/kexec-xen.c | 139 +++++++++++++++++++++++++++++++++++++++ > kexec/kexec.c | 24 +++++-- > kexec/kexec.h | 5 ++ > 7 files changed, 218 insertions(+), 8 deletions(-) > create mode 100644 kexec/kexec-xen.c > > diff --git a/kexec/Makefile b/kexec/Makefile > index 8a6138d..dc9dab1 100644 > --- a/kexec/Makefile > +++ b/kexec/Makefile > @@ -25,6 +25,7 @@ KEXEC_SRCS_base += kexec/phys_arch.c > KEXEC_SRCS_base += kexec/kernel_version.c > KEXEC_SRCS_base += kexec/lzma.c > KEXEC_SRCS_base += kexec/zlib.c > +KEXEC_SRCS_base += kexec/kexec-xen.c > > KEXEC_GENERATED_SRCS += $(PURGATORY_HEX_C) > > diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c > index 7aa5a12..85f3a87 100644 > --- a/kexec/arch/i386/crashdump-x86.c > +++ b/kexec/arch/i386/crashdump-x86.c > @@ -990,8 +990,24 @@ static int crashkernel_mem_callback(void *UNUSED(data), int nr, > > int is_crashkernel_mem_reserved(void) > { > - crash_reserved_mem_nr = kexec_iomem_for_each_line("Crash kernel\n", > - crashkernel_mem_callback, NULL); > + int ret; > + > + if (xen_present()) { > + uint64_t start, end; > + > + ret = xen_get_crashkernel_region(&start, &end); > + if (ret < 0) > + return 0; > + > + crash_reserved_mem[0].start = start; > + crash_reserved_mem[0].end = end; > + crash_reserved_mem[0].type = RANGE_RAM; > + crash_reserved_mem_nr = 1; > + } else { > + ret = kexec_iomem_for_each_line("Crash kernel\n", > + crashkernel_mem_callback, NULL); > + crash_reserved_mem_nr = ret; > + } > > return !!crash_reserved_mem_nr; > } > diff --git a/kexec/crashdump-xen.c b/kexec/crashdump-xen.c > index 79b68e0..60594f6 100644 > --- a/kexec/crashdump-xen.c > +++ b/kexec/crashdump-xen.c > @@ -252,3 +252,37 @@ int xen_get_note(int cpu, uint64_t *addr, uint64_t *len) > > return 0; > } > + > +#ifdef HAVE_LIBXENCTRL > +int xen_get_crashkernel_region(uint64_t *start, uint64_t *end) > +{ > + uint64_t size; > + xc_interface *xc; > + int rc = -1; > + > + xc = xc_interface_open(NULL, NULL, 0); > + if (!xc) { > + fprintf(stderr, "failed to open xen control interface.\n"); > + goto out; > + } > + > + rc = xc_kexec_get_range(xc, KEXEC_RANGE_MA_CRASH, 0, &size, start); > + if (rc < 0) { > + fprintf(stderr, "failed to get crash region from hypervisor.\n"); > + goto out_close; > + } > + > + *end = *start + size - 1; > + > +out_close: > + xc_interface_close(xc); > + > +out: > + return rc; > +} > +#else > +int xen_get_crashkernel_region(uint64_t *start, uint64_t *end) > +{ > + return -1; > +} > +#endif > diff --git a/kexec/crashdump.h b/kexec/crashdump.h > index 0f7c2ea..95f1f0c 100644 > --- a/kexec/crashdump.h > +++ b/kexec/crashdump.h > @@ -1,6 +1,7 @@ > #ifndef CRASHDUMP_H > #define CRASHDUMP_H > > +int get_crashkernel_region(uint64_t *start, uint64_t *end); > extern int get_crash_notes_per_cpu(int cpu, uint64_t *addr, uint64_t *len); > extern int get_kernel_vmcoreinfo(uint64_t *addr, uint64_t *len); > extern int get_xen_vmcoreinfo(uint64_t *addr, uint64_t *len); > @@ -56,9 +57,9 @@ unsigned long crash_architecture(struct crash_elf_info *elf_info); > unsigned long phys_to_virt(struct crash_elf_info *elf_info, > unsigned long paddr); > > -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); > +int xen_get_crashkernel_region(uint64_t *start, uint64_t *end); > > #endif /* CRASHDUMP_H */ > diff --git a/kexec/kexec-xen.c b/kexec/kexec-xen.c > new file mode 100644 > index 0000000..77f65c0 > --- /dev/null > +++ b/kexec/kexec-xen.c > @@ -0,0 +1,139 @@ > +#define _GNU_SOURCE > +#include <stdio.h> > +#include <string.h> > +#include <stdlib.h> > +#include <elf.h> > +#include "kexec.h" > +#include "kexec-syscall.h" > +#include "crashdump.h" > + > +#include "config.h" > + > +#ifdef HAVE_LIBXENCTRL > +#include <xenctrl.h> > + > +#include "crashdump.h" > + > +int xen_kexec_load(struct kexec_info *info) > +{ > + uint32_t nr_segments = info->nr_segments; > + struct kexec_segment *segments = info->segment; > + xc_interface *xch; > + xc_hypercall_buffer_array_t *array = NULL; > + uint8_t type; > + uint8_t arch; > + xen_kexec_segment_t *xen_segs; > + int s; > + int ret = -1; > + > + xch = xc_interface_open(NULL, NULL, 0); > + if (!xch) > + return -1; > + > + xen_segs = calloc(nr_segments + 1, sizeof(*xen_segs)); > + if (!xen_segs) > + goto out; > + > + array = xc_hypercall_buffer_array_create(xch, nr_segments); > + if (array == NULL) > + goto out; > + > + for (s = 0; s < nr_segments; s++) { > + DECLARE_HYPERCALL_BUFFER(void, seg_buf); > + > + seg_buf = xc_hypercall_buffer_array_alloc(xch, array, s, > + seg_buf, segments[s].bufsz); > + if (seg_buf == NULL) > + goto out; > + memcpy(seg_buf, segments[s].buf, segments[s].bufsz); > + > + set_xen_guest_handle(xen_segs[s].buf.h, seg_buf); > + xen_segs[s].buf_size = segments[s].bufsz; > + xen_segs[s].dest_maddr = (uint64_t)segments[s].mem; > + xen_segs[s].dest_size = segments[s].memsz; > + } > + > + /* > + * Ensure 0 - 1 MiB is mapped and accessible by the image. > + * > + * This allows access to the VGA memory and the region > + * purgatory copies in the crash case. > + */ > + set_xen_guest_handle(xen_segs[s].buf.h, HYPERCALL_BUFFER_NULL); > + xen_segs[s].buf_size = 0; > + xen_segs[s].dest_maddr = 0; > + xen_segs[s].dest_size = 1 * 1024 * 1024; > + nr_segments++; > + > + type = (info->kexec_flags & KEXEC_ON_CRASH) ? KEXEC_TYPE_CRASH > + : KEXEC_TYPE_DEFAULT; > + > + arch = (info->kexec_flags & KEXEC_ARCH_MASK) >> 16; > +#if defined(_i386__) || defined(__x86_64__) > + if (!arch) > + arch = EM_386; > +#endif > + > + ret = xc_kexec_load(xch, type, arch, (uint64_t)info->entry, > + nr_segments, xen_segs); > + > +out: > + xc_hypercall_buffer_array_destroy(xch, array); > + free(xen_segs); > + xc_interface_close(xch); > + > + return ret; > +} > + > +int xen_kexec_unload(uint64_t kexec_flags) > +{ > + xc_interface *xch; > + uint8_t type; > + int ret; > + > + xch = xc_interface_open(NULL, NULL, 0); > + if (!xch) > + return -1; > + > + type = (kexec_flags & KEXEC_ON_CRASH) ? KEXEC_TYPE_CRASH > + : KEXEC_TYPE_DEFAULT; > + > + ret = xc_kexec_unload(xch, type); > + > + xc_interface_close(xch); > + > + return ret; > +} > + > +void xen_kexec_exec(void) > +{ > + xc_interface *xch; > + > + xch = xc_interface_open(NULL, NULL, 0); > + if (!xch) > + return; > + > + xc_kexec_exec(xch, KEXEC_TYPE_DEFAULT); > + > + xc_interface_close(xch); > +} > + > +#else /* ! HAVE_LIBXENCTRL */ > + > +int xen_kexec_load(uint64_t entry, > + uint32_t nr_segments, struct kexec_segment *segments, > + uint64_t kexec_flags) > +{ > + return -1; > +} > + > +int xen_kexec_unload(uin64_t kexec_flags); > +{ > + return -1; > +} > + > +void xen_kexec_exec(void) > +{ > +} > + > +#endif > diff --git a/kexec/kexec.c b/kexec/kexec.c > index 2ce570f..9dc3fa4 100644 > --- a/kexec/kexec.c > +++ b/kexec/kexec.c > @@ -764,8 +764,12 @@ static int my_load(const char *type, int fileind, int argc, char **argv, > if (kexec_debug) > print_segments(stderr, &info); > > - result = kexec_load( > - info.entry, info.nr_segments, info.segment, info.kexec_flags); > + if (xen_present()) > + result = xen_kexec_load(&info); > + else > + result = kexec_load(info.entry, > + info.nr_segments, info.segment, > + info.kexec_flags); > if (result != 0) { > /* The load failed, print some debugging information */ > fprintf(stderr, "kexec_load failed: %s\n", > @@ -789,10 +793,13 @@ static int k_unload (unsigned long kexec_flags) > } > kexec_flags |= native_arch; > > - result = kexec_load(NULL, 0, NULL, kexec_flags); > + if (xen_present()) > + result = xen_kexec_unload(kexec_flags); > + else > + result = kexec_load(NULL, 0, NULL, kexec_flags); > if (result != 0) { > /* The unload failed, print some debugging information */ > - fprintf(stderr, "kexec_load (0 segments) failed: %s\n", > + fprintf(stderr, "kexec unload failed: %s\n", > strerror(errno)); > } > return result; > @@ -823,7 +830,10 @@ static int my_shutdown(void) > */ > static int my_exec(void) > { > - reboot(LINUX_REBOOT_CMD_KEXEC); > + if (xen_present()) > + xen_kexec_exec(); > + else > + reboot(LINUX_REBOOT_CMD_KEXEC); > /* I have failed if I make it here */ > fprintf(stderr, "kexec failed: %s\n", > strerror(errno)); > @@ -928,6 +938,10 @@ static int kexec_loaded(void) > char *p; > char line[3]; > > + /* No way to tell if an image is loaded under Xen, assume it is. */ > + if (xen_present()) > + return 1; > + > fp = fopen("/sys/kernel/kexec_loaded", "r"); > if (fp == NULL) > return -1; > diff --git a/kexec/kexec.h b/kexec/kexec.h > index 2904e03..c8be4a5 100644 > --- a/kexec/kexec.h > +++ b/kexec/kexec.h > @@ -289,4 +289,9 @@ const char * proc_iomem(void); > > char *concat_cmdline(const char *base, const char *append); > > +int xen_present(void); > +int xen_kexec_load(struct kexec_info *info); > +int xen_kexec_unload(uint64_t kexec_flags); > +void xen_kexec_exec(void); > + > #endif /* KEXEC_H */
On Wed, Nov 06, 2013 at 02:55:18PM +0000, David Vrabel wrote:> The series adds support for the new hypercall ABI which should be > provided by Xen 4.4. Images are loaded into Xen directly with no > kernel involvement. > > Please do not apply until the hypervisor side patches are applied to > Xen. > > Patch 1 makes libxc 4.4 mandatory for Xen support. > > Patch 2-3 remove uses of /proc/iomem in favour of libxc. > > Patch 4 adds the support for loading, unloading, and exec''ing an image > in Xen. > > This series explicitly drops support for older version of libxc/Xen as > supporting kexec on these hypervisors requires kernel support that > will never be available upstream. > > Changes in v7: > - extend extra segment to 0-1 MiB so the VGA memory is accesible by > the image. > > Changes in v6: > - Close libxc handle a few error paths. > > Changes in v5: > - Dropped the purgatory patch. > > Changes in v4: > - KEXEC_ARCH_DEFAULT => EM_386 > - add segment in the crash case for the backup src. > > Changes in v3 (not posted): > - Rebased > > Changes in v2: > - Patch from Don Sultz: use libxc for vmcoreinfo. > - Use xc_get_max_cpus() to get number of PCPUs. > - Enable unload and exec of images.For whole Xen kexec/kdump kexec-tools series: Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> Tested-by: Daniel Kiper <daniel.kiper@oracle.com> Daniel
On 11/09/13 14:21, Daniel Kiper wrote:> On Wed, Nov 06, 2013 at 02:55:18PM +0000, David Vrabel wrote: >> The series adds support for the new hypercall ABI which should be >> provided by Xen 4.4. Images are loaded into Xen directly with no >> kernel involvement. >> >> Please do not apply until the hypervisor side patches are applied to >> Xen. >> >> Patch 1 makes libxc 4.4 mandatory for Xen support. >> >> Patch 2-3 remove uses of /proc/iomem in favour of libxc. >> >> Patch 4 adds the support for loading, unloading, and exec''ing an image >> in Xen. >> >> This series explicitly drops support for older version of libxc/Xen as >> supporting kexec on these hypervisors requires kernel support that >> will never be available upstream. >> >> Changes in v7: >> - extend extra segment to 0-1 MiB so the VGA memory is accesible by >> the image. >> >> Changes in v6: >> - Close libxc handle a few error paths. >> >> Changes in v5: >> - Dropped the purgatory patch. >> >> Changes in v4: >> - KEXEC_ARCH_DEFAULT => EM_386 >> - add segment in the crash case for the backup src. >> >> Changes in v3 (not posted): >> - Rebased >> >> Changes in v2: >> - Patch from Don Sultz: use libxc for vmcoreinfo. >> - Use xc_get_max_cpus() to get number of PCPUs. >> - Enable unload and exec of images. > For whole Xen kexec/kdump kexec-tools series: > > Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > Tested-by: Daniel Kiper <daniel.kiper@oracle.com> > > DanielAlso Tested-by: Don Slutz <dslutz@verizon.com> -Don Slutz> _______________________________________________ > kexec mailing list > kexec@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/kexec
On 06/11/13 14:55, David Vrabel wrote:> The series adds support for the new hypercall ABI which should be > provided by Xen 4.4. Images are loaded into Xen directly with no > kernel involvement. > > Please do not apply until the hypervisor side patches are applied to > Xen.The hypervisor patches are now in Xen unstable and will be available in the upcoming Xen 4.4 release. Please apply this corresponding kexec-tools series. When making a new release with these patches in I would recommend adding a release note saying Xen 4.4 is now required to kexec under Xen. Thanks. David> Patch 1 makes libxc 4.4 mandatory for Xen support. > > Patch 2-3 remove uses of /proc/iomem in favour of libxc. > > Patch 4 adds the support for loading, unloading, and exec''ing an image > in Xen. > > This series explicitly drops support for older version of libxc/Xen as > supporting kexec on these hypervisors requires kernel support that > will never be available upstream. > > Changes in v7: > - extend extra segment to 0-1 MiB so the VGA memory is accesible by > the image. > > Changes in v6: > - Close libxc handle a few error paths. > > Changes in v5: > - Dropped the purgatory patch. > > Changes in v4: > - KEXEC_ARCH_DEFAULT => EM_386 > - add segment in the crash case for the backup src. > > Changes in v3 (not posted): > - Rebased > > Changes in v2: > - Patch from Don Sultz: use libxc for vmcoreinfo. > - Use xc_get_max_cpus() to get number of PCPUs. > - Enable unload and exec of images. > > David > >
On Wed, Nov 13, 2013 at 10:27:53AM +0000, David Vrabel wrote:> On 06/11/13 14:55, David Vrabel wrote: > > The series adds support for the new hypercall ABI which should be > > provided by Xen 4.4. Images are loaded into Xen directly with no > > kernel involvement. > > > > Please do not apply until the hypervisor side patches are applied to > > Xen. > > The hypervisor patches are now in Xen unstable and will be available in > the upcoming Xen 4.4 release. > > Please apply this corresponding kexec-tools series. > > When making a new release with these patches in I would recommend adding > a release note saying Xen 4.4 is now required to kexec under Xen.Thanks, applied.
Simon Horman
2013-Nov-19 01:20 UTC
Re: [PATCH 4/4] kexec/xen: directly load images images into Xen
On Wed, Nov 06, 2013 at 02:55:22PM +0000, David Vrabel wrote:> From: David Vrabel <david.vrabel@citrix.com> > > Xen 4.4 has an improvided kexec hypercall ABI that allows images to be > loaded and executed without any kernel involvement. Use the API > provided by libxc to load images when running in a Xen guest. > > Support for loading images via the kexec_load syscall in non-upstream > ("classic") Xen kernels is no longer supported. > > Signed-off-by: David Vrabel <david.vrabel@citrix.com> > Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > --- > kexec/Makefile | 1 + > kexec/arch/i386/crashdump-x86.c | 20 +++++- > kexec/crashdump-xen.c | 34 ++++++++++ > kexec/crashdump.h | 3 +- > kexec/kexec-xen.c | 139 +++++++++++++++++++++++++++++++++++++++ > kexec/kexec.c | 24 +++++-- > kexec/kexec.h | 5 ++ > 7 files changed, 218 insertions(+), 8 deletions(-) > create mode 100644 kexec/kexec-xen.c >[snip]> diff --git a/kexec/kexec-xen.c b/kexec/kexec-xen.c > new file mode 100644 > index 0000000..77f65c0 > --- /dev/null > +++ b/kexec/kexec-xen.c > @@ -0,0 +1,139 @@ > +#define _GNU_SOURCE > +#include <stdio.h> > +#include <string.h> > +#include <stdlib.h> > +#include <elf.h> > +#include "kexec.h" > +#include "kexec-syscall.h" > +#include "crashdump.h" > + > +#include "config.h" > + > +#ifdef HAVE_LIBXENCTRL > +#include <xenctrl.h> > + > +#include "crashdump.h" > + > +int xen_kexec_load(struct kexec_info *info) > +{ > + uint32_t nr_segments = info->nr_segments; > + struct kexec_segment *segments = info->segment; > + xc_interface *xch; > + xc_hypercall_buffer_array_t *array = NULL; > + uint8_t type; > + uint8_t arch; > + xen_kexec_segment_t *xen_segs; > + int s; > + int ret = -1; > + > + xch = xc_interface_open(NULL, NULL, 0); > + if (!xch) > + return -1; > + > + xen_segs = calloc(nr_segments + 1, sizeof(*xen_segs)); > + if (!xen_segs) > + goto out; > + > + array = xc_hypercall_buffer_array_create(xch, nr_segments); > + if (array == NULL) > + goto out; > + > + for (s = 0; s < nr_segments; s++) { > + DECLARE_HYPERCALL_BUFFER(void, seg_buf); > + > + seg_buf = xc_hypercall_buffer_array_alloc(xch, array, s, > + seg_buf, segments[s].bufsz); > + if (seg_buf == NULL) > + goto out; > + memcpy(seg_buf, segments[s].buf, segments[s].bufsz); > + > + set_xen_guest_handle(xen_segs[s].buf.h, seg_buf); > + xen_segs[s].buf_size = segments[s].bufsz; > + xen_segs[s].dest_maddr = (uint64_t)segments[s].mem; > + xen_segs[s].dest_size = segments[s].memsz; > + } > + > + /* > + * Ensure 0 - 1 MiB is mapped and accessible by the image. > + * > + * This allows access to the VGA memory and the region > + * purgatory copies in the crash case. > + */ > + set_xen_guest_handle(xen_segs[s].buf.h, HYPERCALL_BUFFER_NULL); > + xen_segs[s].buf_size = 0; > + xen_segs[s].dest_maddr = 0; > + xen_segs[s].dest_size = 1 * 1024 * 1024; > + nr_segments++; > + > + type = (info->kexec_flags & KEXEC_ON_CRASH) ? KEXEC_TYPE_CRASH > + : KEXEC_TYPE_DEFAULT; > + > + arch = (info->kexec_flags & KEXEC_ARCH_MASK) >> 16; > +#if defined(_i386__) || defined(__x86_64__) > + if (!arch) > + arch = EM_386; > +#endif > + > + ret = xc_kexec_load(xch, type, arch, (uint64_t)info->entry, > + nr_segments, xen_segs); > + > +out: > + xc_hypercall_buffer_array_destroy(xch, array); > + free(xen_segs); > + xc_interface_close(xch); > + > + return ret; > +} > + > +int xen_kexec_unload(uint64_t kexec_flags) > +{ > + xc_interface *xch; > + uint8_t type; > + int ret; > + > + xch = xc_interface_open(NULL, NULL, 0); > + if (!xch) > + return -1; > + > + type = (kexec_flags & KEXEC_ON_CRASH) ? KEXEC_TYPE_CRASH > + : KEXEC_TYPE_DEFAULT; > + > + ret = xc_kexec_unload(xch, type); > + > + xc_interface_close(xch); > + > + return ret; > +} > + > +void xen_kexec_exec(void) > +{ > + xc_interface *xch; > + > + xch = xc_interface_open(NULL, NULL, 0); > + if (!xch) > + return; > + > + xc_kexec_exec(xch, KEXEC_TYPE_DEFAULT); > + > + xc_interface_close(xch); > +} > + > +#else /* ! HAVE_LIBXENCTRL */ > + > +int xen_kexec_load(uint64_t entry, > + uint32_t nr_segments, struct kexec_segment *segments, > + uint64_t kexec_flags) > +{ > + return -1; > +} > + > +int xen_kexec_unload(uin64_t kexec_flags); > +{ > + return -1; > +} > + > +void xen_kexec_exec(void) > +{ > +} > + > +#endif[snip] I have applied the following follow-up patch to resolves some errors. Let me know if I messed it up. From: Simon Horman <horms@verge.net.au> [PATCH] kexec/xen: Correct some compile errors Correct various problems introduced by 08cf823704b0fa3b ("kexec/xen: directly load images images into Xen"). These all relate to the case here HAVE_LIBXENCTRL is not set. Signed-off-by: Simon Horman <horms@verge.net.au> --- kexec/kexec-xen.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/kexec/kexec-xen.c b/kexec/kexec-xen.c index 77f65c0..e885246 100644 --- a/kexec/kexec-xen.c +++ b/kexec/kexec-xen.c @@ -2,6 +2,7 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <stdlib.h> #include <elf.h> #include "kexec.h" #include "kexec-syscall.h" @@ -120,14 +121,12 @@ void xen_kexec_exec(void) #else /* ! HAVE_LIBXENCTRL */ -int xen_kexec_load(uint64_t entry, - uint32_t nr_segments, struct kexec_segment *segments, - uint64_t kexec_flags) +int xen_kexec_load(struct kexec_info *UNUSED(info)) { return -1; } -int xen_kexec_unload(uin64_t kexec_flags); +int xen_kexec_unload(uint64_t kexec_flags) { return -1; } -- 1.8.4
Daniel Kiper
2013-Nov-19 08:28 UTC
Re: [PATCH 4/4] kexec/xen: directly load images images into Xen
On Tue, Nov 19, 2013 at 10:20:14AM +0900, Simon Horman wrote:> On Wed, Nov 06, 2013 at 02:55:22PM +0000, David Vrabel wrote: > > From: David Vrabel <david.vrabel@citrix.com> > > > > Xen 4.4 has an improvided kexec hypercall ABI that allows images to be > > loaded and executed without any kernel involvement. Use the API > > provided by libxc to load images when running in a Xen guest. > > > > Support for loading images via the kexec_load syscall in non-upstream > > ("classic") Xen kernels is no longer supported. > > > > Signed-off-by: David Vrabel <david.vrabel@citrix.com> > > Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > > --- > > kexec/Makefile | 1 + > > kexec/arch/i386/crashdump-x86.c | 20 +++++- > > kexec/crashdump-xen.c | 34 ++++++++++ > > kexec/crashdump.h | 3 +- > > kexec/kexec-xen.c | 139 +++++++++++++++++++++++++++++++++++++++ > > kexec/kexec.c | 24 +++++-- > > kexec/kexec.h | 5 ++ > > 7 files changed, 218 insertions(+), 8 deletions(-) > > create mode 100644 kexec/kexec-xen.c > >[...]> I have applied the following follow-up patch to resolves some errors. > Let me know if I messed it up. > > From: Simon Horman <horms@verge.net.au> > > [PATCH] kexec/xen: Correct some compile errors > > Correct various problems introduced by > 08cf823704b0fa3b ("kexec/xen: directly load images images into Xen"). > > These all relate to the case here HAVE_LIBXENCTRL is not set. > > Signed-off-by: Simon Horman <horms@verge.net.au> > --- > kexec/kexec-xen.c | 7 +++---- > 1 file changed, 3 insertions(+), 4 deletions(-) > > diff --git a/kexec/kexec-xen.c b/kexec/kexec-xen.c > index 77f65c0..e885246 100644 > --- a/kexec/kexec-xen.c > +++ b/kexec/kexec-xen.c > @@ -2,6 +2,7 @@ > #include <stdio.h> > #include <string.h> > #include <stdlib.h> > +#include <stdlib.h>Thanks for fixes but why are you including stdlib.h twice? Daniel
Simon Horman
2013-Nov-19 09:19 UTC
Re: [PATCH 4/4] kexec/xen: directly load images images into Xen
On Tue, Nov 19, 2013 at 09:28:27AM +0100, Daniel Kiper wrote:> On Tue, Nov 19, 2013 at 10:20:14AM +0900, Simon Horman wrote: > > On Wed, Nov 06, 2013 at 02:55:22PM +0000, David Vrabel wrote: > > > From: David Vrabel <david.vrabel@citrix.com> > > > > > > Xen 4.4 has an improvided kexec hypercall ABI that allows images to be > > > loaded and executed without any kernel involvement. Use the API > > > provided by libxc to load images when running in a Xen guest. > > > > > > Support for loading images via the kexec_load syscall in non-upstream > > > ("classic") Xen kernels is no longer supported. > > > > > > Signed-off-by: David Vrabel <david.vrabel@citrix.com> > > > Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > > > --- > > > kexec/Makefile | 1 + > > > kexec/arch/i386/crashdump-x86.c | 20 +++++- > > > kexec/crashdump-xen.c | 34 ++++++++++ > > > kexec/crashdump.h | 3 +- > > > kexec/kexec-xen.c | 139 +++++++++++++++++++++++++++++++++++++++ > > > kexec/kexec.c | 24 +++++-- > > > kexec/kexec.h | 5 ++ > > > 7 files changed, 218 insertions(+), 8 deletions(-) > > > create mode 100644 kexec/kexec-xen.c > > > > > [...] > > > I have applied the following follow-up patch to resolves some errors. > > Let me know if I messed it up. > > > > From: Simon Horman <horms@verge.net.au> > > > > [PATCH] kexec/xen: Correct some compile errors > > > > Correct various problems introduced by > > 08cf823704b0fa3b ("kexec/xen: directly load images images into Xen"). > > > > These all relate to the case here HAVE_LIBXENCTRL is not set. > > > > Signed-off-by: Simon Horman <horms@verge.net.au> > > --- > > kexec/kexec-xen.c | 7 +++---- > > 1 file changed, 3 insertions(+), 4 deletions(-) > > > > diff --git a/kexec/kexec-xen.c b/kexec/kexec-xen.c > > index 77f65c0..e885246 100644 > > --- a/kexec/kexec-xen.c > > +++ b/kexec/kexec-xen.c > > @@ -2,6 +2,7 @@ > > #include <stdio.h> > > #include <string.h> > > #include <stdlib.h> > > +#include <stdlib.h> > > Thanks for fixes but why are you including stdlib.h twice?Sorry, that is an error.