We need to prevent firmware-reserved memory regions, particularly EFI
memory map as well as ACPI tables, from being corrupted by loading
kernel/initrd (or other kexec buffers). We also want to support memory
allocation in top-down manner in addition to default bottom-up.
So let's have arm64 specific arch_kexec_walk_mem() which will search
for available memory ranges in usable memblock list,
i.e. !NOMAP & !reserved, instead of system resource tree.

Signed-off-by: AKASHI Takahiro <takahiro.aka...@linaro.org>
Cc: Catalin Marinas <catalin.mari...@arm.com>
Cc: Will Deacon <will.dea...@arm.com>
---
 arch/arm64/kernel/Makefile             |  3 +-
 arch/arm64/kernel/machine_kexec_file.c | 57 ++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/kernel/machine_kexec_file.c

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index bf825f38d206..2f2b2757ae7a 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -48,8 +48,9 @@ arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL)       += 
acpi_parking_protocol.o
 arm64-obj-$(CONFIG_PARAVIRT)           += paravirt.o
 arm64-obj-$(CONFIG_RANDOMIZE_BASE)     += kaslr.o
 arm64-obj-$(CONFIG_HIBERNATION)                += hibernate.o hibernate-asm.o
-arm64-obj-$(CONFIG_KEXEC)              += machine_kexec.o relocate_kernel.o    
\
+arm64-obj-$(CONFIG_KEXEC_CORE)         += machine_kexec.o relocate_kernel.o    
\
                                           cpu-reset.o
+arm64-obj-$(CONFIG_KEXEC_FILE)         += machine_kexec_file.o
 arm64-obj-$(CONFIG_ARM64_RELOC_TEST)   += arm64-reloc-test.o
 arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
 arm64-obj-$(CONFIG_CRASH_DUMP)         += crash_dump.o
diff --git a/arch/arm64/kernel/machine_kexec_file.c 
b/arch/arm64/kernel/machine_kexec_file.c
new file mode 100644
index 000000000000..f9ebf54ca247
--- /dev/null
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * kexec_file for arm64
+ *
+ * Copyright (C) 2018 Linaro Limited
+ * Author: AKASHI Takahiro <takahiro.aka...@linaro.org>
+ *
+ * Most code is derived from arm64 port of kexec-tools
+ */
+
+#define pr_fmt(fmt) "kexec_file: " fmt
+
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/kexec.h>
+#include <linux/memblock.h>
+
+int arch_kexec_walk_mem(struct kexec_buf *kbuf,
+                               int (*func)(struct resource *, void *))
+{
+       phys_addr_t start, end;
+       struct resource res;
+       u64 i;
+       int ret = 0;
+
+       if (kbuf->image->type == KEXEC_TYPE_CRASH)
+               return func(&crashk_res, kbuf);
+
+       if (kbuf->top_down)
+               for_each_mem_range_rev(i, &memblock.memory, &memblock.reserved,
+                               NUMA_NO_NODE, MEMBLOCK_NONE,
+                               &start, &end, NULL) {
+                       if (!memblock_is_map_memory(start))
+                               continue;
+
+                       res.start = start;
+                       res.end = end;
+                       ret = func(&res, kbuf);
+                       if (ret)
+                               break;
+               }
+       else
+               for_each_mem_range(i, &memblock.memory, &memblock.reserved,
+                               NUMA_NO_NODE, MEMBLOCK_NONE,
+                               &start, &end, NULL) {
+                       if (!memblock_is_map_memory(start))
+                               continue;
+
+                       res.start = start;
+                       res.end = end;
+                       ret = func(&res, kbuf);
+                       if (ret)
+                               break;
+               }
+
+       return ret;
+}
-- 
2.17.0

Reply via email to