Skip to content

Commit 0fad198

Browse files
ConchuODgregkh
authored andcommitted
RISC-V: take text_mutex during alternative patching
commit 9493e6f 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 702e645 ("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: ff689fd ("riscv: add RISC-V Svpbmt extension support") Fixes: a35707c ("riscv: add memory-type errata for T-Head") Fixes: 1a0e5db ("riscv: sifive: Add SiFive alternative ports") Reported-by: Guenter Roeck <[email protected]> Link: https://lore.kernel.org/all/[email protected]/ Signed-off-by: Conor Dooley <[email protected]> Reviewed-by: Samuel Holland <[email protected]> Tested-by: Guenter Roeck <[email protected]> Link: https://lore.kernel.org/r/[email protected] Cc: [email protected] Signed-off-by: Palmer Dabbelt <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 13a0e21 commit 0fad198

File tree

3 files changed

+14
-3
lines changed

3 files changed

+14
-3
lines changed

arch/riscv/errata/sifive/errata.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
#include <linux/kernel.h>
7+
#include <linux/memory.h>
78
#include <linux/module.h>
89
#include <linux/string.h>
910
#include <linux/bug.h>
@@ -107,7 +108,9 @@ void __init_or_module sifive_errata_patch_func(struct alt_entry *begin,
107108

108109
tmp = (1U << alt->errata_id);
109110
if (cpu_req_errata & tmp) {
111+
mutex_lock(&text_mutex);
110112
patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len);
113+
mutex_lock(&text_mutex);
111114
cpu_apply_errata |= tmp;
112115
}
113116
}

arch/riscv/errata/thead/errata.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <linux/bug.h>
77
#include <linux/kernel.h>
8+
#include <linux/memory.h>
89
#include <linux/module.h>
910
#include <linux/string.h>
1011
#include <linux/uaccess.h>
@@ -78,11 +79,14 @@ void __init_or_module thead_errata_patch_func(struct alt_entry *begin, struct al
7879
tmp = (1U << alt->errata_id);
7980
if (cpu_req_errata & tmp) {
8081
/* On vm-alternatives, the mmu isn't running yet */
81-
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
82+
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) {
8283
memcpy((void *)__pa_symbol(alt->old_ptr),
8384
(void *)__pa_symbol(alt->alt_ptr), alt->alt_len);
84-
else
85+
} else {
86+
mutex_lock(&text_mutex);
8587
patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len);
88+
mutex_unlock(&text_mutex);
89+
}
8690
}
8791
}
8892

arch/riscv/kernel/cpufeature.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/bitmap.h>
1010
#include <linux/ctype.h>
1111
#include <linux/libfdt.h>
12+
#include <linux/memory.h>
1213
#include <linux/module.h>
1314
#include <linux/of.h>
1415
#include <asm/alternative.h>
@@ -316,8 +317,11 @@ void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin,
316317
}
317318

318319
tmp = (1U << alt->errata_id);
319-
if (cpu_req_feature & tmp)
320+
if (cpu_req_feature & tmp) {
321+
mutex_lock(&text_mutex);
320322
patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len);
323+
mutex_unlock(&text_mutex);
324+
}
321325
}
322326
}
323327
#endif

0 commit comments

Comments
 (0)