Accepting request 221060 from home:jones_tony:branches:Kernel:kdump

OBS-URL: https://build.opensuse.org/request/show/221060
OBS-URL: https://build.opensuse.org/package/show/Kernel:kdump/kexec-tools?expand=0&rev=36
This commit is contained in:
Tony Jones 2014-02-05 23:15:44 +00:00 committed by Git OBS Bridge
parent 213612d58b
commit 4ee4fd74f4
14 changed files with 684 additions and 951 deletions

View File

@ -1,78 +0,0 @@
From 1cbddc80ddfe34cdcdac11c0562e4d8395c48b16 Mon Sep 17 00:00:00 2001
From: Laurent Dufour <ldufour@linux.vnet.ibm.com>
Date: Tue, 15 Oct 2013 19:05:28 +0200
Subject: [PATCH] kexec/fs2dt: fix endianess conversion
Patch-mainline: yes
While reviewing fs2dt.c in the common kexec directory, in order to use it to
support little endian ppc64 architecture, I found some endianess
conversion's issues.
In dt_reserve, dt_base is a pointer and thus should not be converted.
In checkprop, values read from the device tree are big endian encoded and
should be converted if CPU is running in little endian mode.
In add_dyn_reconf_usable_mem_property__, fix extraneous endianess conversion
of rlen which should be natively used to increase the dt pointer.
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/fs2dt.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/kexec/fs2dt.c b/kexec/fs2dt.c
index 242a15e..5d774ae 100644
--- a/kexec/fs2dt.c
+++ b/kexec/fs2dt.c
@@ -84,7 +84,7 @@ static void dt_reserve(unsigned **dt_ptr, unsigned words)
offset = *dt_ptr - dt_base;
dt_base = new_dt;
dt_cur_size = new_size;
- *dt_ptr = cpu_to_be32((unsigned)dt_base + offset);
+ *dt_ptr = dt_base + offset;
memset(*dt_ptr, 0, (new_size - offset)*4);
}
}
@@ -112,19 +112,22 @@ static void checkprop(char *name, unsigned *data, int len)
if ((data == NULL) && (base || size || end))
die("unrecoverable error: no property data");
else if (!strcmp(name, "linux,rtas-base"))
- base = *data;
+ base = be32_to_cpu(*data);
else if (!strcmp(name, "linux,tce-base"))
- base = *(unsigned long long *) data;
+ base = be64_to_cpu(*(unsigned long long *) data);
else if (!strcmp(name, "rtas-size") ||
!strcmp(name, "linux,tce-size"))
- size = *data;
+ size = be32_to_cpu(*data);
else if (reuse_initrd && !strcmp(name, "linux,initrd-start"))
if (len == 8)
- base = *(unsigned long long *) data;
+ base = be64_to_cpu(*(unsigned long long *) data);
else
- base = *data;
+ base = be32_to_cpu(*data);
else if (reuse_initrd && !strcmp(name, "linux,initrd-end"))
- end = *(unsigned long long *) data;
+ if (len == 8)
+ end = be64_to_cpu(*(unsigned long long *) data);
+ else
+ end = be32_to_cpu(*data);
if (size && end)
die("unrecoverable error: size and end set at same time\n");
@@ -267,7 +270,7 @@ static void add_dyn_reconf_usable_mem_property__(int fd)
pad_structure_block(rlen);
memcpy(dt, ranges, rlen);
free(ranges);
- dt += cpu_to_be32((rlen + 3)/4);
+ dt += (rlen + 3)/4;
}
static void add_dyn_reconf_usable_mem_property(struct dirent *dp, int fd)
--
1.8.4.1

View File

