Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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
https://github.com/devicetree-org/dt-schema/pull/158.

Link: https://lkml.kernel.org/r/20250509074635.3187114-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: Dave Hansen <dave.hansen@linux.intel.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: Marc 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>

authored by

Alexander Graf and committed by
Andrew Morton
274cdcb1 4e1d010e

+79
+3
arch/arm64/Kconfig
··· 1602 1602 config ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG 1603 1603 def_bool y 1604 1604 1605 + config ARCH_SUPPORTS_KEXEC_HANDOVER 1606 + def_bool y 1607 + 1605 1608 config ARCH_SUPPORTS_CRASH_DUMP 1606 1609 def_bool y 1607 1610
+34
drivers/of/fdt.c
··· 25 25 #include <linux/serial_core.h> 26 26 #include <linux/sysfs.h> 27 27 #include <linux/random.h> 28 + #include <linux/kexec_handover.h> 28 29 29 30 #include <asm/setup.h> /* for COMMAND_LINE_SIZE */ 30 31 #include <asm/page.h> ··· 876 875 memblock_add(rgn[i].base, rgn[i].size); 877 876 } 878 877 878 + /** 879 + * early_init_dt_check_kho - Decode info required for kexec handover from DT 880 + */ 881 + static void __init early_init_dt_check_kho(void) 882 + { 883 + unsigned long node = chosen_node_offset; 884 + u64 fdt_start, fdt_size, scratch_start, scratch_size; 885 + const __be32 *p; 886 + int l; 887 + 888 + if (!IS_ENABLED(CONFIG_KEXEC_HANDOVER) || (long)node < 0) 889 + return; 890 + 891 + p = of_get_flat_dt_prop(node, "linux,kho-fdt", &l); 892 + if (l != (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) 893 + return; 894 + 895 + fdt_start = dt_mem_next_cell(dt_root_addr_cells, &p); 896 + fdt_size = dt_mem_next_cell(dt_root_addr_cells, &p); 897 + 898 + p = of_get_flat_dt_prop(node, "linux,kho-scratch", &l); 899 + if (l != (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) 900 + return; 901 + 902 + scratch_start = dt_mem_next_cell(dt_root_addr_cells, &p); 903 + scratch_size = dt_mem_next_cell(dt_root_addr_cells, &p); 904 + 905 + kho_populate(fdt_start, fdt_size, scratch_start, scratch_size); 906 + } 907 + 879 908 #ifdef CONFIG_SERIAL_EARLYCON 880 909 881 910 int __init early_init_dt_scan_chosen_stdout(void) ··· 1200 1169 1201 1170 /* Handle linux,usable-memory-range property */ 1202 1171 early_init_dt_check_for_usable_mem_range(); 1172 + 1173 + /* Handle kexec handover */ 1174 + early_init_dt_check_kho(); 1203 1175 } 1204 1176 1205 1177 bool __init early_init_dt_scan(void *dt_virt, phys_addr_t dt_phys)
+42
drivers/of/kexec.c
··· 264 264 } 265 265 #endif /* CONFIG_IMA_KEXEC */ 266 266 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 + 267 304 /* 268 305 * of_kexec_alloc_and_setup_fdt - Alloc and setup a new Flattened Device Tree 269 306 * ··· 450 413 } 451 414 #endif 452 415 } 416 + 417 + /* Add kho metadata if this is a KHO image */ 418 + ret = kho_add_chosen(image, fdt, chosen_node); 419 + if (ret) 420 + goto out; 453 421 454 422 /* add bootargs */ 455 423 if (cmdline) {