Commit de0a9f44 authored by Linus Torvalds's avatar Linus Torvalds

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
parents b75f9472 cc2c169e
...@@ -145,7 +145,7 @@ ...@@ -145,7 +145,7 @@
/* parts of opcode for RVF, RVD and RVQ */ /* parts of opcode for RVF, RVD and RVQ */
#define RVFDQ_FL_FS_WIDTH_OFF 12 #define RVFDQ_FL_FS_WIDTH_OFF 12
#define RVFDQ_FL_FS_WIDTH_MASK GENMASK(3, 0) #define RVFDQ_FL_FS_WIDTH_MASK GENMASK(2, 0)
#define RVFDQ_FL_FS_WIDTH_W 2 #define RVFDQ_FL_FS_WIDTH_W 2
#define RVFDQ_FL_FS_WIDTH_D 3 #define RVFDQ_FL_FS_WIDTH_D 3
#define RVFDQ_LS_FS_WIDTH_Q 4 #define RVFDQ_LS_FS_WIDTH_Q 4
......
...@@ -120,9 +120,6 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec) ...@@ -120,9 +120,6 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
out = ftrace_make_nop(mod, rec, MCOUNT_ADDR); out = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
mutex_unlock(&text_mutex); mutex_unlock(&text_mutex);
if (!mod)
local_flush_icache_range(rec->ip, rec->ip + MCOUNT_INSN_SIZE);
return out; return out;
} }
...@@ -156,9 +153,9 @@ static int __ftrace_modify_code(void *data) ...@@ -156,9 +153,9 @@ static int __ftrace_modify_code(void *data)
} else { } else {
while (atomic_read(&param->cpu_count) <= num_online_cpus()) while (atomic_read(&param->cpu_count) <= num_online_cpus())
cpu_relax(); cpu_relax();
}
local_flush_icache_all(); local_flush_icache_all();
}
return 0; return 0;
} }
......
...@@ -89,6 +89,14 @@ static int __patch_insn_set(void *addr, u8 c, size_t len) ...@@ -89,6 +89,14 @@ static int __patch_insn_set(void *addr, u8 c, size_t len)
memset(waddr, c, len); memset(waddr, c, len);
/*
* We could have just patched a function that is about to be
* called so make sure we don't execute partially patched
* instructions by flushing the icache as soon as possible.
*/
local_flush_icache_range((unsigned long)waddr,
(unsigned long)waddr + len);
patch_unmap(FIX_TEXT_POKE0); patch_unmap(FIX_TEXT_POKE0);
if (across_pages) if (across_pages)
...@@ -135,6 +143,14 @@ static int __patch_insn_write(void *addr, const void *insn, size_t len) ...@@ -135,6 +143,14 @@ static int __patch_insn_write(void *addr, const void *insn, size_t len)
ret = copy_to_kernel_nofault(waddr, insn, len); ret = copy_to_kernel_nofault(waddr, insn, len);
/*
* We could have just patched a function that is about to be
* called so make sure we don't execute partially patched
* instructions by flushing the icache as soon as possible.
*/
local_flush_icache_range((unsigned long)waddr,
(unsigned long)waddr + len);
patch_unmap(FIX_TEXT_POKE0); patch_unmap(FIX_TEXT_POKE0);
if (across_pages) if (across_pages)
...@@ -189,9 +205,6 @@ int patch_text_set_nosync(void *addr, u8 c, size_t len) ...@@ -189,9 +205,6 @@ int patch_text_set_nosync(void *addr, u8 c, size_t len)
ret = patch_insn_set(tp, c, len); ret = patch_insn_set(tp, c, len);
if (!ret)
flush_icache_range((uintptr_t)tp, (uintptr_t)tp + len);
return ret; return ret;
} }
NOKPROBE_SYMBOL(patch_text_set_nosync); NOKPROBE_SYMBOL(patch_text_set_nosync);
...@@ -224,9 +237,6 @@ int patch_text_nosync(void *addr, const void *insns, size_t len) ...@@ -224,9 +237,6 @@ int patch_text_nosync(void *addr, const void *insns, size_t len)
ret = patch_insn_write(tp, insns, len); ret = patch_insn_write(tp, insns, len);
if (!ret)
flush_icache_range((uintptr_t) tp, (uintptr_t) tp + len);
return ret; return ret;
} }
NOKPROBE_SYMBOL(patch_text_nosync); NOKPROBE_SYMBOL(patch_text_nosync);
...@@ -253,9 +263,9 @@ static int patch_text_cb(void *data) ...@@ -253,9 +263,9 @@ static int patch_text_cb(void *data)
} else { } else {
while (atomic_read(&patch->cpu_count) <= num_online_cpus()) while (atomic_read(&patch->cpu_count) <= num_online_cpus())
cpu_relax(); cpu_relax();
}
local_flush_icache_all(); local_flush_icache_all();
}
return ret; return ret;
} }
......
...@@ -156,7 +156,7 @@ unsigned long __get_wchan(struct task_struct *task) ...@@ -156,7 +156,7 @@ unsigned long __get_wchan(struct task_struct *task)
return pc; return pc;
} }
noinline void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
struct task_struct *task, struct pt_regs *regs) struct task_struct *task, struct pt_regs *regs)
{ {
walk_stackframe(task, regs, consume_entry, cookie); walk_stackframe(task, regs, consume_entry, cookie);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment