]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
powerpc/fadump: allocate memory for additional parameters early
authorHari Bathini <hbathini@linux.ibm.com>
Thu, 7 Nov 2024 05:58:16 +0000 (11:28 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Dec 2024 12:53:40 +0000 (13:53 +0100)
[ Upstream commit f4892c68ecc1cf45e41a78820dd2eebccc945b66 ]

Memory for passing additional parameters to fadump capture kernel
is allocated during subsys_initcall level, using memblock. But
as slab is already available by this time, allocation happens via
the buddy allocator. This may work for radix MMU but is likely to
fail in most cases for hash MMU as hash MMU needs this memory in
the first memory block for it to be accessible in real mode in the
capture kernel (second boot). So, allocate memory for additional
parameters area as soon as MMU mode is obvious.

Fixes: 683eab94da75 ("powerpc/fadump: setup additional parameters for dump capture kernel")
Reported-by: Venkat Rao Bagalkote <venkat88@linux.vnet.ibm.com>
Closes: https://lore.kernel.org/lkml/a70e4064-a040-447b-8556-1fd02f19383d@linux.vnet.ibm.com/T/#u
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Sourabh Jain <sourabhjain@linux.ibm.com>
Tested-by: Venkat Rao Bagalkote <venkat88@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://patch.msgid.link/20241107055817.489795-1-sourabhjain@linux.ibm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/powerpc/include/asm/fadump.h
arch/powerpc/kernel/fadump.c
arch/powerpc/kernel/prom.c

index 3638f04447f592e728b275805c6557d53be4f694..a48f54dde4f6566ac3a51b754f090752ad9c0865 100644 (file)
@@ -19,6 +19,7 @@ extern int is_fadump_active(void);
 extern int should_fadump_crash(void);
 extern void crash_fadump(struct pt_regs *, const char *);
 extern void fadump_cleanup(void);
+void fadump_setup_param_area(void);
 extern void fadump_append_bootargs(void);
 
 #else  /* CONFIG_FA_DUMP */
@@ -26,6 +27,7 @@ static inline int is_fadump_active(void) { return 0; }
 static inline int should_fadump_crash(void) { return 0; }
 static inline void crash_fadump(struct pt_regs *regs, const char *str) { }
 static inline void fadump_cleanup(void) { }
+static inline void fadump_setup_param_area(void) { }
 static inline void fadump_append_bootargs(void) { }
 #endif /* !CONFIG_FA_DUMP */
 
index ac7b4e1645e55dc7dc56740bc1f7acccaec64395..6ab7934d719f76a0a1d4f02d5fb348222f79419d 100644 (file)
@@ -1577,6 +1577,12 @@ static void __init fadump_init_files(void)
                return;
        }
 
+       if (fw_dump.param_area) {
+               rc = sysfs_create_file(fadump_kobj, &bootargs_append_attr.attr);
+               if (rc)
+                       pr_err("unable to create bootargs_append sysfs file (%d)\n", rc);
+       }
+
        debugfs_create_file("fadump_region", 0444, arch_debugfs_dir, NULL,
                            &fadump_region_fops);
 
@@ -1731,7 +1737,7 @@ err_out:
  * Reserve memory to store additional parameters to be passed
  * for fadump/capture kernel.
  */
-static void __init fadump_setup_param_area(void)
+void __init fadump_setup_param_area(void)
 {
        phys_addr_t range_start, range_end;
 
@@ -1739,7 +1745,7 @@ static void __init fadump_setup_param_area(void)
                return;
 
        /* This memory can't be used by PFW or bootloader as it is shared across kernels */
-       if (radix_enabled()) {
+       if (early_radix_enabled()) {
                /*
                 * Anywhere in the upper half should be good enough as all memory
                 * is accessible in real mode.
@@ -1767,12 +1773,12 @@ static void __init fadump_setup_param_area(void)
                                                       COMMAND_LINE_SIZE,
                                                       range_start,
                                                       range_end);
-       if (!fw_dump.param_area || sysfs_create_file(fadump_kobj, &bootargs_append_attr.attr)) {
+       if (!fw_dump.param_area) {
                pr_warn("WARNING: Could not setup area to pass additional parameters!\n");
                return;
        }
 
-       memset(phys_to_virt(fw_dump.param_area), 0, COMMAND_LINE_SIZE);
+       memset((void *)fw_dump.param_area, 0, COMMAND_LINE_SIZE);
 }
 
 /*
@@ -1798,7 +1804,6 @@ int __init setup_fadump(void)
        }
        /* Initialize the kernel dump memory structure and register with f/w */
        else if (fw_dump.reserve_dump_area_size) {
-               fadump_setup_param_area();
                fw_dump.ops->fadump_init_mem_struct(&fw_dump);
                register_fadump();
        }
index 88cbe432cad59d042fcb05c5f00a6d6d09e0df4c..e0059842a1c64bfb777fee4ae9ef4742d93e6803 100644 (file)
@@ -908,6 +908,9 @@ void __init early_init_devtree(void *params)
 
        mmu_early_init_devtree();
 
+       /* Setup param area for passing additional parameters to fadump capture kernel. */
+       fadump_setup_param_area();
+
 #ifdef CONFIG_PPC_POWERNV
        /* Scan and build the list of machine check recoverable ranges */
        of_scan_flat_dt(early_init_dt_scan_recoverable_ranges, NULL);