RISC-V Fixes for 6.10-rc6
* 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. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEKzw3R0RoQ7JKlDp6LhMZ81+7GIkFAmZ+4zUTHHBhbG1lckBk YWJiZWx0LmNvbQAKCRAuExnzX7sYiTXxD/wPSWbHf24Mr4CrFYbKR7lHWjGku+jG 8LQa+B9uUgpA8XjNjeeECg7lsJq/1avbPrUlValRckUIMZPHSWK4U7aFkkPs1WFa 87D5pA4AVkt5U8v/3c5GQ8Tod0Afa7OyFggxdglC3XFvUa5TNdn3pdv0rdE4Mx5l QRijFyLlhRv/D5We+exNAVJmkdHfSXQEEyEjXeb83VK+PsZzAXvHLj3omxCyQ1kH Kt2RyN8QpkUisFNTpSvPHiuoPjUeJvRs0JIyrO1SwBGHyYs4kg6g0KBk4YjTTXG5 xbRVG2tMO9TS2jRRHJS7fdI+yF0X1z+t+WUG1F1WHvKxnqbWczJ0UczFgacaVSkw BM/yO+VPg22f6bM4H85K5GBdhN8PplFDuHDdVQ8/LDGOrQKaByrorXWq3WrbwJcq vVwbnBGW6v4we5COzyHvwnakzl4bEMHoUb2NVTzZM+fFleiEdx4Sg+F5Us8+UlZh PztwjPao8spIm81l/wXStxYzschDyonCt74/odic2LDtFBirZWzDdUInXFVzUZs7 CUxF38XJ6SNQJBVVwQv6qisoWhy6Ca9SGKwY2GwW7Ustx3C4Eh0nrOVmI/DcHRgN 9rGm13Qfm8eUSznTM+buWTTluZvtmZupGpAP2GhvaUgTMDIfK/vttidW9Kf4KsP8 hn+jllIc1WgE6Q== =0bpZ -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
de0a9f4486
@ -145,7 +145,7 @@
|
||||
|
||||
/* parts of opcode for RVF, RVD and RVQ */
|
||||
#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_D 3
|
||||
#define RVFDQ_LS_FS_WIDTH_Q 4
|
||||
|
@ -120,9 +120,6 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
|
||||
out = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
|
||||
mutex_unlock(&text_mutex);
|
||||
|
||||
if (!mod)
|
||||
local_flush_icache_range(rec->ip, rec->ip + MCOUNT_INSN_SIZE);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -156,9 +153,9 @@ static int __ftrace_modify_code(void *data)
|
||||
} else {
|
||||
while (atomic_read(¶m->cpu_count) <= num_online_cpus())
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
local_flush_icache_all();
|
||||
local_flush_icache_all();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -89,6 +89,14 @@ static int __patch_insn_set(void *addr, u8 c, size_t 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);
|
||||
|
||||
if (across_pages)
|
||||
@ -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);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
if (across_pages)
|
||||
@ -189,9 +205,6 @@ int patch_text_set_nosync(void *addr, u8 c, size_t len)
|
||||
|
||||
ret = patch_insn_set(tp, c, len);
|
||||
|
||||
if (!ret)
|
||||
flush_icache_range((uintptr_t)tp, (uintptr_t)tp + len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
NOKPROBE_SYMBOL(patch_text_set_nosync);
|
||||
@ -224,9 +237,6 @@ int patch_text_nosync(void *addr, const void *insns, size_t len)
|
||||
|
||||
ret = patch_insn_write(tp, insns, len);
|
||||
|
||||
if (!ret)
|
||||
flush_icache_range((uintptr_t) tp, (uintptr_t) tp + len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
NOKPROBE_SYMBOL(patch_text_nosync);
|
||||
@ -253,9 +263,9 @@ static int patch_text_cb(void *data)
|
||||
} else {
|
||||
while (atomic_read(&patch->cpu_count) <= num_online_cpus())
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
local_flush_icache_all();
|
||||
local_flush_icache_all();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ unsigned long __get_wchan(struct task_struct *task)
|
||||
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)
|
||||
{
|
||||
walk_stackframe(task, regs, consume_entry, cookie);
|
||||
|
Loading…
Reference in New Issue
Block a user