Skip to content

Commit de0a9f4

Browse files
committed
Merge tag 'riscv-for-linus-6.10-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux
Pull RISC-V fixes from Palmer Dabbelt: - A fix for vector load/store instruction decoding, which could result in reserved vector element length encodings decoding as valid vector instructions. - Instruction patching now aggressively flushes the local instruction cache, to avoid situations where patching functions on the flush path results in torn instructions being fetched. - A fix to prevent the stack walker from showing up as part of traces. * tag 'riscv-for-linus-6.10-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: riscv: stacktrace: convert arch_stack_walk() to noinstr riscv: patch: Flush the icache right after patching to avoid illegal insns RISC-V: fix vector insn load/store width mask
2 parents b75f947 + cc2c169 commit de0a9f4

File tree

4 files changed

+22
-15
lines changed

4 files changed

+22
-15
lines changed

arch/riscv/include/asm/insn.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@
145145

146146
/* parts of opcode for RVF, RVD and RVQ */
147147
#define RVFDQ_FL_FS_WIDTH_OFF 12
148-
#define RVFDQ_FL_FS_WIDTH_MASK GENMASK(3, 0)
148+
#define RVFDQ_FL_FS_WIDTH_MASK GENMASK(2, 0)
149149
#define RVFDQ_FL_FS_WIDTH_W 2
150150
#define RVFDQ_FL_FS_WIDTH_D 3
151151
#define RVFDQ_LS_FS_WIDTH_Q 4

arch/riscv/kernel/ftrace.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,6 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
120120
out = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
121121
mutex_unlock(&text_mutex);
122122

123-
if (!mod)
124-
local_flush_icache_range(rec->ip, rec->ip + MCOUNT_INSN_SIZE);
125-
126123
return out;
127124
}
128125

@@ -156,9 +153,9 @@ static int __ftrace_modify_code(void *data)
156153
} else {
157154
while (atomic_read(&param->cpu_count) <= num_online_cpus())
158155
cpu_relax();
159-
}
160156

161-
local_flush_icache_all();
157+
local_flush_icache_all();
158+
}
162159

163160
return 0;
164161
}

arch/riscv/kernel/patch.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ static int __patch_insn_set(void *addr, u8 c, size_t len)
8989

9090
memset(waddr, c, len);
9191

92+
/*
93+
* We could have just patched a function that is about to be
94+
* called so make sure we don't execute partially patched
95+
* instructions by flushing the icache as soon as possible.
96+
*/
97+
local_flush_icache_range((unsigned long)waddr,
98+
(unsigned long)waddr + len);
99+
92100
patch_unmap(FIX_TEXT_POKE0);
93101

94102
if (across_pages)
@@ -135,6 +143,14 @@ static int __patch_insn_write(void *addr, const void *insn, size_t len)
135143

136144
ret = copy_to_kernel_nofault(waddr, insn, len);
137145

146+
/*
147+
* We could have just patched a function that is about to be
148+
* called so make sure we don't execute partially patched
149+
* instructions by flushing the icache as soon as possible.
150+
*/
151+
local_flush_icache_range((unsigned long)waddr,
152+
(unsigned long)waddr + len);
153+
138154
patch_unmap(FIX_TEXT_POKE0);
139155

140156
if (across_pages)
@@ -189,9 +205,6 @@ int patch_text_set_nosync(void *addr, u8 c, size_t len)
189205

190206
ret = patch_insn_set(tp, c, len);
191207

192-
if (!ret)
193-
flush_icache_range((uintptr_t)tp, (uintptr_t)tp + len);
194-
195208
return ret;
196209
}
197210
NOKPROBE_SYMBOL(patch_text_set_nosync);
@@ -224,9 +237,6 @@ int patch_text_nosync(void *addr, const void *insns, size_t len)
224237

225238
ret = patch_insn_write(tp, insns, len);
226239

227-
if (!ret)
228-
flush_icache_range((uintptr_t) tp, (uintptr_t) tp + len);
229-
230240
return ret;
231241
}
232242
NOKPROBE_SYMBOL(patch_text_nosync);
@@ -253,9 +263,9 @@ static int patch_text_cb(void *data)
253263
} else {
254264
while (atomic_read(&patch->cpu_count) <= num_online_cpus())
255265
cpu_relax();
256-
}
257266

258-
local_flush_icache_all();
267+
local_flush_icache_all();
268+
}
259269

260270
return ret;
261271
}

arch/riscv/kernel/stacktrace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ unsigned long __get_wchan(struct task_struct *task)
156156
return pc;
157157
}
158158

159-
noinline void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
159+
noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
160160
struct task_struct *task, struct pt_regs *regs)
161161
{
162162
walk_stackframe(task, regs, consume_entry, cookie);

0 commit comments

Comments
 (0)