On Mon, May 25 2026, George Guo wrote:

> 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/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;

Do you have nothing else for a bootloader to pass data to the kernel?
Passing this via the command line seems crazy... All these addresses are
now available directly to unprivileged userspace. Can't you use the
device tree like we do on ARM64?

Also, this commandline parameter isn't documented anywhere.

> +}
> +#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++ != '@')

Can you please wrap these in parenthesis? I am too dumb to remember all
the precedence rules and this immediately makes me question whether we
are doing (*p)++ or *(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

-- 
Regards,
Pratyush Yadav

Reply via email to