The next patch adds high crashkernel reservation support on powerpc, so
kdump setup is updated to handle high crashkernel while loading the kdump
kernel.

With high crashkernel reservation, the crashkernel is split into two
regions: low crashkernel and high crashkernel. To ensure kdump loads
properly with the split reservation, the following changes are made:

 - Load the kdump image in high memory if enabled
 - Include both low and high crashkernel regions in usable memory
   ranges for the kdump kernel
 - Exclude both low and high crashkernel regions from crashkernel memory
  to prevent them from being exported through /proc/vmcore

Signed-off-by: Sourabh Jain <[email protected]>
---
 arch/powerpc/kexec/elf_64.c       | 10 +++++++---
 arch/powerpc/kexec/file_load_64.c |  5 +++--
 arch/powerpc/kexec/ranges.c       | 24 +++++++++++++++++++++---
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c
index ea50a072debf..85a6e92f1160 100644
--- a/arch/powerpc/kexec/elf_64.c
+++ b/arch/powerpc/kexec/elf_64.c
@@ -52,9 +52,13 @@ static void *elf64_load(struct kimage *image, char 
*kernel_buf,
        if (IS_ENABLED(CONFIG_CRASH_DUMP) && image->type == KEXEC_TYPE_CRASH) {
                /* min & max buffer values for kdump case */
                kbuf.buf_min = pbuf.buf_min = crashk_res.start;
-               kbuf.buf_max = pbuf.buf_max =
-                               ((crashk_res.end < ppc64_rma_size) ?
-                                crashk_res.end : (ppc64_rma_size - 1));
+
+               if (crashk_low_res.end)
+                       kbuf.buf_max = pbuf.buf_max = crashk_res.end;
+               else
+                       kbuf.buf_max = pbuf.buf_max =
+                                       ((crashk_res.end < ppc64_rma_size) ?
+                                       crashk_res.end : (ppc64_rma_size - 1));
        }
 
        ret = kexec_elf_load(image, &ehdr, &elf_info, &kbuf, &kernel_load_addr);
diff --git a/arch/powerpc/kexec/file_load_64.c 
b/arch/powerpc/kexec/file_load_64.c
index 8c72e12ea44e..701d226cd23f 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -731,6 +731,7 @@ int setup_new_fdt_ppc64(const struct kimage *image, void 
*fdt, struct crash_mem
        int i, nr_ranges, ret;
 
 #ifdef CONFIG_CRASH_DUMP
+       uint64_t crashk_start;
        /*
         * Restrict memory usage for kdump kernel by setting up
         * usable memory ranges and memory reserve map.
@@ -750,8 +751,8 @@ int setup_new_fdt_ppc64(const struct kimage *image, void 
*fdt, struct crash_mem
                 * Ensure we don't touch crashed kernel's memory except the
                 * first 64K of RAM, which will be backed up.
                 */
-               ret = fdt_add_mem_rsv(fdt, BACKUP_SRC_END + 1,
-                                     crashk_res.start - BACKUP_SRC_SIZE);
+               crashk_start = crashk_low_res.end ? crashk_low_res.start : 
crashk_res.start;
+               ret = fdt_add_mem_rsv(fdt, BACKUP_SRC_END + 1, crashk_start - 
BACKUP_SRC_SIZE);
                if (ret) {
                        pr_err("Error reserving crash memory: %s\n",
                               fdt_strerror(ret));
diff --git a/arch/powerpc/kexec/ranges.c b/arch/powerpc/kexec/ranges.c
index 867135560e5c..1b08c05ab5a8 100644
--- a/arch/powerpc/kexec/ranges.c
+++ b/arch/powerpc/kexec/ranges.c
@@ -524,9 +524,20 @@ int get_usable_memory_ranges(struct crash_mem **mem_ranges)
         * Also, crashed kernel's memory must be added to reserve map to
         * avoid kdump kernel from using it.
         */
-       ret = add_mem_range(mem_ranges, 0, crashk_res.end + 1);
-       if (ret)
-               goto out;
+       if (crashk_low_res.end) {
+               ret = add_mem_range(mem_ranges, 0, crashk_low_res.end + 1);
+               if (ret)
+                       goto out;
+
+               ret = add_mem_range(mem_ranges, crashk_res.start,
+                                   crashk_res.end - crashk_res.start + 1);
+               if (ret)
+                       goto out;
+       } else {
+               ret = add_mem_range(mem_ranges, 0, crashk_res.end + 1);
+               if (ret)
+                       goto out;
+       }
 
        for (i = 0; i < crashk_cma_cnt; i++) {
                ret = add_mem_range(mem_ranges, crashk_cma_ranges[i].start,
@@ -609,6 +620,13 @@ int get_crash_memory_ranges(struct crash_mem **mem_ranges)
        if (ret)
                goto out;
 
+       if (crashk_low_res.end) {
+               ret = crash_exclude_mem_range_guarded(mem_ranges, 
crashk_low_res.start,
+                                                     crashk_low_res.end);
+               if (ret)
+                       goto out;
+       }
+
        for (i = 0; i < crashk_cma_cnt; ++i) {
                ret = crash_exclude_mem_range_guarded(mem_ranges, 
crashk_cma_ranges[i].start,
                                              crashk_cma_ranges[i].end);
-- 
2.52.0


Reply via email to