As done in commit 944a45abfabc ("arm64: kdump: Reimplement crashkernel=X")
and commit 4831be702b95 ("arm64/kexec: Fix missing extra range for
crashkres_low.") for arm64, while implementing crashkernel=X,[high,low],
riscv should have excluded the "crashk_low_res" reserved ranges from
the crash kernel memory to prevent them from being exported through
/proc/vmcore, and the exclusion would need an extra crash_mem range.

Just simply tested on qemu with crashkernel=4G with kexec in [1] mentioned
in [2]. And the second kernel can be started normally.

        # dmesg | grep crash
        [    0.000000] crashkernel low memory reserved: 0xf8000000 - 
0x100000000 (128 MB)
        [    0.000000] crashkernel reserved: 0x000000017fe00000 - 
0x000000027fe00000 (4096 MB)

Cc: Guo Ren <[email protected]>
Cc: Baoquan He <[email protected]>
[1]: https://github.com/chenjh005/kexec-tools/tree/build-test-riscv-v2
[2]: 
https://lore.kernel.org/all/[email protected]/
Fixes: 5882e5acf18d ("riscv: kdump: Implement crashkernel=X,[high,low]")
Reviewed-by: Guo Ren <[email protected]>
Signed-off-by: Jinjie Ruan <[email protected]>
---
 arch/riscv/kernel/machine_kexec_file.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/kernel/machine_kexec_file.c 
b/arch/riscv/kernel/machine_kexec_file.c
index 54e2d9552e93..3f7766057cac 100644
--- a/arch/riscv/kernel/machine_kexec_file.c
+++ b/arch/riscv/kernel/machine_kexec_file.c
@@ -61,7 +61,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
        unsigned int nr_ranges;
        int ret;
 
-       nr_ranges = 1; /* For exclusion of crashkernel region */
+       nr_ranges = 2; /* For exclusion of crashkernel region */
        walk_system_ram_res(0, -1, &nr_ranges, get_nr_ram_ranges_callback);
 
        cmem = kmalloc_flex(*cmem, ranges, nr_ranges);
@@ -76,8 +76,16 @@ static int prepare_elf_headers(void **addr, unsigned long 
*sz)
 
        /* Exclude crashkernel region */
        ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
-       if (!ret)
-               ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
+       if (ret)
+               goto out;
+
+       if (crashk_low_res.end) {
+               ret = crash_exclude_mem_range(cmem, crashk_low_res.start, 
crashk_low_res.end);
+               if (ret)
+                       goto out;
+       }
+
+       ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
 
 out:
        kfree(cmem);
-- 
2.34.1


Reply via email to