Skip to content

Commit 55a2110

Browse files
committed
Merge tag 'riscv-for-linus-6.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux
Pull RISC-V fixes from Palmer Dabbelt: - RISC-V architecture-specific ELF attributes have been disabled in the kernel builds - A fix for a locking failure while during errata patching that manifests on SiFive-based systems - A fix for a KASAN failure during stack unwinding - A fix for some lockdep failures during text patching * tag 'riscv-for-linus-6.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: RISC-V: Don't check text_mutex during stop_machine riscv: Use READ_ONCE_NOCHECK in imprecise unwinding stack mode RISC-V: fix taking the text_mutex twice during sifive errata patching RISC-V: Stop emitting attributes
2 parents b0d14d2 + 2a8db5e commit 55a2110

File tree

8 files changed

+52
-8
lines changed

8 files changed

+52
-8
lines changed

arch/riscv/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ endif
8484
# Avoid generating .eh_frame sections.
8585
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables
8686

87+
# The RISC-V attributes frequently cause compatibility issues and provide no
88+
# information, so just turn them off.
89+
KBUILD_CFLAGS += $(call cc-option,-mno-riscv-attribute)
90+
KBUILD_AFLAGS += $(call cc-option,-mno-riscv-attribute)
91+
KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mno-arch-attr)
92+
KBUILD_AFLAGS += $(call as-option,-Wa$(comma)-mno-arch-attr)
93+
8794
KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax)
8895
KBUILD_AFLAGS_MODULE += $(call as-option,-Wa$(comma)-mno-relax)
8996

arch/riscv/errata/sifive/errata.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ void __init_or_module sifive_errata_patch_func(struct alt_entry *begin,
111111
mutex_lock(&text_mutex);
112112
patch_text_nosync(ALT_OLD_PTR(alt), ALT_ALT_PTR(alt),
113113
alt->alt_len);
114-
mutex_lock(&text_mutex);
114+
mutex_unlock(&text_mutex);
115115
cpu_apply_errata |= tmp;
116116
}
117117
}

arch/riscv/include/asm/ftrace.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,6 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
109109
#define ftrace_init_nop ftrace_init_nop
110110
#endif
111111

112-
#endif
112+
#endif /* CONFIG_DYNAMIC_FTRACE */
113113

114114
#endif /* _ASM_RISCV_FTRACE_H */

arch/riscv/include/asm/patch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@
99
int patch_text_nosync(void *addr, const void *insns, size_t len);
1010
int patch_text(void *addr, u32 *insns, int ninsns);
1111

12+
extern int riscv_patch_in_stop_machine;
13+
1214
#endif /* _ASM_RISCV_PATCH_H */

arch/riscv/kernel/compat_vdso/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ COMPAT_LD := $(LD)
1414
COMPAT_CC_FLAGS := -march=rv32g -mabi=ilp32
1515
COMPAT_LD_FLAGS := -melf32lriscv
1616

17+
# Disable attributes, as they're useless and break the build.
18+
COMPAT_CC_FLAGS += $(call cc-option,-mno-riscv-attribute)
19+
COMPAT_CC_FLAGS += $(call as-option,-Wa$(comma)-mno-arch-attr)
20+
1721
# Files to link into the compat_vdso
1822
obj-compat_vdso = $(patsubst %, %.o, $(compat_vdso-syms)) note.o
1923

arch/riscv/kernel/ftrace.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,19 @@
1515
void ftrace_arch_code_modify_prepare(void) __acquires(&text_mutex)
1616
{
1717
mutex_lock(&text_mutex);
18+
19+
/*
20+
* The code sequences we use for ftrace can't be patched while the
21+
* kernel is running, so we need to use stop_machine() to modify them
22+
* for now. This doesn't play nice with text_mutex, we use this flag
23+
* to elide the check.
24+
*/
25+
riscv_patch_in_stop_machine = true;
1826
}
1927

2028
void ftrace_arch_code_modify_post_process(void) __releases(&text_mutex)
2129
{
30+
riscv_patch_in_stop_machine = false;
2231
mutex_unlock(&text_mutex);
2332
}
2433

@@ -107,9 +116,9 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
107116
{
108117
int out;
109118

110-
ftrace_arch_code_modify_prepare();
119+
mutex_lock(&text_mutex);
111120
out = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
112-
ftrace_arch_code_modify_post_process();
121+
mutex_unlock(&text_mutex);
113122

114123
return out;
115124
}

arch/riscv/kernel/patch.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <asm/kprobes.h>
1212
#include <asm/cacheflush.h>
1313
#include <asm/fixmap.h>
14+
#include <asm/ftrace.h>
1415
#include <asm/patch.h>
1516

1617
struct patch_insn {
@@ -20,6 +21,8 @@ struct patch_insn {
2021
atomic_t cpu_count;
2122
};
2223

24+
int riscv_patch_in_stop_machine = false;
25+
2326
#ifdef CONFIG_MMU
2427
/*
2528
* The fix_to_virt(, idx) needs a const value (not a dynamic variable of
@@ -60,8 +63,15 @@ static int patch_insn_write(void *addr, const void *insn, size_t len)
6063
* Before reaching here, it was expected to lock the text_mutex
6164
* already, so we don't need to give another lock here and could
6265
* ensure that it was safe between each cores.
66+
*
67+
* We're currently using stop_machine() for ftrace & kprobes, and while
68+
* that ensures text_mutex is held before installing the mappings it
69+
* does not ensure text_mutex is held by the calling thread. That's
70+
* safe but triggers a lockdep failure, so just elide it for that
71+
* specific case.
6372
*/
64-
lockdep_assert_held(&text_mutex);
73+
if (!riscv_patch_in_stop_machine)
74+
lockdep_assert_held(&text_mutex);
6575

6676
if (across_pages)
6777
patch_map(addr + len, FIX_TEXT_POKE1);
@@ -125,14 +135,26 @@ NOKPROBE_SYMBOL(patch_text_cb);
125135

126136
int patch_text(void *addr, u32 *insns, int ninsns)
127137
{
138+
int ret;
128139
struct patch_insn patch = {
129140
.addr = addr,
130141
.insns = insns,
131142
.ninsns = ninsns,
132143
.cpu_count = ATOMIC_INIT(0),
133144
};
134145

135-
return stop_machine_cpuslocked(patch_text_cb,
136-
&patch, cpu_online_mask);
146+
/*
147+
* kprobes takes text_mutex, before calling patch_text(), but as we call
148+
* calls stop_machine(), the lockdep assertion in patch_insn_write()
149+
* gets confused by the context in which the lock is taken.
150+
* Instead, ensure the lock is held before calling stop_machine(), and
151+
* set riscv_patch_in_stop_machine to skip the check in
152+
* patch_insn_write().
153+
*/
154+
lockdep_assert_held(&text_mutex);
155+
riscv_patch_in_stop_machine = true;
156+
ret = stop_machine_cpuslocked(patch_text_cb, &patch, cpu_online_mask);
157+
riscv_patch_in_stop_machine = false;
158+
return ret;
137159
}
138160
NOKPROBE_SYMBOL(patch_text);

arch/riscv/kernel/stacktrace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ void notrace walk_stackframe(struct task_struct *task,
101101
while (!kstack_end(ksp)) {
102102
if (__kernel_text_address(pc) && unlikely(!fn(arg, pc)))
103103
break;
104-
pc = (*ksp++) - 0x4;
104+
pc = READ_ONCE_NOCHECK(*ksp++) - 0x4;
105105
}
106106
}
107107

0 commit comments

Comments
 (0)