Replacing 20230509-suspend-labrador-3eb6f0a8ac77@spud, here's a more complete backport of the patches for the lockdep splats during text patching on RISC-V. I've preserved the original broken patch & the subsequent fix to it.
CC: stable@vger.kernel.org CC: sasha@kernel.org CC: palmer@dabbelt.com CC: linux@roeck-us.net
Conor Dooley (2): RISC-V: take text_mutex during alternative patching RISC-V: fix taking the text_mutex twice during sifive errata patching
arch/riscv/errata/sifive/errata.c | 3 +++ arch/riscv/errata/thead/errata.c | 8 ++++++-- arch/riscv/kernel/cpufeature.c | 6 +++++- 3 files changed, 14 insertions(+), 3 deletions(-)
commit 9493e6f3ce02f44c21aa19f3cbf3b9aa05479d06 upstream.
Guenter reported a splat during boot, that Samuel pointed out was the lockdep assertion failing in patch_insn_write():
WARNING: CPU: 0 PID: 0 at arch/riscv/kernel/patch.c:63 patch_insn_write+0x222/0x2f6 epc : patch_insn_write+0x222/0x2f6 ra : patch_insn_write+0x21e/0x2f6 epc : ffffffff800068c6 ra : ffffffff800068c2 sp : ffffffff81803df0 gp : ffffffff81a1ab78 tp : ffffffff81814f80 t0 : ffffffffffffe000 t1 : 0000000000000001 t2 : 4c45203a76637369 s0 : ffffffff81803e40 s1 : 0000000000000004 a0 : 0000000000000000 a1 : ffffffffffffffff a2 : 0000000000000004 a3 : 0000000000000000 a4 : 0000000000000001 a5 : 0000000000000000 a6 : 0000000000000000 a7 : 0000000052464e43 s2 : ffffffff80b4889c s3 : 000000000000082c s4 : ffffffff80b48828 s5 : 0000000000000828 s6 : ffffffff8131a0a0 s7 : 0000000000000fff s8 : 0000000008000200 s9 : ffffffff8131a520 s10: 0000000000000018 s11: 000000000000000b t3 : 0000000000000001 t4 : 000000000000000d t5 : ffffffffd8180000 t6 : ffffffff81803bc8 status: 0000000200000100 badaddr: 0000000000000000 cause: 0000000000000003 [<ffffffff800068c6>] patch_insn_write+0x222/0x2f6 [<ffffffff80006a36>] patch_text_nosync+0xc/0x2a [<ffffffff80003b86>] riscv_cpufeature_patch_func+0x52/0x98 [<ffffffff80003348>] _apply_alternatives+0x46/0x86 [<ffffffff80c02d36>] apply_boot_alternatives+0x3c/0xfa [<ffffffff80c03ad8>] setup_arch+0x584/0x5b8 [<ffffffff80c0075a>] start_kernel+0xa2/0x8f8
This issue was exposed by 702e64550b12 ("riscv: fpu: switch has_fpu() to riscv_has_extension_likely()"), as it is the patching in has_fpu() that triggers the splats in Guenter's report.
Take the text_mutex before doing any code patching to satisfy lockdep.
Fixes: ff689fd21cb1 ("riscv: add RISC-V Svpbmt extension support") Fixes: a35707c3d850 ("riscv: add memory-type errata for T-Head") Fixes: 1a0e5dbd3723 ("riscv: sifive: Add SiFive alternative ports") Reported-by: Guenter Roeck linux@roeck-us.net Link: https://lore.kernel.org/all/20230212154333.GA3760469@roeck-us.net/ Signed-off-by: Conor Dooley conor.dooley@microchip.com Reviewed-by: Samuel Holland samuel@sholland.org Tested-by: Guenter Roeck linux@roeck-us.net Link: https://lore.kernel.org/r/20230212194735.491785-1-conor@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com --- arch/riscv/errata/sifive/errata.c | 3 +++ arch/riscv/errata/thead/errata.c | 8 ++++++-- arch/riscv/kernel/cpufeature.c | 6 +++++- 3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/arch/riscv/errata/sifive/errata.c b/arch/riscv/errata/sifive/errata.c index 1031038423e7..5b77d7310e39 100644 --- a/arch/riscv/errata/sifive/errata.c +++ b/arch/riscv/errata/sifive/errata.c @@ -4,6 +4,7 @@ */
#include <linux/kernel.h> +#include <linux/memory.h> #include <linux/module.h> #include <linux/string.h> #include <linux/bug.h> @@ -107,7 +108,9 @@ void __init_or_module sifive_errata_patch_func(struct alt_entry *begin,
tmp = (1U << alt->errata_id); if (cpu_req_errata & tmp) { + mutex_lock(&text_mutex); patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len); + mutex_lock(&text_mutex); cpu_apply_errata |= tmp; } } diff --git a/arch/riscv/errata/thead/errata.c b/arch/riscv/errata/thead/errata.c index 21546937db39..32a34ed73509 100644 --- a/arch/riscv/errata/thead/errata.c +++ b/arch/riscv/errata/thead/errata.c @@ -5,6 +5,7 @@
#include <linux/bug.h> #include <linux/kernel.h> +#include <linux/memory.h> #include <linux/module.h> #include <linux/string.h> #include <linux/uaccess.h> @@ -78,11 +79,14 @@ void __init_or_module thead_errata_patch_func(struct alt_entry *begin, struct al tmp = (1U << alt->errata_id); if (cpu_req_errata & tmp) { /* On vm-alternatives, the mmu isn't running yet */ - if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) + if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) { memcpy((void *)__pa_symbol(alt->old_ptr), (void *)__pa_symbol(alt->alt_ptr), alt->alt_len); - else + } else { + mutex_lock(&text_mutex); patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len); + mutex_unlock(&text_mutex); + } } }
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index 694267d1fe81..fd1238df6149 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -9,6 +9,7 @@ #include <linux/bitmap.h> #include <linux/ctype.h> #include <linux/libfdt.h> +#include <linux/memory.h> #include <linux/module.h> #include <linux/of.h> #include <asm/alternative.h> @@ -316,8 +317,11 @@ void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin, }
tmp = (1U << alt->errata_id); - if (cpu_req_feature & tmp) + if (cpu_req_feature & tmp) { + mutex_lock(&text_mutex); patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len); + mutex_unlock(&text_mutex); + } } } #endif
commit bf89b7ee52af5a5944fa3539e86089f72475055b upstream.
Chris pointed out that some bonehead, *cough* me *cough*, added two mutex_locks() to the SiFive errata patching. The second was meant to have been a mutex_unlock().
This results in errors such as
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000030 Oops [#1] Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 6.2.0-rc1-starlight-00079-g9493e6f3ce02 #229 Hardware name: BeagleV Starlight Beta (DT) epc : __schedule+0x42/0x500 ra : schedule+0x46/0xce epc : ffffffff8065957c ra : ffffffff80659a80 sp : ffffffff81203c80 gp : ffffffff812d50a0 tp : ffffffff8120db40 t0 : ffffffff81203d68 t1 : 0000000000000001 t2 : 4c45203a76637369 s0 : ffffffff81203cf0 s1 : ffffffff8120db40 a0 : 0000000000000000 a1 : ffffffff81213958 a2 : ffffffff81213958 a3 : 0000000000000000 a4 : 0000000000000000 a5 : ffffffff80a1bd00 a6 : 0000000000000000 a7 : 0000000052464e43 s2 : ffffffff8120db41 s3 : ffffffff80a1ad00 s4 : 0000000000000000 s5 : 0000000000000002 s6 : ffffffff81213938 s7 : 0000000000000000 s8 : 0000000000000000 s9 : 0000000000000001 s10: ffffffff812d7204 s11: ffffffff80d3c920 t3 : 0000000000000001 t4 : ffffffff812e6dd7 t5 : ffffffff812e6dd8 t6 : ffffffff81203bb8 status: 0000000200000100 badaddr: 0000000000000030 cause: 000000000000000d [<ffffffff80659a80>] schedule+0x46/0xce [<ffffffff80659dce>] schedule_preempt_disabled+0x16/0x28 [<ffffffff8065ae0c>] __mutex_lock.constprop.0+0x3fe/0x652 [<ffffffff8065b138>] __mutex_lock_slowpath+0xe/0x16 [<ffffffff8065b182>] mutex_lock+0x42/0x4c [<ffffffff8000ad94>] sifive_errata_patch_func+0xf6/0x18c [<ffffffff80002b92>] _apply_alternatives+0x74/0x76 [<ffffffff80802ee8>] apply_boot_alternatives+0x3c/0xfa [<ffffffff80803cb0>] setup_arch+0x60c/0x640 [<ffffffff80800926>] start_kernel+0x8e/0x99c ---[ end trace 0000000000000000 ]---
Reported-by: Chris Hofstaedtler zeha@debian.org Fixes: 9493e6f3ce02 ("RISC-V: take text_mutex during alternative patching") Signed-off-by: Conor Dooley conor.dooley@microchip.com Tested-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/20230302174154.970746-1-conor@kernel.org [Palmer: pick up Geert's bug report from the thread] Signed-off-by: Palmer Dabbelt palmer@rivosinc.com --- The Author: field for this patch was broken upstream due to a b4 bug. I've fixed it here, it was just an s/@kernel.org/@microchip.com/. --- arch/riscv/errata/sifive/errata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/errata/sifive/errata.c b/arch/riscv/errata/sifive/errata.c index 5b77d7310e39..c24a349dd026 100644 --- a/arch/riscv/errata/sifive/errata.c +++ b/arch/riscv/errata/sifive/errata.c @@ -110,7 +110,7 @@ void __init_or_module sifive_errata_patch_func(struct alt_entry *begin, if (cpu_req_errata & tmp) { mutex_lock(&text_mutex); patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len); - mutex_lock(&text_mutex); + mutex_unlock(&text_mutex); cpu_apply_errata |= tmp; } }
On Fri, May 12, 2023 at 08:58:17AM +0100, Conor Dooley wrote:
Replacing 20230509-suspend-labrador-3eb6f0a8ac77@spud, here's a more complete backport of the patches for the lockdep splats during text patching on RISC-V. I've preserved the original broken patch & the subsequent fix to it.
Queued up, thanks!
linux-stable-mirror@lists.linaro.org