]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
riscv: patch: Avoid early phys_to_page()
authorVivian Wang <wangruikang@iscas.ac.cn>
Mon, 23 Mar 2026 23:43:47 +0000 (17:43 -0600)
committerPaul Walmsley <pjw@kernel.org>
Sun, 5 Apr 2026 00:37:03 +0000 (18:37 -0600)
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 <thomas.weissschuh@linutronix.de>
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 <rppt@kernel.org>
Signed-off-by: Vivian Wang <wangruikang@iscas.ac.cn>
Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Tested-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
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 <pjw@kernel.org>
arch/riscv/kernel/patch.c

index db13c9ddf9e3d4e6d2e3008340284fdfeb34dd21..16b243376f362189256825d49d03a18774d577c7 100644 (file)
@@ -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)