diff -Nru kexec-tools-2.0.10/debian/changelog kexec-tools-2.0.10/debian/changelog --- kexec-tools-2.0.10/debian/changelog 2016-04-05 09:14:27.000000000 +0000 +++ kexec-tools-2.0.10/debian/changelog 2017-02-10 02:15:56.000000000 +0000 @@ -1,3 +1,22 @@ +kexec-tools (1:2.0.10-1ubuntu2.1) xenial; urgency=medium + + * kexec: Increase the upper limit for RAM segments (LP: #1663400) + * Enable ARM64 support in kexec-tools (LP: #1659618) + - [PATCH] kexec: Add common device tree routines + - [PATCH] arm64: Add arm64 kexec support + - [PATCH] arm64: Add support for binary image files + - [PATCH] arm: include phys_to_virt.h and iomem.h in distribution + - [PATCH] arm64: Cleanup kexec Makefile + - [PATCH] arm64: Add missing kexec dist files + - [PATCH] arm64: Add support for additional relocations in the kexec + - [PATCH] arm64: Add support of R_AARCH64_PREL32 relocation in + - [PATCH] purgatory: Change default sha256 optimization to -O2 + - [PATCH] arm64: Fix initrd requierements + - [PATCH] kexec: phys_to_virt() must take unsigned long long + * Enable support for compressed kernels on ARM64 (LP: #1661363) + + -- Manoj Iyer Tue, 07 Feb 2017 12:52:41 -0600 + kexec-tools (1:2.0.10-1ubuntu2) xenial; urgency=medium * [PowerPC64] Fix failure in purgatory when compiled with gcc5 diff -Nru kexec-tools-2.0.10/debian/control kexec-tools-2.0.10/debian/control --- kexec-tools-2.0.10/debian/control 2016-03-25 15:55:53.000000000 +0000 +++ kexec-tools-2.0.10/debian/control 2017-02-10 02:12:22.000000000 +0000 @@ -4,11 +4,11 @@ Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Khalid Aziz -Build-Depends: debhelper (>= 7.0.0), dh-autoreconf, gnu-efi (>=3.0a-4)[ia64], libz-dev[ia64], po-debconf +Build-Depends: debhelper (>= 7.0.0), dh-autoreconf, gnu-efi (>=3.0a-4)[ia64], libz-dev [arm64 ia64], po-debconf Standards-Version: 3.9.6 Package: kexec-tools -Architecture: i386 amd64 ppc64el ppc64 powerpc powerpcspe ia64 s390x arm armel armhf sh4 mips mipsel +Architecture: i386 amd64 ppc64el ppc64 powerpc powerpcspe ia64 s390x arm arm64 armel armhf sh4 mips mipsel Depends: ${shlibs:Depends}, ${misc:Depends}, debconf Description: tools to support fast kexec reboots This package provides tools to load a kernel into memory and then @@ -17,7 +17,7 @@ Package: kexec-tools-udeb Section: debian-installer -Architecture: i386 amd64 ppc64el ppc64 powerpc powerpcspe ia64 s390x arm armel armhf sh4 mips mipsel +Architecture: i386 amd64 ppc64el ppc64 powerpc powerpcspe ia64 s390x arm arm64 armel armhf sh4 mips mipsel XC-Package-Type: udeb Depends: ${misc:Depends}, ${shlibs:Depends} Description: tools to support fast kexec reboots (udeb) diff -Nru kexec-tools-2.0.10/debian/patches/arm64-Add-arm64-kexec-support.patch kexec-tools-2.0.10/debian/patches/arm64-Add-arm64-kexec-support.patch --- kexec-tools-2.0.10/debian/patches/arm64-Add-arm64-kexec-support.patch 1970-01-01 00:00:00.000000000 +0000 +++ kexec-tools-2.0.10/debian/patches/arm64-Add-arm64-kexec-support.patch 2017-02-10 02:12:22.000000000 +0000 @@ -0,0 +1,1392 @@ +From 522df5f7217fda01ece3f6ac3e9987b0320c2bb0 Mon Sep 17 00:00:00 2001 +From: Geoff Levand +Date: Wed, 21 Sep 2016 18:14:25 +0000 +Subject: [PATCH] arm64: Add arm64 kexec support + +Add kexec reboot support for ARM64 platforms. + +Signed-off-by: Geoff Levand +Tested-By: Pratyush Anand +Tested-By: Matthias Brugger +Signed-off-by: Simon Horman +--- + configure.ac | 3 + + kexec/Makefile | 1 + + kexec/arch/arm64/Makefile | 40 +++ + kexec/arch/arm64/crashdump-arm64.c | 21 ++ + kexec/arch/arm64/crashdump-arm64.h | 12 + + kexec/arch/arm64/image-header.h | 146 ++++++++ + kexec/arch/arm64/include/arch/options.h | 39 ++ + kexec/arch/arm64/kexec-arm64.c | 615 ++++++++++++++++++++++++++++++++ + kexec/arch/arm64/kexec-arm64.h | 71 ++++ + kexec/arch/arm64/kexec-elf-arm64.c | 146 ++++++++ + kexec/arch/arm64/kexec-image-arm64.c | 41 +++ + kexec/kexec-syscall.h | 8 +- + purgatory/Makefile | 1 + + purgatory/arch/arm64/Makefile | 18 + + purgatory/arch/arm64/entry.S | 51 +++ + purgatory/arch/arm64/purgatory-arm64.c | 19 + + 16 files changed, 1230 insertions(+), 2 deletions(-) + create mode 100644 kexec/arch/arm64/Makefile + create mode 100644 kexec/arch/arm64/crashdump-arm64.c + create mode 100644 kexec/arch/arm64/crashdump-arm64.h + create mode 100644 kexec/arch/arm64/image-header.h + create mode 100644 kexec/arch/arm64/include/arch/options.h + create mode 100644 kexec/arch/arm64/kexec-arm64.c + create mode 100644 kexec/arch/arm64/kexec-arm64.h + create mode 100644 kexec/arch/arm64/kexec-elf-arm64.c + create mode 100644 kexec/arch/arm64/kexec-image-arm64.c + create mode 100644 purgatory/arch/arm64/Makefile + create mode 100644 purgatory/arch/arm64/entry.S + create mode 100644 purgatory/arch/arm64/purgatory-arm64.c + +Index: kexec-tools-2.0.10/configure.ac +=================================================================== +--- kexec-tools-2.0.10.orig/configure.ac ++++ kexec-tools-2.0.10/configure.ac +@@ -36,6 +36,9 @@ case $target_cpu in + ARCH="ppc64" + SUBARCH="LE" + ;; ++ aarch64* ) ++ ARCH="arm64" ++ ;; + arm* ) + ARCH="arm" + ;; +Index: kexec-tools-2.0.10/kexec/Makefile +=================================================================== +--- kexec-tools-2.0.10.orig/kexec/Makefile ++++ kexec-tools-2.0.10/kexec/Makefile +@@ -75,6 +75,7 @@ KEXEC_SRCS += $($(ARCH)_DT_OPS) + + 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 +Index: kexec-tools-2.0.10/kexec/arch/arm64/Makefile +=================================================================== +--- /dev/null ++++ kexec-tools-2.0.10/kexec/arch/arm64/Makefile +@@ -0,0 +1,40 @@ ++ ++arm64_FS2DT += kexec/fs2dt.c ++arm64_FS2DT_INCLUDE += -include $(srcdir)/kexec/arch/arm64/kexec-arm64.h \ ++ -include $(srcdir)/kexec/arch/arm64/crashdump-arm64.h ++ ++arm64_DT_OPS += kexec/dt-ops.c ++ ++arm64_CPPFLAGS += -I $(srcdir)/kexec/ ++ ++arm64_KEXEC_SRCS += \ ++ kexec/arch/arm64/kexec-arm64.c \ ++ kexec/arch/arm64/kexec-image-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 = ++arm64_PHYS_TO_VIRT = ++ ++dist += $(arm64_KEXEC_SRCS) \ ++ kexec/arch/arm64/Makefile \ ++ kexec/arch/arm64/kexec-arm64.h \ ++ kexec/arch/arm64/crashdump-arm64.h ++ ++ifdef HAVE_LIBFDT ++ ++LIBS += -lfdt ++ ++else ++ ++include $(srcdir)/kexec/libfdt/Makefile.libfdt ++ ++libfdt_SRCS += $(LIBFDT_SRCS:%=kexec/libfdt/%) ++ ++arm64_CPPFLAGS += -I$(srcdir)/kexec/libfdt ++ ++arm64_KEXEC_SRCS += $(libfdt_SRCS) ++ ++endif +Index: kexec-tools-2.0.10/kexec/arch/arm64/crashdump-arm64.c +=================================================================== +--- /dev/null ++++ kexec-tools-2.0.10/kexec/arch/arm64/crashdump-arm64.c +@@ -0,0 +1,21 @@ ++/* ++ * ARM64 crashdump. ++ */ ++ ++#define _GNU_SOURCE ++ ++#include ++#include ++ ++#include "kexec.h" ++#include "crashdump.h" ++#include "crashdump-arm64.h" ++#include "kexec-arm64.h" ++#include "kexec-elf.h" ++ ++struct memory_ranges usablemem_rgns = {}; ++ ++int is_crashkernel_mem_reserved(void) ++{ ++ return 0; ++} +Index: kexec-tools-2.0.10/kexec/arch/arm64/crashdump-arm64.h +=================================================================== +--- /dev/null ++++ kexec-tools-2.0.10/kexec/arch/arm64/crashdump-arm64.h +@@ -0,0 +1,12 @@ ++/* ++ * ARM64 crashdump. ++ */ ++ ++#if !defined(CRASHDUMP_ARM64_H) ++#define CRASHDUMP_ARM64_H ++ ++#include "kexec.h" ++ ++extern struct memory_ranges usablemem_rgns; ++ ++#endif +Index: kexec-tools-2.0.10/kexec/arch/arm64/image-header.h +=================================================================== +--- /dev/null ++++ kexec-tools-2.0.10/kexec/arch/arm64/image-header.h +@@ -0,0 +1,146 @@ ++/* ++ * ARM64 binary image header. ++ */ ++ ++#if !defined(__ARM64_IMAGE_HEADER_H) ++#define __ARM64_IMAGE_HEADER_H ++ ++#include ++#include ++ ++/** ++ * struct arm64_image_header - arm64 kernel image header. ++ * ++ * @pe_sig: Optional PE format 'MZ' signature. ++ * @branch_code: Reserved for instructions to branch to stext. ++ * @text_offset: The image load offset in LSB byte order. ++ * @image_size: An estimated size of the memory image size in LSB byte order. ++ * @flags: Bit flags in LSB byte order: ++ * Bit 0: Image byte order: 1=MSB. ++ * Bit 1-2: Kernel page size: 1=4K, 2=16K, 3=64K. ++ * Bit 3: Image placement: 0=low. ++ * @reserved_1: Reserved. ++ * @magic: Magic number, "ARM\x64". ++ * @pe_header: Optional offset to a PE format header. ++ **/ ++ ++struct arm64_image_header { ++ uint8_t pe_sig[2]; ++ uint16_t branch_code[3]; ++ uint64_t text_offset; ++ uint64_t image_size; ++ uint64_t flags; ++ uint64_t reserved_1[3]; ++ uint8_t magic[4]; ++ uint32_t pe_header; ++}; ++ ++static const uint8_t arm64_image_magic[4] = {'A', 'R', 'M', 0x64U}; ++static const uint8_t arm64_image_pe_sig[2] = {'M', 'Z'}; ++static const uint64_t arm64_image_flag_be = (1UL << 0); ++static const uint64_t arm64_image_flag_page_size = (3UL << 1); ++static const uint64_t arm64_image_flag_placement = (1UL << 3); ++ ++/** ++ * enum arm64_header_page_size ++ */ ++ ++enum arm64_header_page_size { ++ arm64_header_page_size_invalid = 0, ++ arm64_header_page_size_4k, ++ arm64_header_page_size_16k, ++ arm64_header_page_size_64k ++}; ++ ++/** ++ * arm64_header_check_magic - Helper to check the arm64 image header. ++ * ++ * Returns non-zero if header is OK. ++ */ ++ ++static inline int arm64_header_check_magic(const struct arm64_image_header *h) ++{ ++ if (!h) ++ return 0; ++ ++ return (h->magic[0] == arm64_image_magic[0] ++ && h->magic[1] == arm64_image_magic[1] ++ && h->magic[2] == arm64_image_magic[2] ++ && h->magic[3] == arm64_image_magic[3]); ++} ++ ++/** ++ * arm64_header_check_pe_sig - Helper to check the arm64 image header. ++ * ++ * Returns non-zero if 'MZ' signature is found. ++ */ ++ ++static inline int arm64_header_check_pe_sig(const struct arm64_image_header *h) ++{ ++ if (!h) ++ return 0; ++ ++ return (h->pe_sig[0] == arm64_image_pe_sig[0] ++ && h->pe_sig[1] == arm64_image_pe_sig[1]); ++} ++ ++/** ++ * arm64_header_check_msb - Helper to check the arm64 image header. ++ * ++ * Returns non-zero if the image was built as big endian. ++ */ ++ ++static inline int arm64_header_check_msb(const struct arm64_image_header *h) ++{ ++ if (!h) ++ return 0; ++ ++ return (le64toh(h->flags) & arm64_image_flag_be) >> 0; ++} ++ ++/** ++ * arm64_header_page_size ++ */ ++ ++static inline enum arm64_header_page_size arm64_header_page_size( ++ const struct arm64_image_header *h) ++{ ++ if (!h) ++ return 0; ++ ++ return (le64toh(h->flags) & arm64_image_flag_page_size) >> 1; ++} ++ ++/** ++ * arm64_header_placement ++ * ++ * Returns non-zero if the image has no physical placement restrictions. ++ */ ++ ++static inline int arm64_header_placement(const struct arm64_image_header *h) ++{ ++ if (!h) ++ return 0; ++ ++ return (le64toh(h->flags) & arm64_image_flag_placement) >> 3; ++} ++ ++static inline uint64_t arm64_header_text_offset( ++ const struct arm64_image_header *h) ++{ ++ if (!h) ++ return 0; ++ ++ return le64toh(h->text_offset); ++} ++ ++static inline uint64_t arm64_header_image_size( ++ const struct arm64_image_header *h) ++{ ++ if (!h) ++ return 0; ++ ++ return le64toh(h->image_size); ++} ++ ++#endif +Index: kexec-tools-2.0.10/kexec/arch/arm64/include/arch/options.h +=================================================================== +--- /dev/null ++++ kexec-tools-2.0.10/kexec/arch/arm64/include/arch/options.h +@@ -0,0 +1,39 @@ ++#if !defined(KEXEC_ARCH_ARM64_OPTIONS_H) ++#define KEXEC_ARCH_ARM64_OPTIONS_H ++ ++#define OPT_APPEND ((OPT_MAX)+0) ++#define OPT_DTB ((OPT_MAX)+1) ++#define OPT_INITRD ((OPT_MAX)+2) ++#define OPT_REUSE_CMDLINE ((OPT_MAX)+3) ++#define OPT_ARCH_MAX ((OPT_MAX)+4) ++ ++#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_INITRD }, \ ++ { "ramdisk", 1, NULL, OPT_INITRD }, \ ++ { "reuse-cmdline", 0, NULL, OPT_REUSE_CMDLINE }, \ ++ ++#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 ++ ++static const char arm64_opts_usage[] __attribute__ ((unused)) = ++" --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" ++" --reuse-cmdline Use kernel command line from running system.\n"; ++ ++struct arm64_opts { ++ const char *command_line; ++ const char *dtb; ++ const char *initrd; ++}; ++ ++extern struct arm64_opts arm64_opts; ++ ++#endif +Index: kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.c +=================================================================== +--- /dev/null ++++ kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.c +@@ -0,0 +1,615 @@ ++/* ++ * ARM64 kexec. ++ */ ++ ++#define _GNU_SOURCE ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "kexec.h" ++#include "kexec-arm64.h" ++#include "crashdump.h" ++#include "crashdump-arm64.h" ++#include "dt-ops.h" ++#include "fs2dt.h" ++#include "kexec-syscall.h" ++#include "arch/options.h" ++ ++/* Global varables the core kexec routines expect. */ ++ ++unsigned char reuse_initrd; ++ ++off_t initrd_base; ++off_t initrd_size; ++ ++const struct arch_map_entry arches[] = { ++ { "aarch64", KEXEC_ARCH_ARM64 }, ++ { "aarch64_be", KEXEC_ARCH_ARM64 }, ++ { NULL, 0 }, ++}; ++ ++struct file_type file_type[] = { ++ {"vmlinux", elf_arm64_probe, elf_arm64_load, elf_arm64_usage}, ++ {"Image", image_arm64_probe, image_arm64_load, image_arm64_usage}, ++}; ++ ++int file_types = sizeof(file_type) / sizeof(file_type[0]); ++ ++/* arm64 global varables. */ ++ ++struct arm64_opts arm64_opts; ++struct arm64_mem arm64_mem = { ++ .phys_offset = arm64_mem_ngv, ++ .vp_offset = arm64_mem_ngv, ++}; ++ ++uint64_t get_phys_offset(void) ++{ ++ assert(arm64_mem.phys_offset != arm64_mem_ngv); ++ return arm64_mem.phys_offset; ++} ++ ++uint64_t get_vp_offset(void) ++{ ++ assert(arm64_mem.vp_offset != arm64_mem_ngv); ++ return arm64_mem.vp_offset; ++} ++ ++/** ++ * arm64_process_image_header - Process the arm64 image header. ++ * ++ * Make a guess that KERNEL_IMAGE_SIZE will be enough for older kernels. ++ */ ++ ++int arm64_process_image_header(const struct arm64_image_header *h) ++{ ++#if !defined(KERNEL_IMAGE_SIZE) ++# define KERNEL_IMAGE_SIZE MiB(16) ++#endif ++ ++ if (!arm64_header_check_magic(h)) ++ return -EFAILED; ++ ++ if (h->image_size) { ++ arm64_mem.text_offset = arm64_header_text_offset(h); ++ arm64_mem.image_size = arm64_header_image_size(h); ++ } else { ++ /* For 3.16 and older kernels. */ ++ arm64_mem.text_offset = 0x80000; ++ arm64_mem.image_size = KERNEL_IMAGE_SIZE; ++ fprintf(stderr, ++ "kexec: %s: Warning: Kernel image size set to %lu MiB.\n" ++ " Please verify compatability with lodaed kernel.\n", ++ __func__, KERNEL_IMAGE_SIZE / 1024UL / 1024UL); ++ } ++ ++ return 0; ++} ++ ++void arch_usage(void) ++{ ++ printf(arm64_opts_usage); ++} ++ ++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; ++ char *cmdline = NULL; ++ const char *append = NULL; ++ ++ for (opt = 0; opt != -1; ) { ++ opt = getopt_long(argc, argv, short_options, options, 0); ++ ++ switch (opt) { ++ case OPT_APPEND: ++ append = optarg; ++ break; ++ case OPT_REUSE_CMDLINE: ++ cmdline = get_command_line(); ++ break; ++ case OPT_DTB: ++ arm64_opts.dtb = optarg; ++ break; ++ case OPT_INITRD: ++ arm64_opts.initrd = optarg; ++ break; ++ case OPT_PANIC: ++ die("load-panic (-p) not supported"); ++ break; ++ default: ++ break; /* Ignore core and unknown options. */ ++ } ++ } ++ ++ arm64_opts.command_line = concat_cmdline(cmdline, append); ++ ++ dbgprintf("%s:%d: command_line: %s\n", __func__, __LINE__, ++ arm64_opts.command_line); ++ dbgprintf("%s:%d: initrd: %s\n", __func__, __LINE__, ++ arm64_opts.initrd); ++ dbgprintf("%s:%d: dtb: %s\n", __func__, __LINE__, arm64_opts.dtb); ++ ++ return 0; ++} ++ ++/** ++ * struct dtb - Info about a binary device tree. ++ * ++ * @buf: Device tree data. ++ * @size: Device tree data size. ++ * @name: Shorthand name of this dtb for messages. ++ * @path: Filesystem path. ++ */ ++ ++struct dtb { ++ char *buf; ++ off_t size; ++ const char *name; ++ const char *path; ++}; ++ ++/** ++ * dump_reservemap - Dump the dtb's reservemap. ++ */ ++ ++static void dump_reservemap(const struct dtb *dtb) ++{ ++ int i; ++ ++ for (i = 0; ; i++) { ++ uint64_t address; ++ uint64_t size; ++ ++ fdt_get_mem_rsv(dtb->buf, i, &address, &size); ++ ++ if (!size) ++ break; ++ ++ dbgprintf("%s: %s {%" PRIx64 ", %" PRIx64 "}\n", __func__, ++ dtb->name, address, size); ++ } ++} ++ ++/** ++ * set_bootargs - Set the dtb's bootargs. ++ */ ++ ++static int set_bootargs(struct dtb *dtb, const char *command_line) ++{ ++ int result; ++ ++ if (!command_line || !command_line[0]) ++ return 0; ++ ++ result = dtb_set_bootargs(&dtb->buf, &dtb->size, command_line); ++ ++ if (result) { ++ fprintf(stderr, ++ "kexec: Set device tree bootargs failed.\n"); ++ return -EFAILED; ++ } ++ ++ return 0; ++} ++ ++/** ++ * read_proc_dtb - Read /proc/device-tree. ++ */ ++ ++static int read_proc_dtb(struct dtb *dtb) ++{ ++ int result; ++ struct stat s; ++ static const char path[] = "/proc/device-tree"; ++ ++ result = stat(path, &s); ++ ++ if (result) { ++ dbgprintf("%s: %s\n", __func__, strerror(errno)); ++ return -EFAILED; ++ } ++ ++ dtb->path = path; ++ create_flatten_tree((char **)&dtb->buf, &dtb->size, NULL); ++ ++ return 0; ++} ++ ++/** ++ * read_sys_dtb - Read /sys/firmware/fdt. ++ */ ++ ++static int read_sys_dtb(struct dtb *dtb) ++{ ++ int result; ++ struct stat s; ++ static const char path[] = "/sys/firmware/fdt"; ++ ++ result = stat(path, &s); ++ ++ if (result) { ++ dbgprintf("%s: %s\n", __func__, strerror(errno)); ++ return -EFAILED; ++ } ++ ++ dtb->path = path; ++ dtb->buf = slurp_file(path, &dtb->size); ++ ++ return 0; ++} ++ ++/** ++ * read_1st_dtb - Read the 1st stage kernel's dtb. ++ */ ++ ++static int read_1st_dtb(struct dtb *dtb) ++{ ++ int result; ++ ++ dtb->name = "dtb_sys"; ++ result = read_sys_dtb(dtb); ++ ++ if (!result) ++ goto on_success; ++ ++ dtb->name = "dtb_proc"; ++ result = read_proc_dtb(dtb); ++ ++ if (!result) ++ goto on_success; ++ ++ dbgprintf("%s: not found\n", __func__); ++ return -EFAILED; ++ ++on_success: ++ dbgprintf("%s: found %s\n", __func__, dtb->path); ++ return 0; ++} ++ ++/** ++ * setup_2nd_dtb - Setup the 2nd stage kernel's dtb. ++ */ ++ ++static int setup_2nd_dtb(struct dtb *dtb, char *command_line) ++{ ++ int result; ++ ++ result = fdt_check_header(dtb->buf); ++ ++ if (result) { ++ fprintf(stderr, "kexec: Invalid 2nd device tree.\n"); ++ return -EFAILED; ++ } ++ ++ result = set_bootargs(dtb, command_line); ++ ++ dump_reservemap(dtb); ++ ++ return result; ++} ++ ++unsigned long arm64_locate_kernel_segment(struct kexec_info *info) ++{ ++ unsigned long hole; ++ ++ hole = locate_hole(info, ++ arm64_mem.text_offset + arm64_mem.image_size, ++ MiB(2), 0, ULONG_MAX, 1); ++ ++ if (hole == ULONG_MAX) ++ dbgprintf("%s: locate_hole failed\n", __func__); ++ ++ return hole; ++} ++ ++/** ++ * arm64_load_other_segments - Prepare the dtb, initrd and purgatory segments. ++ */ ++ ++int arm64_load_other_segments(struct kexec_info *info, ++ unsigned long image_base) ++{ ++ int result; ++ unsigned long dtb_base; ++ unsigned long hole_min; ++ unsigned long hole_max; ++ char *initrd_buf = NULL; ++ struct dtb dtb; ++ char command_line[COMMAND_LINE_SIZE] = ""; ++ ++ if (arm64_opts.command_line) { ++ strncpy(command_line, arm64_opts.command_line, ++ sizeof(command_line)); ++ command_line[sizeof(command_line) - 1] = 0; ++ } ++ ++ if (arm64_opts.dtb) { ++ dtb.name = "dtb_user"; ++ dtb.buf = slurp_file(arm64_opts.dtb, &dtb.size); ++ } else { ++ result = read_1st_dtb(&dtb); ++ ++ if (result) { ++ fprintf(stderr, ++ "kexec: Error: No device tree available.\n"); ++ return -EFAILED; ++ } ++ } ++ ++ result = setup_2nd_dtb(&dtb, command_line); ++ ++ if (result) ++ return -EFAILED; ++ ++ /* Put the other segments after the image. */ ++ ++ hole_min = image_base + arm64_mem.image_size; ++ hole_max = ULONG_MAX; ++ ++ if (arm64_opts.initrd) { ++ initrd_buf = slurp_file(arm64_opts.initrd, &initrd_size); ++ ++ if (!initrd_buf) ++ fprintf(stderr, "kexec: Empty ramdisk file.\n"); ++ else { ++ /* ++ * Put the initrd after the kernel. As specified in ++ * booting.txt, align to 1 GiB. ++ */ ++ ++ initrd_base = add_buffer_phys_virt(info, initrd_buf, ++ initrd_size, initrd_size, GiB(1), ++ hole_min, hole_max, 1, 0); ++ ++ /* initrd_base is valid if we got here. */ ++ ++ dbgprintf("initrd: base %lx, size %lxh (%ld)\n", ++ initrd_base, initrd_size, initrd_size); ++ ++ /* Check size limit as specified in booting.txt. */ ++ ++ if (initrd_base - image_base + initrd_size > GiB(32)) { ++ fprintf(stderr, "kexec: Error: image + initrd too big.\n"); ++ return -EFAILED; ++ } ++ ++ result = dtb_set_initrd((char **)&dtb.buf, ++ &dtb.size, initrd_base, ++ initrd_base + initrd_size); ++ ++ if (result) ++ return -EFAILED; ++ } ++ } ++ ++ /* Check size limit as specified in booting.txt. */ ++ ++ if (dtb.size > MiB(2)) { ++ fprintf(stderr, "kexec: Error: dtb too big.\n"); ++ return -EFAILED; ++ } ++ ++ dtb_base = add_buffer_phys_virt(info, dtb.buf, dtb.size, dtb.size, ++ 0, hole_min, hole_max, 1, 0); ++ ++ /* dtb_base is valid if we got here. */ ++ ++ dbgprintf("dtb: base %lx, size %lxh (%ld)\n", dtb_base, dtb.size, ++ dtb.size); ++ ++ elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, ++ hole_min, hole_max, 1, 0); ++ ++ info->entry = (void *)elf_rel_get_addr(&info->rhdr, "purgatory_start"); ++ ++ elf_rel_set_symbol(&info->rhdr, "arm64_kernel_entry", &image_base, ++ sizeof(image_base)); ++ ++ elf_rel_set_symbol(&info->rhdr, "arm64_dtb_addr", &dtb_base, ++ sizeof(dtb_base)); ++ ++ return 0; ++} ++ ++/** ++ * virt_to_phys - For processing elf file values. ++ */ ++ ++unsigned long virt_to_phys(unsigned long v) ++{ ++ unsigned long p; ++ ++ p = v - get_vp_offset() + get_phys_offset(); ++ ++ return p; ++} ++ ++/** ++ * phys_to_virt - For crashdump setup. ++ */ ++ ++unsigned long phys_to_virt(struct crash_elf_info *elf_info, ++ unsigned long long p) ++{ ++ unsigned long v; ++ ++ v = p - get_phys_offset() + elf_info->page_offset; ++ ++ return v; ++} ++ ++/** ++ * add_segment - Use virt_to_phys when loading elf files. ++ */ ++ ++void add_segment(struct kexec_info *info, const void *buf, size_t bufsz, ++ unsigned long base, size_t memsz) ++{ ++ add_segment_phys_virt(info, buf, bufsz, base, memsz, 1); ++} ++ ++/** ++ * get_memory_ranges_iomem_cb - Helper for get_memory_ranges_iomem. ++ */ ++ ++static int get_memory_ranges_iomem_cb(void *data, int nr, char *str, ++ unsigned long long base, unsigned long long length) ++{ ++ struct memory_range *r; ++ ++ if (nr >= KEXEC_SEGMENT_MAX) ++ return -1; ++ ++ r = (struct memory_range *)data + nr; ++ r->type = RANGE_RAM; ++ r->start = base; ++ r->end = base + length - 1; ++ ++ set_phys_offset(r->start); ++ ++ dbgprintf("%s: %016llx - %016llx : %s", __func__, r->start, ++ r->end, str); ++ ++ return 0; ++} ++ ++/** ++ * get_memory_ranges_iomem - Try to get the memory ranges from /proc/iomem. ++ */ ++ ++static int get_memory_ranges_iomem(struct memory_range *array, ++ unsigned int *count) ++{ ++ *count = kexec_iomem_for_each_line("System RAM\n", ++ get_memory_ranges_iomem_cb, array); ++ ++ if (!*count) { ++ dbgprintf("%s: failed: No RAM found.\n", __func__); ++ return -EFAILED; ++ } ++ ++ return 0; ++} ++ ++/** ++ * get_memory_ranges - Try to get the memory ranges some how. ++ */ ++ ++int get_memory_ranges(struct memory_range **range, int *ranges, ++ unsigned long kexec_flags) ++{ ++ static struct memory_range array[KEXEC_SEGMENT_MAX]; ++ unsigned int count; ++ int result; ++ ++ result = get_memory_ranges_iomem(array, &count); ++ ++ *range = result ? NULL : array; ++ *ranges = result ? 0 : count; ++ ++ return result; ++} ++ ++int arch_compat_trampoline(struct kexec_info *info) ++{ ++ return 0; ++} ++ ++int machine_verify_elf_rel(struct mem_ehdr *ehdr) ++{ ++ return (ehdr->e_machine == EM_AARCH64); ++} ++ ++void machine_apply_elf_rel(struct mem_ehdr *ehdr, struct mem_sym *UNUSED(sym), ++ unsigned long r_type, void *ptr, unsigned long address, ++ unsigned long value) ++{ ++#if !defined(R_AARCH64_ABS64) ++# define R_AARCH64_ABS64 257 ++#endif ++ ++#if !defined(R_AARCH64_LD_PREL_LO19) ++# define R_AARCH64_LD_PREL_LO19 273 ++#endif ++ ++#if !defined(R_AARCH64_ADR_PREL_LO21) ++# define R_AARCH64_ADR_PREL_LO21 274 ++#endif ++ ++#if !defined(R_AARCH64_JUMP26) ++# define R_AARCH64_JUMP26 282 ++#endif ++ ++#if !defined(R_AARCH64_CALL26) ++# define R_AARCH64_CALL26 283 ++#endif ++ ++ uint64_t *loc64; ++ uint32_t *loc32; ++ uint64_t *location = (uint64_t *)ptr; ++ uint64_t data = *location; ++ const char *type = NULL; ++ ++ switch(r_type) { ++ case R_AARCH64_ABS64: ++ type = "ABS64"; ++ loc64 = ptr; ++ *loc64 = cpu_to_elf64(ehdr, elf64_to_cpu(ehdr, *loc64) + value); ++ break; ++ case R_AARCH64_LD_PREL_LO19: ++ type = "LD_PREL_LO19"; ++ loc32 = ptr; ++ *loc32 = cpu_to_le32(le32_to_cpu(*loc32) ++ + (((value - address) << 3) & 0xffffe0)); ++ break; ++ case R_AARCH64_ADR_PREL_LO21: ++ if (value & 3) ++ die("%s: ERROR Unaligned value: %lx\n", __func__, ++ value); ++ type = "ADR_PREL_LO21"; ++ loc32 = ptr; ++ *loc32 = cpu_to_le32(le32_to_cpu(*loc32) ++ + (((value - address) << 3) & 0xffffe0)); ++ break; ++ case R_AARCH64_JUMP26: ++ type = "JUMP26"; ++ loc32 = ptr; ++ *loc32 = cpu_to_le32(le32_to_cpu(*loc32) ++ + (((value - address) >> 2) & 0x3ffffff)); ++ break; ++ case R_AARCH64_CALL26: ++ type = "CALL26"; ++ loc32 = ptr; ++ *loc32 = cpu_to_le32(le32_to_cpu(*loc32) ++ + (((value - address) >> 2) & 0x3ffffff)); ++ break; ++ default: ++ die("%s: ERROR Unknown type: %lu\n", __func__, r_type); ++ break; ++ } ++ ++ dbgprintf("%s: %s %016lx->%016lx\n", __func__, type, data, *location); ++} ++ ++void arch_reuse_initrd(void) ++{ ++ reuse_initrd = 1; ++} ++ ++void arch_update_purgatory(struct kexec_info *UNUSED(info)) ++{ ++} +Index: kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.h +=================================================================== +--- /dev/null ++++ kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.h +@@ -0,0 +1,71 @@ ++/* ++ * ARM64 kexec. ++ */ ++ ++#if !defined(KEXEC_ARM64_H) ++#define KEXEC_ARM64_H ++ ++#include ++#include ++ ++#include "image-header.h" ++#include "kexec.h" ++ ++#define KEXEC_SEGMENT_MAX 16 ++ ++#define BOOT_BLOCK_VERSION 17 ++#define BOOT_BLOCK_LAST_COMP_VERSION 16 ++#define COMMAND_LINE_SIZE 512 ++ ++#define KiB(x) ((x) * 1024UL) ++#define MiB(x) (KiB(x) * 1024UL) ++#define GiB(x) (MiB(x) * 1024UL) ++ ++int elf_arm64_probe(const char *kernel_buf, off_t kernel_size); ++int elf_arm64_load(int argc, char **argv, const char *kernel_buf, ++ off_t kernel_size, struct kexec_info *info); ++void elf_arm64_usage(void); ++ ++int image_arm64_probe(const char *kernel_buf, off_t kernel_size); ++int image_arm64_load(int argc, char **argv, const char *kernel_buf, ++ off_t kernel_size, struct kexec_info *info); ++void image_arm64_usage(void); ++ ++off_t initrd_base; ++off_t initrd_size; ++ ++/** ++ * struct arm64_mem - Memory layout info. ++ */ ++ ++struct arm64_mem { ++ uint64_t phys_offset; ++ uint64_t text_offset; ++ uint64_t image_size; ++ uint64_t vp_offset; ++}; ++ ++#define arm64_mem_ngv UINT64_MAX ++struct arm64_mem arm64_mem; ++ ++uint64_t get_phys_offset(void); ++uint64_t get_vp_offset(void); ++ ++static inline void reset_vp_offset(void) ++{ ++ arm64_mem.vp_offset = arm64_mem_ngv; ++} ++ ++static inline void set_phys_offset(uint64_t v) ++{ ++ if (arm64_mem.phys_offset == arm64_mem_ngv ++ || v < arm64_mem.phys_offset) ++ arm64_mem.phys_offset = v; ++} ++ ++int arm64_process_image_header(const struct arm64_image_header *h); ++unsigned long arm64_locate_kernel_segment(struct kexec_info *info); ++int arm64_load_other_segments(struct kexec_info *info, ++ unsigned long image_base); ++ ++#endif +Index: kexec-tools-2.0.10/kexec/arch/arm64/kexec-elf-arm64.c +=================================================================== +--- /dev/null ++++ kexec-tools-2.0.10/kexec/arch/arm64/kexec-elf-arm64.c +@@ -0,0 +1,146 @@ ++/* ++ * ARM64 kexec elf support. ++ */ ++ ++#define _GNU_SOURCE ++ ++#include ++#include ++#include ++#include ++ ++#include "kexec-arm64.h" ++#include "kexec-elf.h" ++#include "kexec-syscall.h" ++ ++int elf_arm64_probe(const char *kernel_buf, off_t kernel_size) ++{ ++ struct mem_ehdr ehdr; ++ int result; ++ ++ result = build_elf_exec_info(kernel_buf, kernel_size, &ehdr, 0); ++ ++ if (result < 0) { ++ dbgprintf("%s: Not an ELF executable.\n", __func__); ++ goto on_exit; ++ } ++ ++ if (ehdr.e_machine != EM_AARCH64) { ++ dbgprintf("%s: Not an AARCH64 ELF executable.\n", __func__); ++ result = -1; ++ goto on_exit; ++ } ++ ++ result = 0; ++on_exit: ++ free_elf_info(&ehdr); ++ return result; ++} ++ ++int elf_arm64_load(int argc, char **argv, const char *kernel_buf, ++ off_t kernel_size, struct kexec_info *info) ++{ ++ const struct arm64_image_header *header = NULL; ++ unsigned long kernel_segment; ++ struct mem_ehdr ehdr; ++ int result; ++ int i; ++ ++ if (info->kexec_flags & KEXEC_ON_CRASH) { ++ fprintf(stderr, "kexec: kdump not yet supported on arm64\n"); ++ return -EFAILED; ++ } ++ ++ result = build_elf_exec_info(kernel_buf, kernel_size, &ehdr, 0); ++ ++ if (result < 0) { ++ dbgprintf("%s: build_elf_exec_info failed\n", __func__); ++ goto exit; ++ } ++ ++ /* Find and process the arm64 image header. */ ++ ++ for (i = 0; i < ehdr.e_phnum; i++) { ++ struct mem_phdr *phdr = &ehdr.e_phdr[i]; ++ unsigned long header_offset; ++ ++ if (phdr->p_type != PT_LOAD) ++ continue; ++ ++ /* ++ * When CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET=y the image header ++ * could be offset in the elf segment. The linker script sets ++ * ehdr.e_entry to the start of text. ++ */ ++ ++ header_offset = ehdr.e_entry - phdr->p_vaddr; ++ ++ header = (const struct arm64_image_header *)( ++ kernel_buf + phdr->p_offset + header_offset); ++ ++ if (!arm64_process_image_header(header)) { ++ dbgprintf("%s: e_entry: %016llx\n", __func__, ++ ehdr.e_entry); ++ dbgprintf("%s: p_vaddr: %016llx\n", __func__, ++ phdr->p_vaddr); ++ dbgprintf("%s: header_offset: %016lx\n", __func__, ++ header_offset); ++ ++ break; ++ } ++ } ++ ++ if (i == ehdr.e_phnum) { ++ dbgprintf("%s: Valid arm64 header not found\n", __func__); ++ result = -EFAILED; ++ goto exit; ++ } ++ ++ kernel_segment = arm64_locate_kernel_segment(info); ++ ++ if (kernel_segment == ULONG_MAX) { ++ dbgprintf("%s: Kernel segment is not allocated\n", __func__); ++ result = -EFAILED; ++ goto exit; ++ } ++ ++ arm64_mem.vp_offset = _ALIGN_DOWN(ehdr.e_entry, MiB(2)); ++ arm64_mem.vp_offset -= kernel_segment - get_phys_offset(); ++ ++ dbgprintf("%s: kernel_segment: %016lx\n", __func__, kernel_segment); ++ dbgprintf("%s: text_offset: %016lx\n", __func__, ++ arm64_mem.text_offset); ++ dbgprintf("%s: image_size: %016lx\n", __func__, ++ arm64_mem.image_size); ++ dbgprintf("%s: phys_offset: %016lx\n", __func__, ++ arm64_mem.phys_offset); ++ dbgprintf("%s: vp_offset: %016lx\n", __func__, ++ arm64_mem.vp_offset); ++ dbgprintf("%s: PE format: %s\n", __func__, ++ (arm64_header_check_pe_sig(header) ? "yes" : "no")); ++ ++ /* load the kernel */ ++ result = elf_exec_load(&ehdr, info); ++ ++ if (result) { ++ dbgprintf("%s: elf_exec_load failed\n", __func__); ++ goto exit; ++ } ++ ++ result = arm64_load_other_segments(info, kernel_segment ++ + arm64_mem.text_offset); ++ ++exit: ++ reset_vp_offset(); ++ free_elf_info(&ehdr); ++ if (result) ++ fprintf(stderr, "kexec: Bad elf image file, load failed.\n"); ++ return result; ++} ++ ++void elf_arm64_usage(void) ++{ ++ printf( ++" An ARM64 ELF image, big or little endian.\n" ++" Typically vmlinux or a stripped version of vmlinux.\n\n"); ++} +Index: kexec-tools-2.0.10/kexec/arch/arm64/kexec-image-arm64.c +=================================================================== +--- /dev/null ++++ kexec-tools-2.0.10/kexec/arch/arm64/kexec-image-arm64.c +@@ -0,0 +1,41 @@ ++/* ++ * ARM64 kexec binary image support. ++ */ ++ ++#define _GNU_SOURCE ++#include "kexec-arm64.h" ++ ++int image_arm64_probe(const char *kernel_buf, off_t kernel_size) ++{ ++ const struct arm64_image_header *h; ++ ++ if (kernel_size < sizeof(struct arm64_image_header)) { ++ dbgprintf("%s: No arm64 image header.\n", __func__); ++ return -1; ++ } ++ ++ h = (const struct arm64_image_header *)(kernel_buf); ++ ++ if (!arm64_header_check_magic(h)) { ++ dbgprintf("%s: Bad arm64 image header.\n", __func__); ++ return -1; ++ } ++ ++ fprintf(stderr, "kexec: ARM64 binary image files are currently NOT SUPPORTED.\n"); ++ return -1; ++} ++ ++int image_arm64_load(int argc, char **argv, const char *kernel_buf, ++ off_t kernel_size, struct kexec_info *info) ++{ ++ return -1; ++} ++ ++void image_arm64_usage(void) ++{ ++ printf( ++" An ARM64 binary image, compressed or not, big or little endian.\n" ++" Typically an Image, Image.gz or Image.lzma file.\n\n"); ++ printf( ++" ARM64 binary image files are currently NOT SUPPORTED.\n\n"); ++} +Index: kexec-tools-2.0.10/kexec/kexec-syscall.h +=================================================================== +--- kexec-tools-2.0.10.orig/kexec/kexec-syscall.h ++++ kexec-tools-2.0.10/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 +@@ -108,6 +108,7 @@ static inline long kexec_file_load(int k + #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_S390 (22 << 16) + #define KEXEC_ARCH_SH (42 << 16) + #define KEXEC_ARCH_MIPS_LE (10 << 16) +@@ -153,5 +154,8 @@ static inline long kexec_file_load(int k + #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 */ +Index: kexec-tools-2.0.10/purgatory/Makefile +=================================================================== +--- kexec-tools-2.0.10.orig/purgatory/Makefile ++++ kexec-tools-2.0.10/purgatory/Makefile +@@ -19,6 +19,7 @@ dist += purgatory/Makefile $(PURGATORY_S + + include $(srcdir)/purgatory/arch/alpha/Makefile + include $(srcdir)/purgatory/arch/arm/Makefile ++include $(srcdir)/purgatory/arch/arm64/Makefile + include $(srcdir)/purgatory/arch/i386/Makefile + include $(srcdir)/purgatory/arch/ia64/Makefile + include $(srcdir)/purgatory/arch/mips/Makefile +Index: kexec-tools-2.0.10/purgatory/arch/arm64/Makefile +=================================================================== +--- /dev/null ++++ kexec-tools-2.0.10/purgatory/arch/arm64/Makefile +@@ -0,0 +1,18 @@ ++ ++arm64_PURGATORY_EXTRA_CFLAGS = \ ++ -mcmodel=large \ ++ -fno-stack-protector \ ++ -fno-asynchronous-unwind-tables \ ++ -Wundef \ ++ -Werror-implicit-function-declaration \ ++ -Wdeclaration-after-statement \ ++ -Werror=implicit-int \ ++ -Werror=strict-prototypes ++ ++arm64_PURGATORY_SRCS += \ ++ purgatory/arch/arm64/entry.S \ ++ purgatory/arch/arm64/purgatory-arm64.c ++ ++dist += \ ++ $(arm64_PURGATORY_SRCS) \ ++ purgatory/arch/arm64/Makefile +Index: kexec-tools-2.0.10/purgatory/arch/arm64/entry.S +=================================================================== +--- /dev/null ++++ kexec-tools-2.0.10/purgatory/arch/arm64/entry.S +@@ -0,0 +1,51 @@ ++/* ++ * ARM64 purgatory. ++ */ ++ ++.macro size, sym:req ++ .size \sym, . - \sym ++.endm ++ ++.text ++ ++.globl purgatory_start ++purgatory_start: ++ ++ adr x19, .Lstack ++ mov sp, x19 ++ ++ bl purgatory ++ ++ /* Start new image. */ ++ ldr x17, arm64_kernel_entry ++ ldr x0, arm64_dtb_addr ++ mov x1, xzr ++ mov x2, xzr ++ mov x3, xzr ++ br x17 ++ ++size purgatory_start ++ ++.ltorg ++ ++.align 4 ++ .rept 256 ++ .quad 0 ++ .endr ++.Lstack: ++ ++.data ++ ++.align 3 ++ ++.globl arm64_kernel_entry ++arm64_kernel_entry: ++ .quad 0 ++size arm64_kernel_entry ++ ++.globl arm64_dtb_addr ++arm64_dtb_addr: ++ .quad 0 ++size arm64_dtb_addr ++ ++.end +\ No newline at end of file +Index: kexec-tools-2.0.10/purgatory/arch/arm64/purgatory-arm64.c +=================================================================== +--- /dev/null ++++ kexec-tools-2.0.10/purgatory/arch/arm64/purgatory-arm64.c +@@ -0,0 +1,19 @@ ++/* ++ * ARM64 purgatory. ++ */ ++ ++#include ++#include ++ ++void putchar(int ch) ++{ ++ /* Nothing for now */ ++} ++ ++void post_verification_setup_arch(void) ++{ ++} ++ ++void setup_arch(void) ++{ ++} diff -Nru kexec-tools-2.0.10/debian/patches/arm64-Add-missing-kexec-dist-files.patch kexec-tools-2.0.10/debian/patches/arm64-Add-missing-kexec-dist-files.patch --- kexec-tools-2.0.10/debian/patches/arm64-Add-missing-kexec-dist-files.patch 1970-01-01 00:00:00.000000000 +0000 +++ kexec-tools-2.0.10/debian/patches/arm64-Add-missing-kexec-dist-files.patch 2017-02-10 02:12:22.000000000 +0000 @@ -0,0 +1,26 @@ +From e345e27417db00a9e754ca0ca14b2ec87d0552f7 Mon Sep 17 00:00:00 2001 +From: Geoff Levand +Date: Mon, 10 Oct 2016 21:22:59 +0000 +Subject: [PATCH] arm64: Add missing kexec dist files + +Signed-off-by: Geoff Levand +Reviewed-by: Matthias Brugger +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/Makefile | 2 ++ + 1 file changed, 2 insertions(+) + +Index: kexec-tools-2.0.10/kexec/arch/arm64/Makefile +=================================================================== +--- kexec-tools-2.0.10.orig/kexec/arch/arm64/Makefile ++++ kexec-tools-2.0.10/kexec/arch/arm64/Makefile +@@ -20,7 +20,9 @@ arm64_VIRT_TO_PHYS = + arm64_PHYS_TO_VIRT = + + dist += $(arm64_KEXEC_SRCS) \ ++ kexec/arch/arm64/include/arch/options.h \ + kexec/arch/arm64/crashdump-arm64.h \ ++ kexec/arch/arm64/image-header.h \ + kexec/arch/arm64/kexec-arm64.h \ + kexec/arch/arm64/Makefile + diff -Nru kexec-tools-2.0.10/debian/patches/arm64-Add-support-for-additional-relocations-in-the-.patch kexec-tools-2.0.10/debian/patches/arm64-Add-support-for-additional-relocations-in-the-.patch --- kexec-tools-2.0.10/debian/patches/arm64-Add-support-for-additional-relocations-in-the-.patch 1970-01-01 00:00:00.000000000 +0000 +++ kexec-tools-2.0.10/debian/patches/arm64-Add-support-for-additional-relocations-in-the-.patch 2017-02-10 02:12:22.000000000 +0000 @@ -0,0 +1,94 @@ +From c743758d77b8a935fca7d72ecd6aa61300eb96da Mon Sep 17 00:00:00 2001 +From: Catalin Marinas +Date: Thu, 20 Oct 2016 11:43:31 +0100 +Subject: [PATCH] arm64: Add support for additional relocations in the kexec + purgatory code + +When compiling the kexec-tools with gcc6, the following additional +reolcations are generated in the purgatory.ro file: + +R_AARCH64_ADR_PREL_PG_HI21 +R_AARCH64_ADD_ABS_LO12_NC +R_AARCH64_LDST64_ABS_LO12_NC + +This patch modifies the arm64 machine_apply_elf_rel() function to handle +these relocations. + +Signed-off-by: Catalin Marinas +Reviewed-by: Geoff Levand +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/kexec-arm64.c | 35 +++++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +Index: kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.c +=================================================================== +--- kexec-tools-2.0.10.orig/kexec/arch/arm64/kexec-arm64.c ++++ kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.c +@@ -550,6 +550,14 @@ void machine_apply_elf_rel(struct mem_eh + # define R_AARCH64_ADR_PREL_LO21 274 + #endif + ++#if !defined(R_AARCH64_ADR_PREL_PG_HI21) ++# define R_AARCH64_ADR_PREL_PG_HI21 275 ++#endif ++ ++#if !defined(R_AARCH64_ADD_ABS_LO12_NC) ++# define R_AARCH64_ADD_ABS_LO12_NC 277 ++#endif ++ + #if !defined(R_AARCH64_JUMP26) + # define R_AARCH64_JUMP26 282 + #endif +@@ -558,10 +566,15 @@ void machine_apply_elf_rel(struct mem_eh + # define R_AARCH64_CALL26 283 + #endif + ++#if !defined(R_AARCH64_LDST64_ABS_LO12_NC) ++# define R_AARCH64_LDST64_ABS_LO12_NC 286 ++#endif ++ + uint64_t *loc64; + uint32_t *loc32; + uint64_t *location = (uint64_t *)ptr; + uint64_t data = *location; ++ uint64_t imm; + const char *type = NULL; + + switch(r_type) { +@@ -585,6 +598,19 @@ void machine_apply_elf_rel(struct mem_eh + *loc32 = cpu_to_le32(le32_to_cpu(*loc32) + + (((value - address) << 3) & 0xffffe0)); + break; ++ case R_AARCH64_ADR_PREL_PG_HI21: ++ type = "ADR_PREL_PG_HI21"; ++ imm = ((value & ~0xfff) - (address & ~0xfff)) >> 12; ++ loc32 = ptr; ++ *loc32 = cpu_to_le32(le32_to_cpu(*loc32) ++ + ((imm & 3) << 29) + ((imm & 0x1ffffc) << (5 - 2))); ++ break; ++ case R_AARCH64_ADD_ABS_LO12_NC: ++ type = "ADD_ABS_LO12_NC"; ++ loc32 = ptr; ++ *loc32 = cpu_to_le32(le32_to_cpu(*loc32) ++ + ((value & 0xfff) << 10)); ++ break; + case R_AARCH64_JUMP26: + type = "JUMP26"; + loc32 = ptr; +@@ -597,6 +623,15 @@ void machine_apply_elf_rel(struct mem_eh + *loc32 = cpu_to_le32(le32_to_cpu(*loc32) + + (((value - address) >> 2) & 0x3ffffff)); + break; ++ case R_AARCH64_LDST64_ABS_LO12_NC: ++ if (value & 7) ++ die("%s: ERROR Unaligned value: %lx\n", __func__, ++ value); ++ type = "LDST64_ABS_LO12_NC"; ++ loc32 = ptr; ++ *loc32 = cpu_to_le32(le32_to_cpu(*loc32) ++ + ((value & 0xff8) << (10 - 3))); ++ break; + default: + die("%s: ERROR Unknown type: %lu\n", __func__, r_type); + break; diff -Nru kexec-tools-2.0.10/debian/patches/arm64-Add-support-for-binary-image-files.patch kexec-tools-2.0.10/debian/patches/arm64-Add-support-for-binary-image-files.patch --- kexec-tools-2.0.10/debian/patches/arm64-Add-support-for-binary-image-files.patch 1970-01-01 00:00:00.000000000 +0000 +++ kexec-tools-2.0.10/debian/patches/arm64-Add-support-for-binary-image-files.patch 2017-02-10 02:12:22.000000000 +0000 @@ -0,0 +1,93 @@ +From abdfe97736f89d9bc73662b9134604b0229a599e Mon Sep 17 00:00:00 2001 +From: Pratyush Anand +Date: Wed, 21 Sep 2016 18:14:25 +0000 +Subject: [PATCH] arm64: Add support for binary image files + +Signed-off-by: Pratyush Anand +[Reworked and cleaned up] +Signed-off-by: Geoff Levand +Tested-By: Pratyush Anand +Tested-By: Matthias Brugger +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/kexec-image-arm64.c | 49 ++++++++++++++++++++++++++++++++---- + 1 file changed, 44 insertions(+), 5 deletions(-) + +Index: kexec-tools-2.0.10/kexec/arch/arm64/kexec-image-arm64.c +=================================================================== +--- kexec-tools-2.0.10.orig/kexec/arch/arm64/kexec-image-arm64.c ++++ kexec-tools-2.0.10/kexec/arch/arm64/kexec-image-arm64.c +@@ -3,7 +3,9 @@ + */ + + #define _GNU_SOURCE ++ + #include "kexec-arm64.h" ++#include + + int image_arm64_probe(const char *kernel_buf, off_t kernel_size) + { +@@ -21,14 +23,53 @@ int image_arm64_probe(const char *kernel + return -1; + } + +- fprintf(stderr, "kexec: ARM64 binary image files are currently NOT SUPPORTED.\n"); +- return -1; ++ return 0; + } + + int image_arm64_load(int argc, char **argv, const char *kernel_buf, + off_t kernel_size, struct kexec_info *info) + { +- return -1; ++ const struct arm64_image_header *header; ++ unsigned long kernel_segment; ++ int result; ++ ++ header = (const struct arm64_image_header *)(kernel_buf); ++ ++ if (arm64_process_image_header(header)) ++ return -1; ++ ++ kernel_segment = arm64_locate_kernel_segment(info); ++ ++ if (kernel_segment == ULONG_MAX) { ++ dbgprintf("%s: Kernel segment is not allocated\n", __func__); ++ result = -EFAILED; ++ goto exit; ++ } ++ ++ dbgprintf("%s: kernel_segment: %016lx\n", __func__, kernel_segment); ++ dbgprintf("%s: text_offset: %016lx\n", __func__, ++ arm64_mem.text_offset); ++ dbgprintf("%s: image_size: %016lx\n", __func__, ++ arm64_mem.image_size); ++ dbgprintf("%s: phys_offset: %016lx\n", __func__, ++ arm64_mem.phys_offset); ++ dbgprintf("%s: vp_offset: %016lx\n", __func__, ++ arm64_mem.vp_offset); ++ dbgprintf("%s: PE format: %s\n", __func__, ++ (arm64_header_check_pe_sig(header) ? "yes" : "no")); ++ ++ /* load the kernel */ ++ add_segment_phys_virt(info, kernel_buf, kernel_size, ++ kernel_segment + arm64_mem.text_offset, ++ arm64_mem.image_size, 0); ++ ++ result = arm64_load_other_segments(info, kernel_segment ++ + arm64_mem.text_offset); ++ ++exit: ++ if (result) ++ fprintf(stderr, "kexec: load failed.\n"); ++ return result; + } + + void image_arm64_usage(void) +@@ -36,6 +77,4 @@ void image_arm64_usage(void) + printf( + " An ARM64 binary image, compressed or not, big or little endian.\n" + " Typically an Image, Image.gz or Image.lzma file.\n\n"); +- printf( +-" ARM64 binary image files are currently NOT SUPPORTED.\n\n"); + } diff -Nru kexec-tools-2.0.10/debian/patches/arm64-Add-support-of-R_AARCH64_PREL32-relocation-in-.patch kexec-tools-2.0.10/debian/patches/arm64-Add-support-of-R_AARCH64_PREL32-relocation-in-.patch --- kexec-tools-2.0.10/debian/patches/arm64-Add-support-of-R_AARCH64_PREL32-relocation-in-.patch 1970-01-01 00:00:00.000000000 +0000 +++ kexec-tools-2.0.10/debian/patches/arm64-Add-support-of-R_AARCH64_PREL32-relocation-in-.patch 2017-02-10 02:12:22.000000000 +0000 @@ -0,0 +1,48 @@ +From ec271d6c298839916009474a9736728c77d959f1 Mon Sep 17 00:00:00 2001 +From: Pratyush Anand +Date: Fri, 28 Oct 2016 09:46:09 +0530 +Subject: [PATCH] arm64: Add support of R_AARCH64_PREL32 relocation in + purgatory + +gcc version in fedora koji is 6.2.1-2.fc25. kexec-tools compiled with this +gcc produced another relocation error: + +machine_apply_elf_rel: ERROR Unknown type: 261 + +This patch fixes the above error. + +Signed-off-by: Pratyush Anand +Reviewed-by: Geoff Levand +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/kexec-arm64.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +Index: kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.c +=================================================================== +--- kexec-tools-2.0.10.orig/kexec/arch/arm64/kexec-arm64.c ++++ kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.c +@@ -542,6 +542,10 @@ void machine_apply_elf_rel(struct mem_eh + # define R_AARCH64_ABS64 257 + #endif + ++#if !defined(R_AARCH64_PREL32) ++# define R_AARCH64_PREL32 261 ++#endif ++ + #if !defined(R_AARCH64_LD_PREL_LO19) + # define R_AARCH64_LD_PREL_LO19 273 + #endif +@@ -583,6 +587,12 @@ void machine_apply_elf_rel(struct mem_eh + loc64 = ptr; + *loc64 = cpu_to_elf64(ehdr, elf64_to_cpu(ehdr, *loc64) + value); + break; ++ case R_AARCH64_PREL32: ++ type = "PREL32"; ++ loc32 = ptr; ++ *loc32 = cpu_to_elf32(ehdr, ++ elf32_to_cpu(ehdr, *loc32) + value - address); ++ break; + case R_AARCH64_LD_PREL_LO19: + type = "LD_PREL_LO19"; + loc32 = ptr; diff -Nru kexec-tools-2.0.10/debian/patches/arm64-Cleanup-kexec-Makefile.patch kexec-tools-2.0.10/debian/patches/arm64-Cleanup-kexec-Makefile.patch --- kexec-tools-2.0.10/debian/patches/arm64-Cleanup-kexec-Makefile.patch 1970-01-01 00:00:00.000000000 +0000 +++ kexec-tools-2.0.10/debian/patches/arm64-Cleanup-kexec-Makefile.patch 2017-02-10 02:12:22.000000000 +0000 @@ -0,0 +1,53 @@ +From 402cf1427293b248b8a0ecdbf093be54298db530 Mon Sep 17 00:00:00 2001 +From: Geoff Levand +Date: Mon, 10 Oct 2016 21:22:58 +0000 +Subject: [PATCH] arm64: Cleanup kexec Makefile + +Put files in alphabetical order, reformat whitspace. + +Signed-off-by: Geoff Levand +Reviewed-by: Matthias Brugger +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/Makefile | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +Index: kexec-tools-2.0.10/kexec/arch/arm64/Makefile +=================================================================== +--- kexec-tools-2.0.10.orig/kexec/arch/arm64/Makefile ++++ kexec-tools-2.0.10/kexec/arch/arm64/Makefile +@@ -1,17 +1,18 @@ + + arm64_FS2DT += kexec/fs2dt.c +-arm64_FS2DT_INCLUDE += -include $(srcdir)/kexec/arch/arm64/kexec-arm64.h \ +- -include $(srcdir)/kexec/arch/arm64/crashdump-arm64.h ++arm64_FS2DT_INCLUDE += \ ++ -include $(srcdir)/kexec/arch/arm64/crashdump-arm64.h \ ++ -include $(srcdir)/kexec/arch/arm64/kexec-arm64.h + + arm64_DT_OPS += kexec/dt-ops.c + + arm64_CPPFLAGS += -I $(srcdir)/kexec/ + + arm64_KEXEC_SRCS += \ ++ kexec/arch/arm64/crashdump-arm64.c \ + kexec/arch/arm64/kexec-arm64.c \ +- kexec/arch/arm64/kexec-image-arm64.c \ + kexec/arch/arm64/kexec-elf-arm64.c \ +- kexec/arch/arm64/crashdump-arm64.c ++ kexec/arch/arm64/kexec-image-arm64.c + + arm64_ARCH_REUSE_INITRD = + arm64_ADD_SEGMENT = +@@ -19,9 +20,9 @@ arm64_VIRT_TO_PHYS = + arm64_PHYS_TO_VIRT = + + dist += $(arm64_KEXEC_SRCS) \ +- kexec/arch/arm64/Makefile \ ++ kexec/arch/arm64/crashdump-arm64.h \ + kexec/arch/arm64/kexec-arm64.h \ +- kexec/arch/arm64/crashdump-arm64.h ++ kexec/arch/arm64/Makefile + + ifdef HAVE_LIBFDT + diff -Nru kexec-tools-2.0.10/debian/patches/arm64-Fix-initrd-requierements.patch kexec-tools-2.0.10/debian/patches/arm64-Fix-initrd-requierements.patch --- kexec-tools-2.0.10/debian/patches/arm64-Fix-initrd-requierements.patch 1970-01-01 00:00:00.000000000 +0000 +++ kexec-tools-2.0.10/debian/patches/arm64-Fix-initrd-requierements.patch 2017-02-10 02:12:22.000000000 +0000 @@ -0,0 +1,66 @@ +From a2451670230c5687ae6a6af0685f22c1659fb94a Mon Sep 17 00:00:00 2001 +From: Matthias Brugger +Date: Wed, 7 Dec 2016 17:26:15 +0100 +Subject: [PATCH] arm64: Fix initrd requierements + +The initrd doesn't need to be aligend to 1 GB, which breaks kexec for system with +RAM <= 1 GB. Instead the memory size between the kernel start rounded down to 1 GB +and the end of the initrd rounded up to 1 GB can't be bigger then 32 GB. + +Signed-off-by: Matthias Brugger +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/kexec-arm64.c | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +Index: kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.c +=================================================================== +--- kexec-tools-2.0.10.orig/kexec/arch/arm64/kexec-arm64.c ++++ kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.c +@@ -327,6 +327,7 @@ int arm64_load_other_segments(struct kex + unsigned long dtb_base; + unsigned long hole_min; + unsigned long hole_max; ++ unsigned long initrd_end; + char *initrd_buf = NULL; + struct dtb dtb; + char command_line[COMMAND_LINE_SIZE] = ""; +@@ -366,27 +367,27 @@ int arm64_load_other_segments(struct kex + if (!initrd_buf) + fprintf(stderr, "kexec: Empty ramdisk file.\n"); + else { +- /* +- * Put the initrd after the kernel. As specified in +- * booting.txt, align to 1 GiB. +- */ ++ /* Put the initrd after the kernel. */ + + initrd_base = add_buffer_phys_virt(info, initrd_buf, +- initrd_size, initrd_size, GiB(1), ++ initrd_size, initrd_size, 0, + hole_min, hole_max, 1, 0); + +- /* initrd_base is valid if we got here. */ +- +- dbgprintf("initrd: base %lx, size %lxh (%ld)\n", +- initrd_base, initrd_size, initrd_size); ++ initrd_end = initrd_base + initrd_size; + +- /* Check size limit as specified in booting.txt. */ ++ /* Check limits as specified in booting.txt. ++ * The kernel may have as little as 32 GB of address space to map ++ * system memory and both kernel and initrd must be 1GB aligend. ++ */ + +- if (initrd_base - image_base + initrd_size > GiB(32)) { ++ if (_ALIGN_UP(initrd_end, GiB(1)) - _ALIGN_DOWN(image_base, GiB(1)) > GiB(32)) { + fprintf(stderr, "kexec: Error: image + initrd too big.\n"); + return -EFAILED; + } + ++ dbgprintf("initrd: base %lx, size %lxh (%ld)\n", ++ initrd_base, initrd_size, initrd_size); ++ + result = dtb_set_initrd((char **)&dtb.buf, + &dtb.size, initrd_base, + initrd_base + initrd_size); diff -Nru kexec-tools-2.0.10/debian/patches/arm-include-phys_to_virt.h-and-iomem.h-in-distributi.patch kexec-tools-2.0.10/debian/patches/arm-include-phys_to_virt.h-and-iomem.h-in-distributi.patch --- kexec-tools-2.0.10/debian/patches/arm-include-phys_to_virt.h-and-iomem.h-in-distributi.patch 1970-01-01 00:00:00.000000000 +0000 +++ kexec-tools-2.0.10/debian/patches/arm-include-phys_to_virt.h-and-iomem.h-in-distributi.patch 2017-02-10 02:12:22.000000000 +0000 @@ -0,0 +1,27 @@ +From 1574ff1aae4f3a2396187b4fe4f75a9be2ba2cc3 Mon Sep 17 00:00:00 2001 +From: Dave Young +Date: Tue, 9 Aug 2016 15:57:47 +0800 +Subject: [PATCH] arm: include phys_to_virt.h and iomem.h in distribution + +These files are required to build kexec-tools on arm. + +Signed-off-by: Dave Young +[simon: added changelog] +Signed-off-by: Simon Horman +--- + kexec/arch/arm/Makefile | 2 ++ + 1 file changed, 2 insertions(+) + +Index: kexec-tools-2.0.10/kexec/arch/arm/Makefile +=================================================================== +--- kexec-tools-2.0.10.orig/kexec/arch/arm/Makefile ++++ kexec-tools-2.0.10/kexec/arch/arm/Makefile +@@ -22,6 +22,8 @@ arm_KEXEC_SRCS += $(libfdt_SRCS) + + arm_UIMAGE = kexec/kexec-uImage.c + arm_PHYS_TO_VIRT = kexec/arch/arm/phys_to_virt.c ++arm_PHYS_TO_VIRT += kexec/arch/arm/iomem.h ++arm_PHYS_TO_VIRT += kexec/arch/arm/phys_to_virt.h + + dist += kexec/arch/arm/Makefile $(arm_KEXEC_SRCS) $(arm_PHYS_TO_VIRT) \ + kexec/arch/arm/crashdump-arm.h kexec/arch/arm/kexec-arm.h \ diff -Nru kexec-tools-2.0.10/debian/patches/kexec-Add-common-device-tree-routines.patch kexec-tools-2.0.10/debian/patches/kexec-Add-common-device-tree-routines.patch --- kexec-tools-2.0.10/debian/patches/kexec-Add-common-device-tree-routines.patch 1970-01-01 00:00:00.000000000 +0000 +++ kexec-tools-2.0.10/debian/patches/kexec-Add-common-device-tree-routines.patch 2017-02-10 02:12:22.000000000 +0000 @@ -0,0 +1,203 @@ +From 217bcc00c9309416a6c6cd0584196559d28a9259 Mon Sep 17 00:00:00 2001 +From: Geoff Levand +Date: Wed, 21 Sep 2016 18:14:25 +0000 +Subject: [PATCH] kexec: Add common device tree routines + +Common device tree routines that can be shared between all arches +that have device tree support. + +Signed-off-by: Geoff Levand +Tested-By: Pratyush Anand +Tested-By: Matthias Brugger +Signed-off-by: Simon Horman +--- + kexec/Makefile | 4 ++ + kexec/dt-ops.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + kexec/dt-ops.h | 13 ++++++ + 3 files changed, 162 insertions(+) + create mode 100644 kexec/dt-ops.c + create mode 100644 kexec/dt-ops.h + +Index: kexec-tools-2.0.10/kexec/Makefile +=================================================================== +--- kexec-tools-2.0.10.orig/kexec/Makefile ++++ kexec-tools-2.0.10/kexec/Makefile +@@ -69,6 +69,10 @@ dist += kexec/fs2dt.c kexec/fs2dt.h + $(ARCH)_FS2DT = + KEXEC_SRCS += $($(ARCH)_FS2DT) + ++dist += kexec/dt-ops.c kexec/dt-ops.h ++$(ARCH)_DT_OPS = ++KEXEC_SRCS += $($(ARCH)_DT_OPS) ++ + include $(srcdir)/kexec/arch/alpha/Makefile + include $(srcdir)/kexec/arch/arm/Makefile + include $(srcdir)/kexec/arch/i386/Makefile +Index: kexec-tools-2.0.10/kexec/dt-ops.c +=================================================================== +--- /dev/null ++++ kexec-tools-2.0.10/kexec/dt-ops.c +@@ -0,0 +1,145 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "kexec.h" ++#include "dt-ops.h" ++ ++static const char n_chosen[] = "/chosen"; ++ ++static const char p_bootargs[] = "bootargs"; ++static const char p_initrd_start[] = "linux,initrd-start"; ++static const char p_initrd_end[] = "linux,initrd-end"; ++ ++int dtb_set_initrd(char **dtb, off_t *dtb_size, off_t start, off_t end) ++{ ++ int result; ++ uint64_t value; ++ ++ dbgprintf("%s: start %jd, end %jd, size %jd (%jd KiB)\n", ++ __func__, (intmax_t)start, (intmax_t)end, ++ (intmax_t)(end - start), ++ (intmax_t)(end - start) / 1024); ++ ++ value = cpu_to_fdt64(start); ++ ++ result = dtb_set_property(dtb, dtb_size, n_chosen, p_initrd_start, ++ &value, sizeof(value)); ++ ++ if (result) ++ return result; ++ ++ value = cpu_to_fdt64(end); ++ ++ result = dtb_set_property(dtb, dtb_size, n_chosen, p_initrd_end, ++ &value, sizeof(value)); ++ ++ if (result) { ++ dtb_delete_property(*dtb, n_chosen, p_initrd_start); ++ return result; ++ } ++ ++ return 0; ++} ++ ++int dtb_set_bootargs(char **dtb, off_t *dtb_size, const char *command_line) ++{ ++ return dtb_set_property(dtb, dtb_size, n_chosen, p_bootargs, ++ command_line, strlen(command_line) + 1); ++} ++ ++int dtb_set_property(char **dtb, off_t *dtb_size, const char *node, ++ const char *prop, const void *value, int value_len) ++{ ++ int result; ++ int nodeoffset; ++ void *new_dtb; ++ int new_size; ++ ++ value_len = FDT_TAGALIGN(value_len); ++ ++ new_size = FDT_TAGALIGN(*dtb_size + fdt_node_len(node) ++ + fdt_prop_len(prop, value_len)); ++ ++ new_dtb = malloc(new_size); ++ ++ if (!new_dtb) { ++ dbgprintf("%s: malloc failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ result = fdt_open_into(*dtb, new_dtb, new_size); ++ ++ if (result) { ++ dbgprintf("%s: fdt_open_into failed: %s\n", __func__, ++ fdt_strerror(result)); ++ goto on_error; ++ } ++ ++ nodeoffset = fdt_path_offset(new_dtb, node); ++ ++ if (nodeoffset == -FDT_ERR_NOTFOUND) { ++ result = fdt_add_subnode(new_dtb, nodeoffset, node); ++ ++ if (result) { ++ dbgprintf("%s: fdt_add_subnode failed: %s\n", __func__, ++ fdt_strerror(result)); ++ goto on_error; ++ } ++ } else if (nodeoffset < 0) { ++ dbgprintf("%s: fdt_path_offset failed: %s\n", __func__, ++ fdt_strerror(nodeoffset)); ++ goto on_error; ++ } ++ ++ result = fdt_setprop(new_dtb, nodeoffset, prop, value, value_len); ++ ++ if (result) { ++ dbgprintf("%s: fdt_setprop failed: %s\n", __func__, ++ fdt_strerror(result)); ++ goto on_error; ++ } ++ ++ /* ++ * Can't call free on dtb since dtb may have been mmaped by ++ * slurp_file(). ++ */ ++ ++ result = fdt_pack(new_dtb); ++ ++ if (result) ++ dbgprintf("%s: Unable to pack device tree: %s\n", __func__, ++ fdt_strerror(result)); ++ ++ *dtb = new_dtb; ++ *dtb_size = fdt_totalsize(*dtb); ++ ++ return 0; ++ ++on_error: ++ free(new_dtb); ++ return result; ++} ++ ++int dtb_delete_property(char *dtb, const char *node, const char *prop) ++{ ++ int result; ++ int nodeoffset = fdt_path_offset(dtb, node); ++ ++ if (nodeoffset < 0) { ++ dbgprintf("%s: fdt_path_offset failed: %s\n", __func__, ++ fdt_strerror(nodeoffset)); ++ return nodeoffset; ++ } ++ ++ result = fdt_delprop(dtb, nodeoffset, prop); ++ ++ if (result) ++ dbgprintf("%s: fdt_delprop failed: %s\n", __func__, ++ fdt_strerror(nodeoffset)); ++ ++ return result; ++} +Index: kexec-tools-2.0.10/kexec/dt-ops.h +=================================================================== +--- /dev/null ++++ kexec-tools-2.0.10/kexec/dt-ops.h +@@ -0,0 +1,13 @@ ++#if !defined(KEXEC_DT_OPS_H) ++#define KEXEC_DT_OPS_H ++ ++#include ++ ++int dtb_set_initrd(char **dtb, off_t *dtb_size, off_t start, off_t end); ++int dtb_set_bootargs(char **dtb, off_t *dtb_size, const char *command_line); ++int dtb_set_property(char **dtb, off_t *dtb_size, const char *node, ++ const char *prop, const void *value, int value_len); ++ ++int dtb_delete_property(char *dtb, const char *node, const char *prop); ++ ++#endif diff -Nru kexec-tools-2.0.10/debian/patches/kexec-Increase-the-upper-limit-for-RAM-segments.patch kexec-tools-2.0.10/debian/patches/kexec-Increase-the-upper-limit-for-RAM-segments.patch --- kexec-tools-2.0.10/debian/patches/kexec-Increase-the-upper-limit-for-RAM-segments.patch 1970-01-01 00:00:00.000000000 +0000 +++ kexec-tools-2.0.10/debian/patches/kexec-Increase-the-upper-limit-for-RAM-segments.patch 2017-02-10 02:14:46.000000000 +0000 @@ -0,0 +1,28 @@ +From 24aa2d93cac316657a2c20f28b8687bbf7e22991 Mon Sep 17 00:00:00 2001 +From: Sameer Goel +Date: Wed, 18 Jan 2017 16:15:12 -0700 +Subject: [PATCH] kexec: Increase the upper limit for RAM segments + +On a newer UEFI based Qualcomm target the number of system ram regions +retrieved from /proc/iomem are ~40. So increasing the current hardcoded +values to 64 from 16. + +Signed-off-by: Sameer Goel +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/kexec-arm64.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.h +=================================================================== +--- kexec-tools-2.0.10.orig/kexec/arch/arm64/kexec-arm64.h ++++ kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.h +@@ -11,7 +11,7 @@ + #include "image-header.h" + #include "kexec.h" + +-#define KEXEC_SEGMENT_MAX 16 ++#define KEXEC_SEGMENT_MAX 64 + + #define BOOT_BLOCK_VERSION 17 + #define BOOT_BLOCK_LAST_COMP_VERSION 16 diff -Nru kexec-tools-2.0.10/debian/patches/kexec-phys_to_virt-must-take-unsigned-long-long.patch kexec-tools-2.0.10/debian/patches/kexec-phys_to_virt-must-take-unsigned-long-long.patch --- kexec-tools-2.0.10/debian/patches/kexec-phys_to_virt-must-take-unsigned-long-long.patch 1970-01-01 00:00:00.000000000 +0000 +++ kexec-tools-2.0.10/debian/patches/kexec-phys_to_virt-must-take-unsigned-long-long.patch 2017-02-10 02:12:22.000000000 +0000 @@ -0,0 +1,57 @@ +From 8d8d2229a3afe6323a737c42c25a101ea104efbe Mon Sep 17 00:00:00 2001 +From: Russell King +Date: Mon, 6 Jun 2016 17:59:29 +0100 +Subject: [PATCH] kexec: phys_to_virt() must take unsigned long long + +crashdump-elf.c passes unsigned long long addresses into phys_to_virt() +so make phys_to_virt() accept such addresses without truncating them. +This is important for ARM LPAE systems. + +Reviewed-by: Pratyush Anand +Signed-off-by: Russell King +Signed-off-by: Simon Horman +--- + kexec/arch/arm/phys_to_virt.c | 2 +- + kexec/crashdump.h | 2 +- + kexec/phys_to_virt.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +Index: kexec-tools-2.0.10/kexec/arch/arm/phys_to_virt.c +=================================================================== +--- kexec-tools-2.0.10.orig/kexec/arch/arm/phys_to_virt.c ++++ kexec-tools-2.0.10/kexec/arch/arm/phys_to_virt.c +@@ -14,7 +14,7 @@ + * http://lists.arm.linux.org.uk/lurker/message/20010723.185051.94ce743c.en.html + */ + unsigned long +-phys_to_virt(struct crash_elf_info *elf_info, unsigned long paddr) ++phys_to_virt(struct crash_elf_info *elf_info, unsigned long long paddr) + { + return paddr + elf_info->page_offset - phys_offset; + } +Index: kexec-tools-2.0.10/kexec/crashdump.h +=================================================================== +--- kexec-tools-2.0.10.orig/kexec/crashdump.h ++++ kexec-tools-2.0.10/kexec/crashdump.h +@@ -55,7 +55,7 @@ int crash_create_elf64_headers(struct ke + unsigned long crash_architecture(struct crash_elf_info *elf_info); + + unsigned long phys_to_virt(struct crash_elf_info *elf_info, +- unsigned long paddr); ++ unsigned long long paddr); + + unsigned long xen_architecture(struct crash_elf_info *elf_info); + int xen_get_nr_phys_cpus(void); +Index: kexec-tools-2.0.10/kexec/phys_to_virt.c +=================================================================== +--- kexec-tools-2.0.10.orig/kexec/phys_to_virt.c ++++ kexec-tools-2.0.10/kexec/phys_to_virt.c +@@ -10,7 +10,7 @@ + * their own implementation. + */ + unsigned long +-phys_to_virt(struct crash_elf_info *elf_info, unsigned long paddr) ++phys_to_virt(struct crash_elf_info *elf_info, unsigned long long paddr) + { + return paddr + elf_info->page_offset; + } diff -Nru kexec-tools-2.0.10/debian/patches/purgatory-Change-default-sha256-optimization-to-O2.patch kexec-tools-2.0.10/debian/patches/purgatory-Change-default-sha256-optimization-to-O2.patch --- kexec-tools-2.0.10/debian/patches/purgatory-Change-default-sha256-optimization-to-O2.patch 1970-01-01 00:00:00.000000000 +0000 +++ kexec-tools-2.0.10/debian/patches/purgatory-Change-default-sha256-optimization-to-O2.patch 2017-02-10 02:12:22.000000000 +0000 @@ -0,0 +1,57 @@ +From 0a7fba8b145306af4909950f64f2797a08db68d4 Mon Sep 17 00:00:00 2001 +From: Geoff Levand +Date: Thu, 1 Dec 2016 11:09:37 -0800 +Subject: [PATCH] purgatory: Change default sha256 optimization to -O2 + +Change the default purgatory sha256 code optimization from -O0 to -O2, and add a +new arch specific makefile variable $(ARCH)_PURGATORY_SHA256_CFLAGS which can +over ride this default. Set ia64_PURGATORY_SHA256_CFLAGS to -O0 to retain the +previous optimization level for ia64. + +The purgatory sha256 code needs the be built with -O0 for the ia64 +architecture. Currently this code is built with -O0 for all architectures, +which slows down the calculations for architectures which could otherwise +use -O2. + +On arm64, it takes around 20 second to verify SHA in purgatory when +vmlinuz image is around 13MB and initramfs is around 30M with -O2 +enabled. Otherwise, it takes more than 2 minutes. + +Cc: Pratyush Anand +Signed-off-by: Geoff Levand +Signed-off-by: Simon Horman +--- + purgatory/Makefile | 4 +--- + purgatory/arch/ia64/Makefile | 4 ++++ + 2 files changed, 5 insertions(+), 3 deletions(-) + +Index: kexec-tools-2.0.10/purgatory/Makefile +=================================================================== +--- kexec-tools-2.0.10.orig/purgatory/Makefile ++++ kexec-tools-2.0.10/purgatory/Makefile +@@ -38,9 +38,7 @@ clean += $(PURGATORY_OBJS) $(PURGATORY_D + + -include $(PURGATORY_DEPS) + +-# sha256.c needs to be compiled without optimization, else +-# purgatory fails to execute on ia64. +-purgatory/sha256.o: CFLAGS += -O0 ++purgatory/sha256.o: CFLAGS += -O2 $($(ARCH)_PURGATORY_SHA256_CFLAGS) + + purgatory/sha256.o: $(srcdir)/util_lib/sha256.c + mkdir -p $(@D) +Index: kexec-tools-2.0.10/purgatory/arch/ia64/Makefile +=================================================================== +--- kexec-tools-2.0.10.orig/purgatory/arch/ia64/Makefile ++++ kexec-tools-2.0.10/purgatory/arch/ia64/Makefile +@@ -8,6 +8,10 @@ ia64_PURGATORY_SRCS += purgatory/arch/ia + + ia64_PURGATORY_EXTRA_CFLAGS = -ffixed-r28 + ++# sha256.c needs to be compiled without optimization, else ++# purgatory fails to execute on ia64. ++ia64_PURGATORY_SHA256_CFLAGS = -O0 ++ + dist += purgatory/arch/ia64/Makefile $(ia64_PURGATORY_SRCS) \ + purgatory/arch/ia64/io.h purgatory/arch/ia64/purgatory-ia64.h + diff -Nru kexec-tools-2.0.10/debian/patches/series kexec-tools-2.0.10/debian/patches/series --- kexec-tools-2.0.10/debian/patches/series 2016-03-25 15:55:53.000000000 +0000 +++ kexec-tools-2.0.10/debian/patches/series 2017-02-10 02:14:40.000000000 +0000 @@ -8,3 +8,15 @@ powerpcspe_support.patch format-security.patch lp1546260-fix-purgatory-fail-gcc5.patch +kexec-Add-common-device-tree-routines.patch +arm64-Add-arm64-kexec-support.patch +arm64-Add-support-for-binary-image-files.patch +arm-include-phys_to_virt.h-and-iomem.h-in-distributi.patch +arm64-Cleanup-kexec-Makefile.patch +arm64-Add-missing-kexec-dist-files.patch +arm64-Add-support-for-additional-relocations-in-the-.patch +arm64-Add-support-of-R_AARCH64_PREL32-relocation-in-.patch +purgatory-Change-default-sha256-optimization-to-O2.patch +arm64-Fix-initrd-requierements.patch +kexec-phys_to_virt-must-take-unsigned-long-long.patch +kexec-Increase-the-upper-limit-for-RAM-segments.patch