From: Vivian Wang Date: Mon, 23 Mar 2026 23:43:47 +0000 (-0600) Subject: riscv: patch: Avoid early phys_to_page() X-Git-Tag: v7.0-rc7~1^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6b60a128c2f43180664a614830f3c529497e0394;p=thirdparty%2Fkernel%2Flinux.git riscv: patch: Avoid early phys_to_page() Similarly to commit 8d09e2d569f6 ("arm64: patching: avoid early page_to_phys()"), avoid using phys_to_page() for the kernel address case in patch_map(). Since this is called from apply_boot_alternatives() in setup_arch(), and commit 4267739cabb8 ("arch, mm: consolidate initialization of SPARSE memory model") has moved sparse_init() to after setup_arch(), phys_to_page() is not available there yet, and it panics on boot with SPARSEMEM on RV32, which does not use SPARSEMEM_VMEMMAP. Reported-by: Thomas Weißschuh Closes: https://lore.kernel.org/r/20260223144108-dcace0b9-02e8-4b67-a7ce-f263bed36f26@linutronix.de/ Fixes: 4267739cabb8 ("arch, mm: consolidate initialization of SPARSE memory model") Suggested-by: Mike Rapoport Signed-off-by: Vivian Wang Acked-by: Mike Rapoport (Microsoft) Tested-by: Thomas Weißschuh Link: https://patch.msgid.link/20260310-riscv-sparsemem-alternatives-fix-v1-1-659d5dd257e2@iscas.ac.cn [pjw@kernel.org: fix the subject line to align with the patch description] Signed-off-by: Paul Walmsley --- diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c index db13c9ddf9e3..16b243376f36 100644 --- a/arch/riscv/kernel/patch.c +++ b/arch/riscv/kernel/patch.c @@ -42,19 +42,20 @@ static inline bool is_kernel_exittext(uintptr_t addr) static __always_inline void *patch_map(void *addr, const unsigned int fixmap) { uintptr_t uintaddr = (uintptr_t) addr; - struct page *page; + phys_addr_t phys; - if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) - page = phys_to_page(__pa_symbol(addr)); - else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) - page = vmalloc_to_page(addr); - else - return addr; + if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) { + phys = __pa_symbol(addr); + } else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) { + struct page *page = vmalloc_to_page(addr); - BUG_ON(!page); + BUG_ON(!page); + phys = page_to_phys(page) + offset_in_page(addr); + } else { + return addr; + } - return (void *)set_fixmap_offset(fixmap, page_to_phys(page) + - offset_in_page(addr)); + return (void *)set_fixmap_offset(fixmap, phys); } static void patch_unmap(int fixmap)