Message ID | 20231214091926.203439-1-alexghiti@rivosinc.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 420370f3ae3d3b883813fd3051a38805160b2b9f |
Headers | show |
Series | [-fixes,v2] riscv: Check if the code to patch lies in the exit section | expand |
On Thu, Dec 14, 2023 at 10:19:26AM +0100, Alexandre Ghiti wrote: > Otherwise we fall through to vmalloc_to_page() which panics since the > address does not lie in the vmalloc region. > > Fixes: 043cb41a85de ("riscv: introduce interfaces to patch kernel code") > Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com> > --- > > Changes in v2: > - Fix XIP rv32 build failure > > arch/riscv/include/asm/sections.h | 1 + > arch/riscv/kernel/patch.c | 11 ++++++++++- > arch/riscv/kernel/vmlinux-xip.lds.S | 2 ++ > arch/riscv/kernel/vmlinux.lds.S | 2 ++ > 4 files changed, 15 insertions(+), 1 deletion(-) > > diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h > index 32336e8a17cb..a393d5035c54 100644 > --- a/arch/riscv/include/asm/sections.h > +++ b/arch/riscv/include/asm/sections.h > @@ -13,6 +13,7 @@ extern char _start_kernel[]; > extern char __init_data_begin[], __init_data_end[]; > extern char __init_text_begin[], __init_text_end[]; > extern char __alt_start[], __alt_end[]; > +extern char __exittext_begin[], __exittext_end[]; > > static inline bool is_va_kernel_text(uintptr_t va) > { > diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c > index 13ee7bf589a1..37e87fdcf6a0 100644 > --- a/arch/riscv/kernel/patch.c > +++ b/arch/riscv/kernel/patch.c > @@ -14,6 +14,7 @@ > #include <asm/fixmap.h> > #include <asm/ftrace.h> > #include <asm/patch.h> > +#include <asm/sections.h> > > struct patch_insn { > void *addr; > @@ -25,6 +26,14 @@ struct patch_insn { > int riscv_patch_in_stop_machine = false; > > #ifdef CONFIG_MMU > + > +static inline bool is_kernel_exittext(uintptr_t addr) > +{ > + return system_state < SYSTEM_RUNNING && > + addr >= (uintptr_t)__exittext_begin && > + addr < (uintptr_t)__exittext_end; > +} > + > /* > * The fix_to_virt(, idx) needs a const value (not a dynamic variable of > * reg-a0) or BUILD_BUG_ON failed with "idx >= __end_of_fixed_addresses". > @@ -35,7 +44,7 @@ static __always_inline void *patch_map(void *addr, const unsigned int fixmap) > uintptr_t uintaddr = (uintptr_t) addr; > struct page *page; > > - if (core_kernel_text(uintaddr)) > + 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); > diff --git a/arch/riscv/kernel/vmlinux-xip.lds.S b/arch/riscv/kernel/vmlinux-xip.lds.S > index 50767647fbc6..8c3daa1b0531 100644 > --- a/arch/riscv/kernel/vmlinux-xip.lds.S > +++ b/arch/riscv/kernel/vmlinux-xip.lds.S > @@ -29,10 +29,12 @@ SECTIONS > HEAD_TEXT_SECTION > INIT_TEXT_SECTION(PAGE_SIZE) > /* we have to discard exit text and such at runtime, not link time */ > + __exittext_begin = .; > .exit.text : > { > EXIT_TEXT > } > + __exittext_end = .; > > .text : { > _text = .; > diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S > index 492dd4b8f3d6..002ca58dd998 100644 > --- a/arch/riscv/kernel/vmlinux.lds.S > +++ b/arch/riscv/kernel/vmlinux.lds.S > @@ -69,10 +69,12 @@ SECTIONS > __soc_builtin_dtb_table_end = .; > } > /* we have to discard exit text and such at runtime, not link time */ > + __exittext_begin = .; > .exit.text : > { > EXIT_TEXT > } > + __exittext_end = .; > > __init_text_end = .; > . = ALIGN(SECTION_ALIGN); > -- > 2.39.2 Reviewed-by: Charlie Jenkins <charlie@rivosinc.com> > > > _______________________________________________ > linux-riscv mailing list > linux-riscv@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv
Hello: This patch was applied to riscv/linux.git (fixes) by Palmer Dabbelt <palmer@rivosinc.com>: On Thu, 14 Dec 2023 10:19:26 +0100 you wrote: > Otherwise we fall through to vmalloc_to_page() which panics since the > address does not lie in the vmalloc region. > > Fixes: 043cb41a85de ("riscv: introduce interfaces to patch kernel code") > Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com> > --- > > [...] Here is the summary with links: - [-fixes,v2] riscv: Check if the code to patch lies in the exit section https://git.kernel.org/riscv/c/420370f3ae3d You are awesome, thank you!
diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h index 32336e8a17cb..a393d5035c54 100644 --- a/arch/riscv/include/asm/sections.h +++ b/arch/riscv/include/asm/sections.h @@ -13,6 +13,7 @@ extern char _start_kernel[]; extern char __init_data_begin[], __init_data_end[]; extern char __init_text_begin[], __init_text_end[]; extern char __alt_start[], __alt_end[]; +extern char __exittext_begin[], __exittext_end[]; static inline bool is_va_kernel_text(uintptr_t va) { diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c index 13ee7bf589a1..37e87fdcf6a0 100644 --- a/arch/riscv/kernel/patch.c +++ b/arch/riscv/kernel/patch.c @@ -14,6 +14,7 @@ #include <asm/fixmap.h> #include <asm/ftrace.h> #include <asm/patch.h> +#include <asm/sections.h> struct patch_insn { void *addr; @@ -25,6 +26,14 @@ struct patch_insn { int riscv_patch_in_stop_machine = false; #ifdef CONFIG_MMU + +static inline bool is_kernel_exittext(uintptr_t addr) +{ + return system_state < SYSTEM_RUNNING && + addr >= (uintptr_t)__exittext_begin && + addr < (uintptr_t)__exittext_end; +} + /* * The fix_to_virt(, idx) needs a const value (not a dynamic variable of * reg-a0) or BUILD_BUG_ON failed with "idx >= __end_of_fixed_addresses". @@ -35,7 +44,7 @@ static __always_inline void *patch_map(void *addr, const unsigned int fixmap) uintptr_t uintaddr = (uintptr_t) addr; struct page *page; - if (core_kernel_text(uintaddr)) + 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); diff --git a/arch/riscv/kernel/vmlinux-xip.lds.S b/arch/riscv/kernel/vmlinux-xip.lds.S index 50767647fbc6..8c3daa1b0531 100644 --- a/arch/riscv/kernel/vmlinux-xip.lds.S +++ b/arch/riscv/kernel/vmlinux-xip.lds.S @@ -29,10 +29,12 @@ SECTIONS HEAD_TEXT_SECTION INIT_TEXT_SECTION(PAGE_SIZE) /* we have to discard exit text and such at runtime, not link time */ + __exittext_begin = .; .exit.text : { EXIT_TEXT } + __exittext_end = .; .text : { _text = .; diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S index 492dd4b8f3d6..002ca58dd998 100644 --- a/arch/riscv/kernel/vmlinux.lds.S +++ b/arch/riscv/kernel/vmlinux.lds.S @@ -69,10 +69,12 @@ SECTIONS __soc_builtin_dtb_table_end = .; } /* we have to discard exit text and such at runtime, not link time */ + __exittext_begin = .; .exit.text : { EXIT_TEXT } + __exittext_end = .; __init_text_end = .; . = ALIGN(SECTION_ALIGN);
Otherwise we fall through to vmalloc_to_page() which panics since the address does not lie in the vmalloc region. Fixes: 043cb41a85de ("riscv: introduce interfaces to patch kernel code") Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com> --- Changes in v2: - Fix XIP rv32 build failure arch/riscv/include/asm/sections.h | 1 + arch/riscv/kernel/patch.c | 11 ++++++++++- arch/riscv/kernel/vmlinux-xip.lds.S | 2 ++ arch/riscv/kernel/vmlinux.lds.S | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-)