Skip to content

Commit ba6b613

Browse files
agrafakpm00
authored andcommitted
arm64: add KHO support
We now have all bits in place to support KHO kexecs. Add awareness of KHO in the kexec file as well as boot path for arm64 and adds the respective kconfig option to the architecture so that it can use KHO successfully. Changes to the "chosen" node have been sent to devicetree-org/dt-schema#158. Link: https://lkml.kernel.org/r/20250411053745.1817356-10-changyuanl@google.com Signed-off-by: Alexander Graf <graf@amazon.com> Co-developed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Co-developed-by: Changyuan Lyu <changyuanl@google.com> Signed-off-by: Changyuan Lyu <changyuanl@google.com> Cc: Andy Lutomirski <luto@kernel.org> Cc: Anthony Yznaga <anthony.yznaga@oracle.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Ashish Kalra <ashish.kalra@amd.com> Cc: Ben Herrenschmidt <benh@kernel.crashing.org> Cc: Borislav Betkov <bp@alien8.de> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Eric Biederman <ebiederm@xmission.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Gowans <jgowans@amazon.com> Cc: Jason Gunthorpe <jgg@nvidia.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Krzysztof Kozlowski <krzk@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Pasha Tatashin <pasha.tatashin@soleen.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Pratyush Yadav <ptyadav@amazon.de> Cc: Rob Herring <robh@kernel.org> Cc: Saravana Kannan <saravanak@google.com> Cc: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Thomas Gleinxer <tglx@linutronix.de> Cc: Thomas Lendacky <thomas.lendacky@amd.com> Cc: Will Deacon <will@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent 958dbc0 commit ba6b613

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

arch/arm64/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,6 +1602,9 @@ config ARCH_SUPPORTS_KEXEC_IMAGE_VERIFY_SIG
16021602
config ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG
16031603
def_bool y
16041604

1605+
config ARCH_SUPPORTS_KEXEC_HANDOVER
1606+
def_bool y
1607+
16051608
config ARCH_SUPPORTS_CRASH_DUMP
16061609
def_bool y
16071610

drivers/of/fdt.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/serial_core.h>
2626
#include <linux/sysfs.h>
2727
#include <linux/random.h>
28+
#include <linux/kexec_handover.h>
2829

2930
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
3031
#include <asm/page.h>
@@ -875,6 +876,36 @@ void __init early_init_dt_check_for_usable_mem_range(void)
875876
memblock_add(rgn[i].base, rgn[i].size);
876877
}
877878

879+
/**
880+
* early_init_dt_check_kho - Decode info required for kexec handover from DT
881+
*/
882+
static void __init early_init_dt_check_kho(void)
883+
{
884+
unsigned long node = chosen_node_offset;
885+
u64 fdt_start, fdt_size, scratch_start, scratch_size;
886+
const __be32 *p;
887+
int l;
888+
889+
if (!IS_ENABLED(CONFIG_KEXEC_HANDOVER) || (long)node < 0)
890+
return;
891+
892+
p = of_get_flat_dt_prop(node, "linux,kho-fdt", &l);
893+
if (l != (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32))
894+
return;
895+
896+
fdt_start = dt_mem_next_cell(dt_root_addr_cells, &p);
897+
fdt_size = dt_mem_next_cell(dt_root_addr_cells, &p);
898+
899+
p = of_get_flat_dt_prop(node, "linux,kho-scratch", &l);
900+
if (l != (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32))
901+
return;
902+
903+
scratch_start = dt_mem_next_cell(dt_root_addr_cells, &p);
904+
scratch_size = dt_mem_next_cell(dt_root_addr_cells, &p);
905+
906+
kho_populate(fdt_start, fdt_size, scratch_start, scratch_size);
907+
}
908+
878909
#ifdef CONFIG_SERIAL_EARLYCON
879910

880911
int __init early_init_dt_scan_chosen_stdout(void)
@@ -1169,6 +1200,9 @@ void __init early_init_dt_scan_nodes(void)
11691200

11701201
/* Handle linux,usable-memory-range property */
11711202
early_init_dt_check_for_usable_mem_range();
1203+
1204+
/* Handle kexec handover */
1205+
early_init_dt_check_kho();
11721206
}
11731207

11741208
bool __init early_init_dt_scan(void *dt_virt, phys_addr_t dt_phys)

drivers/of/kexec.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,43 @@ static inline int setup_ima_buffer(const struct kimage *image, void *fdt,
264264
}
265265
#endif /* CONFIG_IMA_KEXEC */
266266

267+
static int kho_add_chosen(const struct kimage *image, void *fdt, int chosen_node)
268+
{
269+
int ret = 0;
270+
#ifdef CONFIG_KEXEC_HANDOVER
271+
phys_addr_t fdt_mem = 0;
272+
phys_addr_t fdt_len = 0;
273+
phys_addr_t scratch_mem = 0;
274+
phys_addr_t scratch_len = 0;
275+
276+
ret = fdt_delprop(fdt, chosen_node, "linux,kho-fdt");
277+
if (ret && ret != -FDT_ERR_NOTFOUND)
278+
return ret;
279+
ret = fdt_delprop(fdt, chosen_node, "linux,kho-scratch");
280+
if (ret && ret != -FDT_ERR_NOTFOUND)
281+
return ret;
282+
283+
if (!image->kho.fdt || !image->kho.scratch)
284+
return 0;
285+
286+
fdt_mem = image->kho.fdt;
287+
fdt_len = PAGE_SIZE;
288+
scratch_mem = image->kho.scratch->mem;
289+
scratch_len = image->kho.scratch->bufsz;
290+
291+
pr_debug("Adding kho metadata to DT");
292+
293+
ret = fdt_appendprop_addrrange(fdt, 0, chosen_node, "linux,kho-fdt",
294+
fdt_mem, fdt_len);
295+
if (ret)
296+
return ret;
297+
ret = fdt_appendprop_addrrange(fdt, 0, chosen_node, "linux,kho-scratch",
298+
scratch_mem, scratch_len);
299+
300+
#endif /* CONFIG_KEXEC_HANDOVER */
301+
return ret;
302+
}
303+
267304
/*
268305
* of_kexec_alloc_and_setup_fdt - Alloc and setup a new Flattened Device Tree
269306
*
@@ -414,6 +451,11 @@ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image,
414451
#endif
415452
}
416453

454+
/* Add kho metadata if this is a KHO image */
455+
ret = kho_add_chosen(image, fdt, chosen_node);
456+
if (ret)
457+
goto out;
458+
417459
/* add bootargs */
418460
if (cmdline) {
419461
ret = fdt_setprop_string(fdt, chosen_node, "bootargs", cmdline);

0 commit comments

Comments
 (0)