@ -1,39 +0,0 @@
From 01d6e4371f2c49459f3600a2bbadbc66a94f870b Mon Sep 17 00:00:00 2001
From: Dirk Mueller <dmueller@suse.com>
Date: Mon, 3 Feb 2014 18:50:04 +0100
Subject: [PATCH] Avoid buffer overflow on strncat usage
strncat() does not want the total size but the maximum length
(without trailing NUL) that can still be added. Switch over
to snprintf which is both more readable and avoids this issue.
Signed-off-by: Dirk Mueller <dmueller@suse.com>
---
kexec/fs2dt.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
Index: kexec/fs2dt.c
===================================================================
--- kexec/fs2dt.c.orig
+++ kexec/fs2dt.c
@@ -614,8 +614,7 @@ static void putnode(void)
* code can print 'I'm in purgatory' message. Currently only
* pseries/hvcterminal is supported.
*/
- strcpy(filename, pathname);
- strncat(filename, "linux,stdout-path", MAXPATH);
+ snprintf(filename, MAXPATH, "%slinux,stdout-path", pathname);
fd = open(filename, O_RDONLY);
if (fd == -1) {
printf("Unable to find %s, printing from purgatory is diabled\n",
@@ -638,9 +637,7 @@ static void putnode(void)
}
read(fd, buff, statbuf.st_size);
close(fd);
- strncpy(filename, "/proc/device-tree/", MAXPATH);
- strncat(filename, buff, MAXPATH);
- strncat(filename, "/compatible", MAXPATH);
+ snprintf(filename, MAXPATH, "/proc/device-tree/%s/compatible", buff);
fd = open(filename, O_RDONLY);
if (fd == -1) {
printf("Unable to find %s printing from purgatory is diabled\n",

View File

@ -1,797 +0,0 @@
From: Geoff Levand <geoff@infradead.org>
Date: Mon, 15 Jul 2013 23:32:36 +0000 (-0700)
Subject: Add arm64 support
Patch-mainline: Not yet
References: http://fedorapeople.org/~hrw/aarch64/for-fedora/kexec-aarch64.patch
X-Git-Url: https://git.linaro.org/gitweb?p=people%2Fgeoff%2Fkexec-tools.git;a=commitdiff_plain;h=fbf5ac6c2c70ec0f6da2b9ff563e573999752c01
Add arm64 support
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
Index: kexec-tools-2.0.4/configure.ac
===================================================================
--- kexec-tools-2.0.4.orig/configure.ac
+++ kexec-tools-2.0.4/configure.ac
@@ -30,6 +30,9 @@ case $target_cpu in
powerpc64 )
ARCH="ppc64"
;;
+ aarch64 )
+ ARCH="arm64"
+ ;;
arm* )
ARCH="arm"
;;
Index: kexec-tools-2.0.4/kexec/Makefile
===================================================================
--- kexec-tools-2.0.4.orig/kexec/Makefile
+++ kexec-tools-2.0.4/kexec/Makefile
@@ -70,6 +70,7 @@ KEXEC_SRCS += $($(ARCH)_FS2DT)
include $(srcdir)/kexec/arch/alpha/Makefile
include $(srcdir)/kexec/arch/arm/Makefile
+include $(srcdir)/kexec/arch/arm64/Makefile
include $(srcdir)/kexec/arch/i386/Makefile
include $(srcdir)/kexec/arch/ia64/Makefile
include $(srcdir)/kexec/arch/mips/Makefile
Index: kexec-tools-2.0.4/kexec/arch/arm64/Makefile
===================================================================
--- /dev/null
+++ kexec-tools-2.0.4/kexec/arch/arm64/Makefile
@@ -0,0 +1,13 @@
+
+arm64_KEXEC_SRCS += \
+ kexec/arch/arm64/kexec-arm64.c \
+ kexec/arch/arm64/kexec-elf-arm64.c \
+ kexec/arch/arm64/crashdump-arm64.c
+
+arm64_ARCH_REUSE_INITRD =
+arm64_ADD_SEGMENT =
+arm64_VIRT_TO_PHYS =
+
+dist += $(arm64_KEXEC_SRCS) \
+ kexec/arch/arm64/Makefile \
+ kexec/arch/arm64/kexec-arm64.h
Index: kexec-tools-2.0.4/kexec/arch/arm64/crashdump-arm64.c
===================================================================
--- /dev/null
+++ kexec-tools-2.0.4/kexec/arch/arm64/crashdump-arm64.c
@@ -0,0 +1,305 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation (version 2 of the License).
+ */
+
+#include "../../kexec.h"
+#include "../../kexec-elf.h"
+#include "../../crashdump.h"
+
+int is_crashkernel_mem_reserved(void)
+{
+ return 0;
+}
+
+#if 0
+/*
+ * Used to save various memory ranges/regions needed for the captured
+ * kernel to boot. (lime memmap= option in other archs)
+ */
+static struct memory_range crash_memory_ranges[CRASH_MAX_MEMORY_RANGES];
+struct memory_ranges usablemem_rgns = {
+ .size = 0,
+ .ranges = crash_memory_ranges,
+};
+
+/* memory range reserved for crashkernel */
+static struct memory_range crash_reserved_mem;
+
+static struct crash_elf_info elf_info = {
+ .class = ELFCLASS32,
+ .data = ELFDATA2LSB,
+ .machine = EM_ARM,
+ .page_offset = PAGE_OFFSET,
+};
+
+unsigned long phys_offset;
+
+/**
+ * crash_range_callback() - callback called for each iomem region
+ * @data: not used
+ * @nr: not used
+ * @str: name of the memory region
+ * @base: start address of the memory region
+ * @length: size of the memory region
+ *
+ * This function is called once for each memory region found in /proc/iomem. It
+ * locates system RAM and crashkernel reserved memory and places these to
+ * variables: @crash_memory_ranges and @crash_reserved_mem. Number of memory
+ * regions is placed in @crash_memory_nr_ranges.
+ */
+static int crash_range_callback(void *UNUSED(data), int UNUSED(nr),
+ char *str, unsigned long base,
+ unsigned long length)
+{
+ struct memory_range *range;
+
+ if (usablemem_rgns.size >= CRASH_MAX_MEMORY_RANGES)
+ return 1;
+
+ range = usablemem_rgns.ranges + usablemem_rgns.size;
+
+ if (strncmp(str, "System RAM\n", 11) == 0) {
+ range->start = base;
+ range->end = base + length - 1;
+ range->type = RANGE_RAM;
+ usablemem_rgns.size++;
+ } else if (strncmp(str, "Crash kernel\n", 13) == 0) {
+ crash_reserved_mem.start = base;
+ crash_reserved_mem.end = base + length - 1;
+ crash_reserved_mem.type = RANGE_RAM;
+ }
+
+ return 0;
+}
+
+/**
+ * crash_exclude_range() - excludes memory region reserved for crashkernel
+ *
+ * Function locates where crashkernel reserved memory is and removes that region
+ * from the available memory regions.
+ */
+static void crash_exclude_range(void)
+{
+ const struct memory_range *range = &crash_reserved_mem;
+ int i;
+
+ for (i = 0; i < usablemem_rgns.size; i++) {
+ struct memory_range *r = usablemem_rgns.ranges + i;
+
+ /*
+ * We assume that crash area is fully contained in
+ * some larger memory area.
+ */
+ if (r->start <= range->start && r->end >= range->end) {
+ struct memory_range *new;
+ /*
+ * Let's split this area into 2 smaller ones and
+ * remove excluded range from between. First create
+ * new entry for the remaining area.
+ */
+ new = usablemem_rgns.ranges + usablemem_rgns.size;
+ new->start = range->end + 1;
+ new->end = r->end;
+ usablemem_rgns.size++;
+ /*
+ * Next update this area to end before excluded range.
+ */
+ r->end = range->start - 1;
+ break;
+ }
+ }
+}
+
+static int range_cmp(const void *a1, const void *a2)
+{
+ const struct memory_range *r1 = a1;
+ const struct memory_range *r2 = a2;
+
+ if (r1->start > r2->start)
+ return 1;
+ if (r1->start < r2->start)
+ return -1;
+
+ return 0;
+}
+
+/**
+ * crash_get_memory_ranges() - read system physical memory
+ *
+ * Function reads through system physical memory and stores found memory regions
+ * in @crash_memory_ranges. Number of memory regions found is placed in
+ * @crash_memory_nr_ranges. Regions are sorted in ascending order.
+ *
+ * Returns %0 in case of success and %-1 otherwise (errno is set).
+ */
+static int crash_get_memory_ranges(void)
+{
+ /*
+ * First read all memory regions that can be considered as
+ * system memory including the crash area.
+ */
+ kexec_iomem_for_each_line(NULL, crash_range_callback, NULL);
+
+ if (usablemem_rgns.size < 1) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /*
+ * Exclude memory reserved for crashkernel (this may result a split memory
+ * region).
+ */
+ crash_exclude_range();
+
+ /*
+ * Make sure that the memory regions are sorted.
+ */
+ qsort(usablemem_rgns.ranges, usablemem_rgns.size,
+ sizeof(*usablemem_rgns.ranges), range_cmp);
+
+ return 0;
+}
+
+/**
+ * cmdline_add_elfcorehdr() - adds elfcorehdr= to @cmdline
+ * @cmdline: buffer where parameter is placed
+ * @elfcorehdr: physical address of elfcorehdr
+ *
+ * Function appends 'elfcorehdr=start' at the end of the command line given in
+ * @cmdline. Note that @cmdline must be at least %COMMAND_LINE_SIZE bytes long
+ * (inclunding %NUL).
+ */
+static void cmdline_add_elfcorehdr(char *cmdline, unsigned long elfcorehdr)
+{
+ char buf[COMMAND_LINE_SIZE];
+ int buflen;
+
+ buflen = snprintf(buf, sizeof(buf), "%s elfcorehdr=%#lx",
+ cmdline, elfcorehdr);
+ if (buflen < 0)
+ die("Failed to construct elfcorehdr= command line parameter\n");
+ if (buflen >= sizeof(buf))
+ die("Command line overflow\n");
+
+ (void) strncpy(cmdline, buf, COMMAND_LINE_SIZE);
+ cmdline[COMMAND_LINE_SIZE - 1] = '\0';
+}
+
+/**
+ * cmdline_add_mem() - adds mem= parameter to kernel command line
+ * @cmdline: buffer where parameter is placed
+ * @size: size of the kernel reserved memory (in bytes)
+ *
+ * This function appends 'mem=size' at the end of the command line given in
+ * @cmdline. Note that @cmdline must be at least %COMMAND_LINE_SIZE bytes long
+ * (including %NUL).
+ */
+static void cmdline_add_mem(char *cmdline, unsigned long size)
+{
+ char buf[COMMAND_LINE_SIZE];
+ int buflen;
+
+ buflen = snprintf(buf, sizeof(buf), "%s mem=%ldK", cmdline, size >> 10);
+ if (buflen < 0)
+ die("Failed to construct mem= command line parameter\n");
+ if (buflen >= sizeof(buf))
+ die("Command line overflow\n");
+
+ (void) strncpy(cmdline, buf, COMMAND_LINE_SIZE);
+ cmdline[COMMAND_LINE_SIZE - 1] = '\0';
+}
+
+static unsigned long long range_size(const struct memory_range *r)
+{
+ return r->end - r->start + 1;
+}
+
+static void dump_memory_ranges(void)
+{
+ int i;
+
+ if (!kexec_debug)
+ return;
+
+ dbgprintf("crashkernel: [%#llx - %#llx] (%ldM)\n",
+ crash_reserved_mem.start, crash_reserved_mem.end,
+ (unsigned long)range_size(&crash_reserved_mem) >> 20);
+
+ for (i = 0; i < usablemem_rgns.size; i++) {
+ struct memory_range *r = usablemem_rgns.ranges + i;
+ dbgprintf("memory range: [%#llx - %#llx] (%ldM)\n",
+ r->start, r->end, (unsigned long)range_size(r) >> 20);
+ }
+}
+
+/**
+ * load_crashdump_segments() - loads additional segments needed for kdump
+ * @info: kexec info structure
+ * @mod_cmdline: kernel command line
+ *
+ * This function loads additional segments which are needed for the dump capture
+ * kernel. It also updates kernel command line passed in @mod_cmdline to have
+ * right parameters for the dump capture kernel.
+ *
+ * Return %0 in case of success and %-1 in case of error.
+ */
+int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline)
+{
+ unsigned long elfcorehdr;
+ unsigned long bufsz;
+ void *buf;
+ int err;
+
+ /*
+ * First fetch all the memory (RAM) ranges that we are going to pass to
+ * the crashdump kernel during panic.
+ */
+ err = crash_get_memory_ranges();
+ if (err)
+ return err;
+
+ /*
+ * Now that we have memory regions sorted, we can use first memory
+ * region as PHYS_OFFSET.
+ */
+ phys_offset = usablemem_rgns.ranges->start;
+ dbgprintf("phys_offset: %#lx\n", phys_offset);
+
+ err = crash_create_elf32_headers(info, &elf_info,
+ usablemem_rgns.ranges,
+ usablemem_rgns.size, &buf, &bufsz,
+ ELF_CORE_HEADER_ALIGN);
+ if (err)
+ return err;
+
+ /*
+ * We allocate ELF core header from the end of the memory area reserved
+ * for the crashkernel. We align the header to SECTION_SIZE (which is
+ * 1MB) so that available memory passed in kernel command line will be
+ * aligned to 1MB. This is because kernel create_mapping() wants memory
+ * regions to be aligned to SECTION_SIZE.
+ */
+ elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 1 << 20,
+ crash_reserved_mem.start,
+ crash_reserved_mem.end, -1, 0);
+
+ dbgprintf("elfcorehdr: %#lx\n", elfcorehdr);
+ cmdline_add_elfcorehdr(mod_cmdline, elfcorehdr);
+
+ /*
+ * Add 'mem=size' parameter to dump capture kernel command line. This
+ * prevents the dump capture kernel from using any other memory regions
+ * which belong to the primary kernel.
+ */
+ cmdline_add_mem(mod_cmdline, elfcorehdr - crash_reserved_mem.start);
+
+ dump_memory_ranges();
+ dbgprintf("kernel command line: \"%s\"\n", mod_cmdline);
+
+ return 0;
+}
+
+#endif
+
Index: kexec-tools-2.0.4/kexec/arch/arm64/include/arch/options.h
===================================================================
--- /dev/null
+++ kexec-tools-2.0.4/kexec/arch/arm64/include/arch/options.h
@@ -0,0 +1,26 @@
+#ifndef KEXEC_ARCH_ARM64_OPTIONS_H
+#define KEXEC_ARCH_ARM64_OPTIONS_H
+
+//#define OPT_ARCH_MAX ((OPT_MAX)+0)
+
+#define OPT_APPEND ((OPT_MAX)+0)
+#define OPT_RAMDISK ((OPT_MAX)+1)
+#define OPT_DTB ((OPT_MAX)+2)
+
+#define OPT_ARCH_MAX ((OPT_MAX)+3)
+
+
+#define KEXEC_ARCH_OPTIONS \
+ KEXEC_OPTIONS \
+ { "append", 1, NULL, OPT_APPEND }, \
+ { "command-line", 1, NULL, OPT_APPEND }, \
+ { "dtb", 1, NULL, OPT_DTB }, \
+ { "initrd", 1, NULL, OPT_RAMDISK }, \
+ { "ramdisk", 1, NULL, OPT_RAMDISK }, \
+
+#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR /* Only accept long arch options. */
+
+#define KEXEC_ALL_OPTIONS KEXEC_ARCH_OPTIONS
+#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR
+
+#endif /* KEXEC_ARCH_ARM64_OPTIONS_H */
Index: kexec-tools-2.0.4/kexec/arch/arm64/kexec-arm64.c
===================================================================
--- /dev/null
+++ kexec-tools-2.0.4/kexec/arch/arm64/kexec-arm64.c
@@ -0,0 +1,177 @@
+/*
+ * ARM64 kexec support.
+ */
+
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <stddef.h>
+
+//#include <linux/kexec.h>
+
+#include "../../kexec.h"
+#include "../../kexec-syscall.h"
+#include "kexec-arm64.h"
+
+
+void arch_usage(void)
+{
+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
+
+ printf(
+" --append=STRING Set the kernel command line to STRING.\n"
+" --command-line=STRING Set the kernel command line to STRING.\n"
+" --dtb=FILE Use FILE as the device tree blob.\n"
+" --initrd=FILE Use FILE as the kernel initial ramdisk.\n"
+" --ramdisk=FILE Use FILE as the kernel initial ramdisk.\n");
+
+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
+}
+
+int arch_process_options(int UNUSED(argc), char **UNUSED(argv))
+{
+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
+ return 0;
+}
+
+const struct arch_map_entry arches[] = {
+ { "aarch64", KEXEC_ARCH_ARM64 },
+ { NULL, 0 },
+};
+
+void arch_update_purgatory(struct kexec_info *UNUSED(info))
+{
+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
+}
+
+unsigned long virt_to_phys(unsigned long addr)
+{
+ fprintf(stderr, "%s:%d: %016lx -> %016lx\n", __func__, __LINE__, addr,
+ addr + 0x080000000UL);
+ return addr + 0x080000000UL;
+}
+
+void add_segment(struct kexec_info *info, const void *buf, size_t bufsz,
+ unsigned long base, size_t memsz)
+{
+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
+ add_segment_phys_virt(info, buf, bufsz, base, memsz, 1);
+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
+}
+
+static int get_memory_ranges_1(struct memory_range **range, int *ranges,
+ unsigned long kexec_flags)
+{
+ static struct memory_range memory_range[KEXEC_SEGMENT_MAX];
+ const char *iomem;
+ int range_count = 0;
+ char line[MAX_LINE];
+ FILE *fp;
+
+ iomem = proc_iomem();
+ fp = fopen(iomem, "r");
+
+ if (!fp) {
+ fprintf(stderr, "Cannot open %s: %s\n",
+ iomem, strerror(errno));
+ return -1;
+ }
+
+ dbgprintf("memory ranges:\n");
+
+ while(fgets(line, sizeof(line), fp) != 0) {
+ struct memory_range r;
+ char *str;
+ int consumed;
+
+ if (range_count >= KEXEC_SEGMENT_MAX)
+ break;
+
+ if (sscanf(line, "%Lx-%Lx : %n", &r.start, &r.end, &consumed)
+ != 2)
+ continue;
+
+ str = line + consumed;
+ r.end++;
+
+ if (memcmp(str, "System RAM\n", 11)) {
+ dbgprintf(" Skip: %016Lx - %016Lx : %s", r.start, r.end,
+ str);
+ continue;
+ }
+
+ r.type = RANGE_RAM;
+ memory_range[range_count] = r;
+ range_count++;
+
+ dbgprintf(" Add: %016Lx - %016Lx : %s", r.start, r.end, str);
+ }
+
+ fclose(fp);
+ *range = memory_range;
+ *ranges = range_count;
+
+ return 0;
+}
+
+static int get_memory_ranges_2(struct memory_range **range, int *ranges,
+ unsigned long UNUSED(kexec_flags))
+{
+ static struct memory_range memory_range[2];
+
+ memory_range[0].start = 0x080000000;
+ memory_range[0].end = 0x100000000;
+ memory_range[0].type = RANGE_RAM;
+
+ memory_range[1].start = 0x900000000;
+ memory_range[1].end = 0x880000000;
+ memory_range[1].type = RANGE_RAM;
+
+ *range = memory_range;
+ *ranges = sizeof(memory_range) / sizeof(memory_range[0]);
+
+ return 0;
+}
+
+int get_memory_ranges(struct memory_range **range, int *ranges,
+ unsigned long kexec_flags)
+{
+ /* FIXME: Should get this info from device tree. */
+
+ return get_memory_ranges_1(range, ranges, kexec_flags);
+}
+
+struct file_type file_type[] = {
+ { "elf-arm64", elf_arm64_probe, elf_arm64_load, elf_arm64_usage },
+};
+
+int file_types = sizeof(file_type) / sizeof(file_type[0]);
+
+int arch_compat_trampoline(struct kexec_info *info)
+{
+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
+ return 0;
+}
+
+void arch_reuse_initrd(void)
+{
+}
+
+int machine_verify_elf_rel(struct mem_ehdr *ehdr)
+{
+ (void)ehdr;
+
+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
+ return 0;
+}
+
+void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
+ void *location, unsigned long address, unsigned long value)
+{
+ (void)ehdr;
+ (void)r_type;
+ (void)location;
+ (void)address;
+ (void)value;
+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
+}
Index: kexec-tools-2.0.4/kexec/arch/arm64/kexec-arm64.h
===================================================================
--- /dev/null
+++ kexec-tools-2.0.4/kexec/arch/arm64/kexec-arm64.h
@@ -0,0 +1,20 @@
+/*
+ * ARM64 kexec support.
+ */
+
+#if !defined(KEXEC_ARM64_H)
+#define KEXEC_ARM64_H
+
+/* #include <linux/kexec.h> FIXME: this is broken */
+#include <sys/types.h>
+
+#include "../../kexec.h"
+
+#define KEXEC_SEGMENT_MAX 16 /* FIXME: this should come from <linux/kexec.h> */
+
+int elf_arm64_probe(const char *buf, off_t len);
+int elf_arm64_load(int argc, char **argv, const char *buf, off_t len,
+ struct kexec_info *info);
+void elf_arm64_usage(void);
+
+#endif
\ No newline at end of file
Index: kexec-tools-2.0.4/kexec/arch/arm64/kexec-elf-arm64.c
===================================================================
--- /dev/null
+++ kexec-tools-2.0.4/kexec/arch/arm64/kexec-elf-arm64.c
@@ -0,0 +1,114 @@
+/*
+ * ARM64 kexec support.
+ */
+
+#define _GNU_SOURCE
+
+#include <elf.h>
+#include <getopt.h>
+
+#include "../../kexec-syscall.h"
+
+#include "kexec-arm64.h"
+#include "arch/options.h"
+
+#if !defined(EM_AARCH64)
+# define EM_AARCH64 183
+#endif
+
+int elf_arm64_probe(const char *buf, off_t len)
+{
+ int result;
+ struct mem_ehdr ehdr;
+
+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
+
+ result = build_elf_exec_info(buf, len, &ehdr, 0);
+
+ if (result < 0) {
+ dbgprintf("Not an ELF executable\n");
+ goto out;
+ }
+
+ if (ehdr.e_machine != EM_AARCH64) {
+ dbgprintf("Not an AARCH64 executable\n");
+ result = -1;
+ goto out;
+ }
+
+ result = 0;
+
+out:
+ free_elf_info(&ehdr);
+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
+ return result;
+}
+
+int elf_arm64_load(int argc, char **argv, const char *buf, off_t len,
+ struct kexec_info *info)
+{
+ static const struct option options[] = {
+ KEXEC_ARCH_OPTIONS
+ { 0 }
+ };
+ static const char short_options[] = KEXEC_OPT_STR "";
+ const char *command_line = NULL;
+ unsigned int command_line_len = 0;
+ const char *ramdisk = NULL;
+ const char *dtb = NULL;
+ int opt;
+ struct mem_ehdr ehdr;
+ int result;
+
+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
+
+ while ((opt = getopt_long(argc, argv, short_options, options, 0))
+ != -1) {
+ switch (opt) {
+ default:
+ if (opt < OPT_MAX) /* Ignore core options */
+ break;
+ case OPT_APPEND:
+ command_line = optarg;
+ command_line_len = strlen(command_line) + 1;
+ break;
+ case OPT_RAMDISK:
+ ramdisk = optarg;
+ break;
+ case OPT_DTB:
+ dtb = optarg;
+ break;
+ }
+ }
+
+ fprintf(stderr, "%s:%d: command_line: %s\n", __func__, __LINE__, command_line);
+ fprintf(stderr, "%s:%d: ramdisk: %s\n", __func__, __LINE__, ramdisk);
+ fprintf(stderr, "%s:%d: dtb: %s\n", __func__, __LINE__, dtb);
+
+ if (info->kexec_flags & KEXEC_ON_CRASH) {
+ fprintf(stderr, "kexec: kdump not yet supported on arm64\n");
+ return -1;
+ }
+
+ result = build_elf_exec_info(buf, len, &ehdr, 0);
+
+ if (result < 0) {
+ free_elf_info(&ehdr);
+ fprintf(stderr, "%s:%d: free_elf_info failed\n", __func__,
+ __LINE__);
+ return result;
+ }
+
+ elf_exec_build_load(info, &ehdr, buf, len, 0);
+
+ info->entry = (void*)0x80080000UL; // FIXME
+
+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
+ return 0;
+}
+
+void elf_arm64_usage(void)
+{
+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
+}
Index: kexec-tools-2.0.4/kexec/kexec-syscall.h
===================================================================
--- kexec-tools-2.0.4.orig/kexec/kexec-syscall.h
+++ kexec-tools-2.0.4/kexec/kexec-syscall.h
@@ -39,8 +39,8 @@
#ifdef __s390__
#define __NR_kexec_load 277
#endif
-#ifdef __arm__
-#define __NR_kexec_load __NR_SYSCALL_BASE + 347
+#if defined(__arm__) || defined(__arm64__)
+#define __NR_kexec_load __NR_SYSCALL_BASE + 347
#endif
#if defined(__mips__)
#define __NR_kexec_load 4311
@@ -72,6 +72,8 @@ static inline long kexec_load(void *entr
#define KEXEC_ARCH_PPC64 (21 << 16)
#define KEXEC_ARCH_IA_64 (50 << 16)
#define KEXEC_ARCH_ARM (40 << 16)
+#define KEXEC_ARCH_ARM64 (183 << 16)
+/* #define KEXEC_ARCH_AARCH64 (183 << 16) */
#define KEXEC_ARCH_S390 (22 << 16)
#define KEXEC_ARCH_SH (42 << 16)
#define KEXEC_ARCH_MIPS_LE (10 << 16)
@@ -114,5 +116,8 @@ static inline long kexec_load(void *entr
#if defined(__mips__)
#define KEXEC_ARCH_NATIVE KEXEC_ARCH_MIPS
#endif
+#if defined(__arm64__)
+#define KEXEC_ARCH_NATIVE KEXEC_ARCH_ARM64
+#endif
#endif /* KEXEC_SYSCALL_H */
Index: kexec-tools-2.0.4/kexec/kexec.c
===================================================================
--- kexec-tools-2.0.4.orig/kexec/kexec.c
+++ kexec-tools-2.0.4/kexec/kexec.c
@@ -659,6 +659,8 @@ static int my_load(const char *type, int
info.backup_start = 0;
info.kexec_flags = kexec_flags;
+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
+
result = 0;
if (argc - fileind <= 0) {
fprintf(stderr, "No kernel specified\n");
Index: kexec-tools-2.0.4/purgatory/arch/arm64/Makefile
===================================================================
--- /dev/null
+++ kexec-tools-2.0.4/purgatory/arch/arm64/Makefile
@@ -0,0 +1,7 @@
+#
+# Purgatory arm64
+#
+
+arm64_PURGATORY_SRCS =
+
+dist += purgatory/arch/arm64/Makefile $(arm64_PURGATORY_SRCS)
Index: kexec-tools-2.0.4/configure
===================================================================
--- kexec-tools-2.0.4.orig/configure
+++ kexec-tools-2.0.4/configure
@@ -2256,6 +2256,9 @@ case $target_cpu in
powerpc64 )
ARCH="ppc64"
;;
+ aarch64 )
+ ARCH="arm64"
+ ;;
arm* )
ARCH="arm"
;;

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ad3b8d1219f6fb98c89166f9e0069418ebdd4a48986783e0d52b5bd9f9051a4d
size 300973

3
kexec-tools-2.0.5.tar.xz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:216f91cadd1cd7ab3dd96b9d50a8d1ae68c65ae01f5b19233d985d75fbbf56e7
size 279684

View File

@ -0,0 +1,34 @@
From: Tony Jones <tonyj@suse.de>
Subject: fixup aarch64 libfdt
Upstream: no
LIBS change had global scope, fix.
---
kexec/arch/arm64/Makefile | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
--- a/kexec/arch/arm64/Makefile
+++ b/kexec/arch/arm64/Makefile
@@ -2,9 +2,14 @@
arm64_FS2DT += kexec/fs2dt.c
arm64_FS2DT_INCLUDE += -include $(srcdir)/kexec/arch/arm64/kexec-arm64.h
+libfdt_SRCS += $(LIBFDT_SRCS:%=kexec/libfdt/%)
+
arm64_KEXEC_SRCS += \
kexec/arch/arm64/kexec-arm64.c \
- kexec/arch/arm64/kexec-elf-arm64.c
+ kexec/arch/arm64/kexec-elf-arm64.c \
+ $(libfdt_SRCS)
+
+arm64_CPPFLAGS = -I$(srcdir)/kexec/libfdt
arm64_ARCH_REUSE_INITRD =
arm64_ADD_SEGMENT =
@@ -13,5 +18,3 @@ arm64_VIRT_TO_PHYS =
dist += $(arm64_KEXEC_SRCS) \
kexec/arch/arm64/Makefile \
kexec/arch/arm64/kexec-arm64.h
-
-LIBS += -lfdt

View File

@ -0,0 +1,550 @@
From: Geoff Levand <geoff@infradead.org>
Date: Mon, 15 Jul 2013 23:32:36 +0000 (-0700)
Subject: Add arm64 support
Git-repo: https://git.linaro.org/people/geoff.levand/kexec-tools.git
Git-commit: 44a50d00fa02dbb43d19a267039b53422a11eb6
Signed-off-by: Dirk Müller <dmueller@suse.com>
Add arm64 support
Signed-off-by: Geoff Levand <geoff@infradead.org>
diff --git a/configure.ac b/configure.ac
index 31d1bbe..c6e8bd6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -35,6 +35,9 @@ case $target_cpu in
ARCH="ppc64"
SUBARCH="LE"
;;
+ aarch64 )
+ ARCH="arm64"
+ ;;
arm* )
ARCH="arm"
;;
diff --git a/kexec/Makefile b/kexec/Makefile
index 7d3175b..9777ec3 100644
--- a/kexec/Makefile
+++ b/kexec/Makefile
@@ -71,6 +71,7 @@ KEXEC_SRCS += $($(ARCH)_FS2DT)
include $(srcdir)/kexec/arch/alpha/Makefile
include $(srcdir)/kexec/arch/arm/Makefile
+include $(srcdir)/kexec/arch/arm64/Makefile
include $(srcdir)/kexec/arch/i386/Makefile
include $(srcdir)/kexec/arch/ia64/Makefile
include $(srcdir)/kexec/arch/m68k/Makefile
diff --git a/kexec/arch/arm64/Makefile b/kexec/arch/arm64/Makefile
new file mode 100644
index 0000000..8b7f8a5
--- /dev/null
+++ b/kexec/arch/arm64/Makefile
@@ -0,0 +1,17 @@
+
+arm64_FS2DT += kexec/fs2dt.c
+arm64_FS2DT_INCLUDE += -include $(srcdir)/kexec/arch/arm64/kexec-arm64.h
+
+arm64_KEXEC_SRCS += \
+ kexec/arch/arm64/kexec-arm64.c \
+ kexec/arch/arm64/kexec-elf-arm64.c
+
+arm64_ARCH_REUSE_INITRD =
+arm64_ADD_SEGMENT =
+arm64_VIRT_TO_PHYS =
+
+dist += $(arm64_KEXEC_SRCS) \
+ kexec/arch/arm64/Makefile \
+ kexec/arch/arm64/kexec-arm64.h
+
+LIBS += -lfdt
diff --git a/kexec/arch/arm64/include/arch/options.h b/kexec/arch/arm64/include/arch/options.h
new file mode 100644
index 0000000..c9a0287
--- /dev/null
+++ b/kexec/arch/arm64/include/arch/options.h
@@ -0,0 +1,30 @@
+#ifndef KEXEC_ARCH_ARM64_OPTIONS_H
+#define KEXEC_ARCH_ARM64_OPTIONS_H
+
+#define OPT_APPEND ((OPT_MAX)+0)
+#define OPT_RAMDISK ((OPT_MAX)+1)
+#define OPT_DTB ((OPT_MAX)+2)
+#define OPT_ARCH_MAX ((OPT_MAX)+3)
+
+#define KEXEC_ARCH_OPTIONS \
+ KEXEC_OPTIONS \
+ { "append", 1, NULL, OPT_APPEND }, \
+ { "command-line", 1, NULL, OPT_APPEND }, \
+ { "dtb", 1, NULL, OPT_DTB }, \
+ { "initrd", 1, NULL, OPT_RAMDISK }, \
+ { "ramdisk", 1, NULL, OPT_RAMDISK }, \
+
+#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR /* Only accept long arch options. */
+
+#define KEXEC_ALL_OPTIONS KEXEC_ARCH_OPTIONS
+#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR
+
+struct arm64_opts {
+ const char *command_line;
+ const char *ramdisk;
+ const char *dtb;
+};
+
+struct arm64_opts arm64_opts;
+
+#endif /* KEXEC_ARCH_ARM64_OPTIONS_H */
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
new file mode 100644
index 0000000..e02c38d
--- /dev/null
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -0,0 +1,228 @@
+/*
+ * ARM64 kexec support.
+ */
+
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <getopt.h>
+#include <stddef.h>
+
+//#include <linux/kexec.h>
+
+#include "../../kexec.h"
+#include "../../kexec-syscall.h"
+#include "kexec-arm64.h"
+#include "arch/options.h"
+
+/* Global varables the core kexec routines expect. */
+
+unsigned char reuse_initrd;
+off_t initrd_base = 0;
+off_t initrd_size = 0;
+
+struct memory_ranges usablemem_rgns = {
+};
+
+const struct arch_map_entry arches[] = {
+ { "aarch64", KEXEC_ARCH_ARM64 },
+ { NULL, 0 },
+};
+
+/* arm64 global varables. */
+
+struct arm64_opts arm64_opts;
+
+void arch_usage(void)
+{
+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
+
+ printf(
+" --append=STRING Set the kernel command line to STRING.\n"
+" --command-line=STRING Set the kernel command line to STRING.\n"
+" --dtb=FILE Use FILE as the device tree blob.\n"
+" --initrd=FILE Use FILE as the kernel initial ramdisk.\n"
+" --ramdisk=FILE Use FILE as the kernel initial ramdisk.\n");
+
+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
+}
+
+int arch_process_options(int argc, char **argv)
+{
+ static const char short_options[] = KEXEC_OPT_STR "";
+ static const struct option options[] = {
+ KEXEC_ARCH_OPTIONS
+ { 0 }
+ };
+ int opt;
+
+ for (opt = 0; opt != -1; ) {
+ opt = getopt_long(argc, argv, short_options, options, 0);
+
+ switch (opt) {
+ case OPT_APPEND:
+ arm64_opts.command_line = optarg;
+ break;
+ case OPT_RAMDISK:
+ arm64_opts.ramdisk = optarg;
+ break;
+ case OPT_DTB:
+ arm64_opts.dtb = optarg;
+ break;
+ default:
+ break; /* Ignore core and unknown options */
+ }
+ }
+
+ dbgprintf("%s:%d: command_line: %s\n", __func__, __LINE__,
+ arm64_opts.command_line);
+ dbgprintf("%s:%d: ramdisk: %s\n", __func__, __LINE__,
+ arm64_opts.ramdisk);
+ dbgprintf("%s:%d: dtb: %s\n", __func__, __LINE__, arm64_opts.dtb);
+
+ return 0;
+}
+
+int is_crashkernel_mem_reserved(void)
+{
+ return 0; /* TODO: kdump not implemented yet. */
+}
+
+void arch_reuse_initrd(void)
+{
+ reuse_initrd = 1;
+}
+
+void arch_update_purgatory(struct kexec_info *UNUSED(info))
+{
+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
+}
+
+unsigned long virt_to_phys(unsigned long addr)
+{
+ fprintf(stderr, "%s:%d: %016lx -> %016lx\n", __func__, __LINE__, addr,
+ addr + 0x080000000UL);
+ return addr + 0x080000000UL;
+}
+
+void add_segment(struct kexec_info *info, const void *buf, size_t bufsz,
+ unsigned long base, size_t memsz)
+{
+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
+ add_segment_phys_virt(info, buf, bufsz, base, memsz, 1);
+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
+}
+
+static int get_memory_ranges_1(struct memory_range **range, int *ranges,
+ unsigned long kexec_flags)
+{
+ static struct memory_range memory_range[KEXEC_SEGMENT_MAX];
+ const char *iomem;
+ int range_count = 0;
+ char line[MAX_LINE];
+ FILE *fp;
+
+ iomem = proc_iomem();
+ fp = fopen(iomem, "r");
+
+ if (!fp) {
+ fprintf(stderr, "Cannot open %s: %s\n",
+ iomem, strerror(errno));
+ return -1;
+ }
+
+ dbgprintf("memory ranges:\n");
+
+ while(fgets(line, sizeof(line), fp) != 0) {
+ struct memory_range r;
+ char *str;
+ int consumed;
+
+ if (range_count >= KEXEC_SEGMENT_MAX)
+ break;
+
+ if (sscanf(line, "%Lx-%Lx : %n", &r.start, &r.end, &consumed)
+ != 2)
+ continue;
+
+ str = line + consumed;
+ r.end++;
+
+ if (memcmp(str, "System RAM\n", 11)) {
+ dbgprintf(" Skip: %016Lx - %016Lx : %s", r.start, r.end,
+ str);
+ continue;
+ }
+
+ r.type = RANGE_RAM;
+ memory_range[range_count] = r;
+ range_count++;
+
+ dbgprintf(" Add: %016Lx - %016Lx : %s", r.start, r.end, str);
+ }
+
+ fclose(fp);
+ *range = memory_range;
+ *ranges = range_count;
+
+ return 0;
+}
+
+static int get_memory_ranges_2(struct memory_range **range, int *ranges,
+ unsigned long UNUSED(kexec_flags))
+{
+ static struct memory_range memory_range[2];
+
+ memory_range[0].start = 0x080000000;
+ memory_range[0].end = 0x100000000;
+ memory_range[0].type = RANGE_RAM;
+
+ memory_range[1].start = 0x900000000;
+ memory_range[1].end = 0x880000000;
+ memory_range[1].type = RANGE_RAM;
+
+ *range = memory_range;
+ *ranges = sizeof(memory_range) / sizeof(memory_range[0]);
+
+ return 0;
+}
+
+int get_memory_ranges(struct memory_range **range, int *ranges,
+ unsigned long kexec_flags)
+{
+ /* FIXME: Should get this info from device tree. */
+
+ return get_memory_ranges_1(range, ranges, kexec_flags);
+}
+
+struct file_type file_type[] = {
+ { "elf-arm64", elf_arm64_probe, elf_arm64_load, elf_arm64_usage },
+};
+
+int file_types = sizeof(file_type) / sizeof(file_type[0]);
+
+int arch_compat_trampoline(struct kexec_info *info)
+{
+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
+ return 0;
+}
+
+
+int machine_verify_elf_rel(struct mem_ehdr *ehdr)
+{
+ (void)ehdr;
+
+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
+ return 0;
+}
+
+void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
+ void *location, unsigned long address, unsigned long value)
+{
+ (void)ehdr;
+ (void)r_type;
+ (void)location;
+ (void)address;
+ (void)value;
+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
+}
diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h
new file mode 100644
index 0000000..673d525
--- /dev/null
+++ b/kexec/arch/arm64/kexec-arm64.h
@@ -0,0 +1,28 @@
+/*
+ * ARM64 kexec support.
+ */
+
+#if !defined(KEXEC_ARM64_H)
+#define KEXEC_ARM64_H
+
+/* #include <linux/kexec.h> FIXME: this is broken */
+#include <sys/types.h>
+
+#include "../../kexec.h"
+
+#define KEXEC_SEGMENT_MAX 16 /* FIXME: this should come from <linux/kexec.h> */
+
+#define BOOT_BLOCK_VERSION 17
+#define BOOT_BLOCK_LAST_COMP_VERSION 16
+#define COMMAND_LINE_SIZE 512
+
+int elf_arm64_probe(const char *buf, off_t len);
+int elf_arm64_load(int argc, char **argv, const char *buf, off_t len,
+ struct kexec_info *info);
+void elf_arm64_usage(void);
+
+struct memory_ranges usablemem_rgns;
+off_t initrd_base;
+off_t initrd_size;
+
+#endif
diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c
new file mode 100644
index 0000000..b267a15
--- /dev/null
+++ b/kexec/arch/arm64/kexec-elf-arm64.c
@@ -0,0 +1,147 @@
+/*
+ * ARM64 kexec support.
+ */
+
+#define _GNU_SOURCE
+
+#include <elf.h>
+#include <getopt.h>
+#include <libfdt.h>
+
+#include "kexec-arm64.h"
+
+#include "../../kexec-syscall.h"
+#include "../../fs2dt.h"
+
+#include "arch/options.h"
+
+#if !defined(EM_AARCH64)
+# define EM_AARCH64 183
+#endif
+
+int elf_arm64_probe(const char *buf, off_t len)
+{
+ int result;
+ struct mem_ehdr ehdr;
+
+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
+
+ result = build_elf_exec_info(buf, len, &ehdr, 0);
+
+ if (result < 0) {
+ dbgprintf("Not an ELF executable\n");
+ goto out;
+ }
+
+ if (ehdr.e_machine != EM_AARCH64) {
+ dbgprintf("Not an AARCH64 executable\n");
+ result = -1;
+ goto out;
+ }
+
+ result = 0;
+
+out:
+ free_elf_info(&ehdr);
+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
+ return result;
+}
+
+static off_t round_up(off_t v)
+{
+ return _ALIGN_DOWN(v + getpagesize(), getpagesize());
+}
+
+int elf_arm64_load(int argc, char **argv, const char *buf, off_t len,
+ struct kexec_info *info)
+{
+ char *dtb_buf;
+ off_t dtb_base;
+ off_t dtb_size;
+ struct mem_ehdr ehdr;
+ int result;
+ //unsigned int command_line_len = strlen(arm64_opts.command_line) + 1;
+
+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
+
+ if (info->kexec_flags & KEXEC_ON_CRASH) {
+ fprintf(stderr, "kexec: kdump not yet supported on arm64\n");
+ return -1;
+ }
+
+ result = build_elf_exec_info(buf, len, &ehdr, 0);
+
+ if (result < 0) {
+ free_elf_info(&ehdr);
+ fprintf(stderr, "%s:%d: build_elf_exec_info failed\n", __func__,
+ __LINE__);
+ return result;
+ }
+
+ elf_exec_build_load(info, &ehdr, buf, len, 0);
+
+ info->entry = (void*)0x80080000UL; // FIXME
+
+ initrd_base = 0;
+ initrd_size = 0;
+
+ if (arm64_opts.ramdisk) {
+ char *buf;
+
+ buf = slurp_file(arm64_opts.ramdisk, &initrd_size);
+
+ if (!buf)
+ fprintf(stderr, "kexec: empty ramdisk file\n");
+ else {
+ initrd_base = locate_hole(info, initrd_size, 0, 0, -1, -1);
+
+ add_segment_phys_virt(info, buf, initrd_size, initrd_base,
+ initrd_size, 0);
+ }
+ }
+
+ fprintf(stderr, "%s:%d: initrd_base: %lx, initrd_size: %lx\n", __func__,
+ __LINE__, (unsigned long)initrd_base, (unsigned long)initrd_size);
+
+ if (arm64_opts.dtb)
+ dtb_buf = slurp_file(arm64_opts.dtb, &dtb_size);
+ else
+ create_flatten_tree(&dtb_buf, &dtb_size,
+ arm64_opts.command_line);
+
+ fprintf(stderr, "%s:%d: dt magic: %x : %x\n", __func__, __LINE__,
+ fdt32_to_cpu(*(uint32_t*)dtb_buf), *(uint32_t*)dtb_buf);
+
+ result = fdt_check_header(dtb_buf);
+
+ if (result) {
+ fprintf(stderr, "Invalid FDT.\n");
+ return -1;
+ }
+
+ if (arm64_opts.command_line) {
+ // FIXME: need to handle command line...
+ fprintf(stderr, "%s:%d: command line support TODO\n", __func__, __LINE__);
+ }
+
+if (1) {
+ dtb_base = (unsigned long)info->entry + round_up(0xA43FA0); // computed kernel mem size.
+
+ fprintf(stderr, "%s:%d: dtb_base: %lx, dtb_size: %lx\n", __func__,
+ __LINE__, (unsigned long)dtb_base, (unsigned long)dtb_size);
+} else {
+ dtb_base = locate_hole(info, dtb_size, 0, 0, -1, -1);
+
+ fprintf(stderr, "%s:%d: dtb_base: %lx, dtb_size: %lx\n", __func__,
+ __LINE__, (unsigned long)dtb_base, (unsigned long)dtb_size);
+}
+ add_segment_phys_virt(info, dtb_buf, dtb_size, dtb_base, dtb_size, 0);
+
+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
+ return 0;
+}
+
+void elf_arm64_usage(void)
+{
+ fprintf(stderr, "%s:%d\n", __func__, __LINE__);
+}
diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h
index 6238044..ccca19c 100644
--- a/kexec/kexec-syscall.h
+++ b/kexec/kexec-syscall.h
@@ -39,8 +39,8 @@
#ifdef __s390__
#define __NR_kexec_load 277
#endif
-#ifdef __arm__
-#define __NR_kexec_load __NR_SYSCALL_BASE + 347
+#if defined(__arm__) || defined(__arm64__)
+#define __NR_kexec_load __NR_SYSCALL_BASE + 347
#endif
#if defined(__mips__)
#define __NR_kexec_load 4311
@@ -76,6 +76,8 @@ static inline long kexec_load(void *entry, unsigned long nr_segments,
#define KEXEC_ARCH_PPC64 (21 << 16)
#define KEXEC_ARCH_IA_64 (50 << 16)
#define KEXEC_ARCH_ARM (40 << 16)
+#define KEXEC_ARCH_ARM64 (183 << 16)
+/* #define KEXEC_ARCH_AARCH64 (183 << 16) */
#define KEXEC_ARCH_S390 (22 << 16)
#define KEXEC_ARCH_SH (42 << 16)
#define KEXEC_ARCH_MIPS_LE (10 << 16)
@@ -121,5 +123,8 @@ static inline long kexec_load(void *entry, unsigned long nr_segments,
#ifdef __m68k__
#define KEXEC_ARCH_NATIVE KEXEC_ARCH_68K
#endif
+#if defined(__arm64__)
+#define KEXEC_ARCH_NATIVE KEXEC_ARCH_ARM64
+#endif
#endif /* KEXEC_SYSCALL_H */

View File

@ -0,0 +1,22 @@
From: Tony Jones <tonyj@suse.de>
Subject: fix build error on i386
Upstream: pending
Commit 9c200a85de2245a850546fded96a1977b84ad24d referenced
'bzImage_support_efi_boot' without matching 32-bit declaration.
Signed-off-by: Tony Jones <tonyj@suse.de>
---
kexec/arch/i386/kexec-bzImage.c | 1 +
1 file changed, 1 insertion(+)
--- a/kexec/arch/i386/kexec-bzImage.c
+++ b/kexec/arch/i386/kexec-bzImage.c
@@ -40,6 +40,7 @@
#include <arch/options.h>
static const int probe_debug = 0;
+int bzImage_support_efi_boot = 0;
int bzImage_probe(const char *buf, off_t len)
{

View File

@ -5,8 +5,8 @@ Disable ballooning before doing kexec.
---
kexec/crashdump-xen.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++---
kexec/crashdump.h | 1
kexec/kexec.c | 6 ++
kexec/kexec.h | 1
3 files changed, 119 insertions(+), 6 deletions(-)
--- a/kexec/crashdump-xen.c
@ -177,19 +177,9 @@ Disable ballooning before doing kexec.
unsigned long xen_architecture(struct crash_elf_info *elf_info)
{
unsigned long machine = elf_info->machine;
--- a/kexec/crashdump.h
+++ b/kexec/crashdump.h
@@ -57,6 +57,7 @@ unsigned long phys_to_virt(struct crash_
unsigned long paddr);
int xen_present(void);
+int xen_balloon_up(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);
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -1054,6 +1054,7 @@ int main(int argc, char *argv[])
@@ -1071,6 +1071,7 @@ int main(int argc, char *argv[])
int do_shutdown = 1;
int do_sync = 1;
int do_ifdown = 0;
@ -197,7 +187,7 @@ Disable ballooning before doing kexec.
int do_unload = 0;
int do_reuse_initrd = 0;
void *entry = 0;
@@ -1088,6 +1089,7 @@ int main(int argc, char *argv[])
@@ -1105,6 +1106,7 @@ int main(int argc, char *argv[])
do_shutdown = 0;
do_sync = 1;
do_ifdown = 1;
@ -205,7 +195,7 @@ Disable ballooning before doing kexec.
do_exec = 1;
break;
case OPT_LOAD:
@@ -1106,6 +1108,7 @@ int main(int argc, char *argv[])
@@ -1123,6 +1125,7 @@ int main(int argc, char *argv[])
do_shutdown = 0;
do_sync = 1;
do_ifdown = 1;
@ -213,7 +203,7 @@ Disable ballooning before doing kexec.
do_exec = 1;
break;
case OPT_LOAD_JUMP_BACK_HELPER:
@@ -1228,6 +1231,9 @@ int main(int argc, char *argv[])
@@ -1246,6 +1249,9 @@ int main(int argc, char *argv[])
if ((result == 0) && do_ifdown) {
ifdown();
}
@ -223,3 +213,12 @@ Disable ballooning before doing kexec.
if ((result == 0) && do_exec) {
result = my_exec();
}
--- a/kexec/kexec.h
+++ b/kexec/kexec.h
@@ -293,5 +293,6 @@ 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);
+int xen_balloon_up(void);
#endif /* KEXEC_H */

View File

@ -0,0 +1,27 @@
From: Tony Jones <tonyj@suse.de>
Subject: fix redefinition error for e820
Upstream: pending
Our xenctrl.h duplicates e820 definition.
---
kexec/arch/i386/crashdump-x86.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -41,12 +41,13 @@
#include "../../crashdump.h"
#include "kexec-x86.h"
#include "crashdump-x86.h"
-#include "x86-linux-setup.h"
#ifdef HAVE_LIBXENCTRL
#include <xenctrl.h>
#endif /* HAVE_LIBXENCTRL */
+#include "x86-linux-setup.h"
+
#include <x86/x86-linux.h>
extern struct arch_options_t arch_options;

View File

@ -18,9 +18,9 @@ Signed-off-by: Bernhard Walle <bwalle@suse.de>
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_version,
- AC_CHECK_LIB(xenctrl, xc_kexec_load, ,
+ AC_CHECK_LIB(xenctrl, xc_kexec_load,
+ [[LIBS="$LIBS -Wl,-Bstatic -lxenctrl -Wl,-Bdynamic"]]
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

View File

@ -1,3 +1,19 @@
-------------------------------------------------------------------
Wed Feb 5 17:53:56 UTC 2014 - tonyj@suse.com
- Update to version 2.0.5
Drop patch 'device-tree-buffer-overflows.patch' (upstream)
Drop patch '0001-kexec-fs2dt-fix-endianess-conversion.patch' (upstream)
- Rename aarch64 patch to 'kexec-tools-enable-aarch64.patch' and rebase to
version from Linaro git.
- Add 'kexec-tools-enable-aarch64-fixup.patch' to solve arm libfdt breakage
with Linaro patch.
- Enable ppc64le
- Refresh patches for context.
- Add following patches (pending upstream):
'kexec-tools-i386-bzimage_efi.patch' to fix i386 breakage.
'kexec-tools-xen-e820-redefinition.patch' to fix xen/820 breakage.
-------------------------------------------------------------------
Tue Feb 4 13:00:37 UTC 2014 - dmueller@suse.com

View File

@ -26,19 +26,20 @@ PreReq: %insserv_prereq %fillup_prereq
Summary: Tools for fast kernel loading
License: GPL-2.0+
Group: System/Kernel
Version: 2.0.4
Version: 2.0.5
Release: 0
Source: ftp://kernel.org/pub/linux/utils/kernel/kexec/%{name}-%{version}.tar.bz2
Source: ftp://kernel.org/pub/linux/utils/kernel/kexec/%{name}-%{version}.tar.xz
Source1: kexec-bootloader
Source2: kexec-bootloader.8.txt
Source3: kexec.init
Source4: %{name}-%{version}-rpmlintrc
Source4: %{name}-rpmlintrc
Patch1: %{name}-xen-static.patch
Patch2: %{name}-xen-balloon-up.patch
Patch3: %{name}-disable-test.patch
Patch4: kexec-aarch64.patch
Patch5: device-tree-buffer-overflows.patch
Patch6: 0001-kexec-fs2dt-fix-endianess-conversion.patch
Patch4: %{name}-enable-aarch64.patch
Patch5: %{name}-xen-e820-redefinition.patch
Patch6: %{name}-enable-aarch64-fixup.patch
Patch7: %{name}-i386-bzimage_efi.patch
Url: ftp://kernel.org/pub/linux/utils/kernel/kexec/%{name}-%{version}.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-build
#!BuildIgnore: fop
@ -51,12 +52,12 @@ BuildRequires: libxslt
%ifarch x86_64
BuildRequires: xen-devel
%endif
ExclusiveArch: aarch64 %ix86 x86_64 ia64 ppc ppc64 s390 s390x %arm sh mips mipsel
ExclusiveArch: ppc64le aarch64 %ix86 x86_64 ia64 ppc ppc64 s390 s390x %arm sh mips mipsel
%description
Kexec is a user space utility for loading another kernel and asking the
currently running kernel to do something with it. A currently running
kernel may be asked to start the loaded kernel on reboot, or to start
kkexec-tools-xen-e820-redefinition.patchernel may be asked to start the loaded kernel on reboot, or to start
the loaded kernel after it panics.
%prep
@ -65,8 +66,9 @@ the loaded kernel after it panics.
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5
%patch5 -p1
%patch6 -p1
%patch7 -p1
%build
# disable as-needed
@ -77,14 +79,12 @@ RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS | sed -e 's/-fstack-protector//')
%endif
autoreconf -f
CFLAGS=$RPM_OPT_FLAGS BUILD_CFLAGS=$RPM_OPT_FLAGS \
%configure \
%ifarch ppc
--host=powerpc64-suse-linux \
--build=powerpc64-suse-linux \
%configure --host=powerpc64-suse-linux --build=powerpc64-suse-linux
%else
%configure
%endif
# --libdir=/%_lib || true
make
# manpage
cp %{S:1} .
cp %{S:2} .
cp %{S:3} .
@ -117,7 +117,6 @@ ln -s %{_sbindir}/kexec $RPM_BUILD_ROOT/sbin
%{fillup_and_insserv -n kexec kexec}
%endif
#
#%preun
%postun
%if 0%{?suse_version} >= 1110