From: George Guo <[email protected]> Enable Kexec Handover on LoongArch64:
- Kconfig: select ARCH_SUPPORTS_KEXEC_HANDOVER for 64BIT - machine_kexec_file: add cmdline_add_kho() to pass the KHO FDT and scratch buffer addresses to the next kernel via the "kho_handover=" command-line parameter - setup: parse "kho_handover=" early and call kho_populate() to hand memory regions to the KHO core Co-developed-by: Kexin Liu <[email protected]> Signed-off-by: Kexin Liu <[email protected]> Signed-off-by: George Guo <[email protected]> --- arch/loongarch/Kconfig | 3 +++ arch/loongarch/kernel/machine_kexec_file.c | 22 ++++++++++++++++++ arch/loongarch/kernel/setup.c | 27 ++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 606597da46b8..d494418545f5 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -684,6 +684,9 @@ config ARCH_SUPPORTS_KEXEC config ARCH_SUPPORTS_KEXEC_FILE def_bool 64BIT +config ARCH_SUPPORTS_KEXEC_HANDOVER + def_bool 64BIT + config ARCH_SELECTS_KEXEC_FILE def_bool 64BIT depends on KEXEC_FILE diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/kernel/machine_kexec_file.c index 5584b798ba46..ddf4d0e0e7fd 100644 --- a/arch/loongarch/kernel/machine_kexec_file.c +++ b/arch/loongarch/kernel/machine_kexec_file.c @@ -55,6 +55,24 @@ static void cmdline_add_initrd(struct kimage *image, unsigned long *cmdline_tmpl *cmdline_tmplen += initrd_strlen; } +#ifdef CONFIG_KEXEC_HANDOVER +/* Add "kho_handover=<fdt_size>@<fdt_addr>,<scratch_size>@<scratch_addr>" to cmdline. */ +static void cmdline_add_kho(struct kimage *image, unsigned long *cmdline_tmplen, + char *modified_cmdline) +{ + int n; + + if (!image->kho.fdt || !image->kho.scratch) + return; + + n = sprintf(modified_cmdline + *cmdline_tmplen, + "kho_handover=0x%llx@0x%llx,0x%lx@0x%llx ", + (u64)PAGE_SIZE, image->kho.fdt, + image->kho.scratch->bufsz, (u64)image->kho.scratch->mem); + *cmdline_tmplen += n; +} +#endif + #ifdef CONFIG_CRASH_DUMP static int prepare_elf_headers(void **addr, unsigned long *sz) @@ -220,6 +238,10 @@ int load_other_segments(struct kimage *image, cmdline_add_initrd(image, &cmdline_tmplen, modified_cmdline, initrd_load_addr); } +#ifdef CONFIG_KEXEC_HANDOVER + cmdline_add_kho(image, &cmdline_tmplen, modified_cmdline); +#endif + if (cmdline_len + cmdline_tmplen > COMMAND_LINE_SIZE) { pr_err("Appending command line exceeds COMMAND_LINE_SIZE\n"); ret = -EINVAL; diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index 839b23edee87..5934ba6f13e3 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -48,6 +48,7 @@ #include <asm/setup.h> #include <asm/time.h> #include <asm/unwind.h> +#include <linux/kexec_handover.h> #define SMBIOS_BIOSSIZE_OFFSET 0x09 #define SMBIOS_BIOSEXTERN_OFFSET 0x13 @@ -227,6 +228,32 @@ static int __init early_parse_mem(char *p) } early_param("mem", early_parse_mem); +#ifdef CONFIG_KEXEC_HANDOVER +static int __init early_parse_kho(char *p) +{ + phys_addr_t fdt_addr, scratch_addr; + u64 fdt_size, scratch_size; + + if (!p) + return -EINVAL; + + fdt_size = memparse(p, &p); + if (*p++ != '@') + return -EINVAL; + fdt_addr = memparse(p, &p); + if (*p++ != ',') + return -EINVAL; + scratch_size = memparse(p, &p); + if (*p++ != '@') + return -EINVAL; + scratch_addr = memparse(p, &p); + + kho_populate(fdt_addr, fdt_size, scratch_addr, scratch_size); + return 0; +} +early_param("kho_handover", early_parse_kho); +#endif + static void __init arch_reserve_vmcore(void) { #ifdef CONFIG_PROC_VMCORE -- 2.25.1

