Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/fadump: allocate memory for additional parameters early

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

authored by

Hari Bathini and committed by
Michael Ellerman
f4892c68 cfec8463

+15 -5
+2
arch/powerpc/include/asm/fadump.h
··· 19 19 extern int should_fadump_crash(void); 20 20 extern void crash_fadump(struct pt_regs *, const char *); 21 21 extern void fadump_cleanup(void); 22 + void fadump_setup_param_area(void); 22 23 extern void fadump_append_bootargs(void); 23 24 24 25 #else /* CONFIG_FA_DUMP */ ··· 27 26 static inline int should_fadump_crash(void) { return 0; } 28 27 static inline void crash_fadump(struct pt_regs *regs, const char *str) { } 29 28 static inline void fadump_cleanup(void) { } 29 + static inline void fadump_setup_param_area(void) { } 30 30 static inline void fadump_append_bootargs(void) { } 31 31 #endif /* !CONFIG_FA_DUMP */ 32 32
+10 -5
arch/powerpc/kernel/fadump.c
··· 1587 1587 return; 1588 1588 } 1589 1589 1590 + if (fw_dump.param_area) { 1591 + rc = sysfs_create_file(fadump_kobj, &bootargs_append_attr.attr); 1592 + if (rc) 1593 + pr_err("unable to create bootargs_append sysfs file (%d)\n", rc); 1594 + } 1595 + 1590 1596 debugfs_create_file("fadump_region", 0444, arch_debugfs_dir, NULL, 1591 1597 &fadump_region_fops); 1592 1598 ··· 1747 1741 * Reserve memory to store additional parameters to be passed 1748 1742 * for fadump/capture kernel. 1749 1743 */ 1750 - static void __init fadump_setup_param_area(void) 1744 + void __init fadump_setup_param_area(void) 1751 1745 { 1752 1746 phys_addr_t range_start, range_end; 1753 1747 ··· 1755 1749 return; 1756 1750 1757 1751 /* This memory can't be used by PFW or bootloader as it is shared across kernels */ 1758 - if (radix_enabled()) { 1752 + if (early_radix_enabled()) { 1759 1753 /* 1760 1754 * Anywhere in the upper half should be good enough as all memory 1761 1755 * is accessible in real mode. ··· 1783 1777 COMMAND_LINE_SIZE, 1784 1778 range_start, 1785 1779 range_end); 1786 - if (!fw_dump.param_area || sysfs_create_file(fadump_kobj, &bootargs_append_attr.attr)) { 1780 + if (!fw_dump.param_area) { 1787 1781 pr_warn("WARNING: Could not setup area to pass additional parameters!\n"); 1788 1782 return; 1789 1783 } 1790 1784 1791 - memset(phys_to_virt(fw_dump.param_area), 0, COMMAND_LINE_SIZE); 1785 + memset((void *)fw_dump.param_area, 0, COMMAND_LINE_SIZE); 1792 1786 } 1793 1787 1794 1788 /* ··· 1814 1808 } 1815 1809 /* Initialize the kernel dump memory structure and register with f/w */ 1816 1810 else if (fw_dump.reserve_dump_area_size) { 1817 - fadump_setup_param_area(); 1818 1811 fw_dump.ops->fadump_init_mem_struct(&fw_dump); 1819 1812 register_fadump(); 1820 1813 }
+3
arch/powerpc/kernel/prom.c
··· 908 908 909 909 mmu_early_init_devtree(); 910 910 911 + /* Setup param area for passing additional parameters to fadump capture kernel. */ 912 + fadump_setup_param_area(); 913 + 911 914 #ifdef CONFIG_PPC_POWERNV 912 915 /* Scan and build the list of machine check recoverable ranges */ 913 916 of_scan_flat_dt(early_init_dt_scan_recoverable_ranges, NULL);