Commit 261b8e89 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'riscv-for-linus-6.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux

Pull RISC-V fixes from Palmer Dabbelt:

 - A fix for an __{get,put}_kernel_nofault to avoid an uninitialized
   value causing spurious failures

 - compat_vdso.so.dbg is now installed to the standard install location

 - A fix to avoid initializing PERF_SAMPLE_BRANCH_*-related events, as
   they aren't supported and will just later fail

 - A fix to make AT_VECTOR_SIZE_ARCH correct now that we're providing
   AT_MINSIGSTKSZ

 - pgprot_nx() is now implemented, which fixes vmap W^X protection

 - A fix for the vector save/restore code, which at least manifests as
   corrupted vector state when a signal is taken

 - A fix for a race condition in instruction patching

 - A fix to avoid leaking the kernel-mode GP to userspace, which is a
   kernel pointer leak that can be used to defeat KASLR in various ways

 - A handful of smaller fixes to build warnings, an overzealous printk,
   and some missing tracing annotations

* tag 'riscv-for-linus-6.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
  riscv: process: Fix kernel gp leakage
  riscv: Disable preemption when using patch_map()
  riscv: Fix warning by declaring arch_cpu_idle() as noinstr
  riscv: use KERN_INFO in do_trap
  riscv: Fix vector state restore in rt_sigreturn()
  riscv: mm: implement pgprot_nx
  riscv: compat_vdso: align VDSOAS build log
  RISC-V: Update AT_VECTOR_SIZE_ARCH for new AT_MINSIGSTKSZ
  riscv: Mark __se_sys_* functions __used
  drivers/perf: riscv: Disable PERF_SAMPLE_BRANCH_* while not supported
  riscv: compat_vdso: install compat_vdso.so.dbg to /lib/modules/*/vdso/
  riscv: hwprobe: do not produce frtace relocation
  riscv: Fix spurious errors from __get/put_kernel_nofault
  riscv: mm: Fix prototype to avoid discarding const
parents 50094473 d14fa1fc
...@@ -151,7 +151,7 @@ endif ...@@ -151,7 +151,7 @@ endif
endif endif
vdso-install-y += arch/riscv/kernel/vdso/vdso.so.dbg vdso-install-y += arch/riscv/kernel/vdso/vdso.so.dbg
vdso-install-$(CONFIG_COMPAT) += arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg:../compat_vdso/compat_vdso.so vdso-install-$(CONFIG_COMPAT) += arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg
ifneq ($(CONFIG_XIP_KERNEL),y) ifneq ($(CONFIG_XIP_KERNEL),y)
ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_ARCH_CANAAN),yy) ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_ARCH_CANAAN),yy)
......
...@@ -593,6 +593,12 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma, ...@@ -593,6 +593,12 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
return ptep_test_and_clear_young(vma, address, ptep); return ptep_test_and_clear_young(vma, address, ptep);
} }
#define pgprot_nx pgprot_nx
static inline pgprot_t pgprot_nx(pgprot_t _prot)
{
return __pgprot(pgprot_val(_prot) & ~_PAGE_EXEC);
}
#define pgprot_noncached pgprot_noncached #define pgprot_noncached pgprot_noncached
static inline pgprot_t pgprot_noncached(pgprot_t _prot) static inline pgprot_t pgprot_noncached(pgprot_t _prot)
{ {
......
...@@ -36,7 +36,8 @@ asmlinkage long __riscv_sys_ni_syscall(const struct pt_regs *); ...@@ -36,7 +36,8 @@ asmlinkage long __riscv_sys_ni_syscall(const struct pt_regs *);
ulong) \ ulong) \
__attribute__((alias(__stringify(___se_##prefix##name)))); \ __attribute__((alias(__stringify(___se_##prefix##name)))); \
__diag_pop(); \ __diag_pop(); \
static long noinline ___se_##prefix##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ static long noinline ___se_##prefix##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
__used; \
static long ___se_##prefix##name(__MAP(x,__SC_LONG,__VA_ARGS__)) static long ___se_##prefix##name(__MAP(x,__SC_LONG,__VA_ARGS__))
#define SC_RISCV_REGS_TO_ARGS(x, ...) \ #define SC_RISCV_REGS_TO_ARGS(x, ...) \
......
...@@ -319,7 +319,7 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n) ...@@ -319,7 +319,7 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
#define __get_kernel_nofault(dst, src, type, err_label) \ #define __get_kernel_nofault(dst, src, type, err_label) \
do { \ do { \
long __kr_err; \ long __kr_err = 0; \
\ \
__get_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \ __get_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \
if (unlikely(__kr_err)) \ if (unlikely(__kr_err)) \
...@@ -328,7 +328,7 @@ do { \ ...@@ -328,7 +328,7 @@ do { \
#define __put_kernel_nofault(dst, src, type, err_label) \ #define __put_kernel_nofault(dst, src, type, err_label) \
do { \ do { \
long __kr_err; \ long __kr_err = 0; \
\ \
__put_user_nocheck(*((type *)(src)), (type *)(dst), __kr_err); \ __put_user_nocheck(*((type *)(src)), (type *)(dst), __kr_err); \
if (unlikely(__kr_err)) \ if (unlikely(__kr_err)) \
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#define AT_L3_CACHEGEOMETRY 47 #define AT_L3_CACHEGEOMETRY 47
/* entries in ARCH_DLINFO */ /* entries in ARCH_DLINFO */
#define AT_VECTOR_SIZE_ARCH 9 #define AT_VECTOR_SIZE_ARCH 10
#define AT_MINSIGSTKSZ 51 #define AT_MINSIGSTKSZ 51
#endif /* _UAPI_ASM_RISCV_AUXVEC_H */ #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
...@@ -74,5 +74,5 @@ quiet_cmd_compat_vdsold = VDSOLD $@ ...@@ -74,5 +74,5 @@ quiet_cmd_compat_vdsold = VDSOLD $@
rm $@.tmp rm $@.tmp
# actual build commands # actual build commands
quiet_cmd_compat_vdsoas = VDSOAS $@ quiet_cmd_compat_vdsoas = VDSOAS $@
cmd_compat_vdsoas = $(COMPAT_CC) $(a_flags) $(COMPAT_CC_FLAGS) -c -o $@ $< cmd_compat_vdsoas = $(COMPAT_CC) $(a_flags) $(COMPAT_CC_FLAGS) -c -o $@ $<
...@@ -80,6 +80,8 @@ static int __patch_insn_set(void *addr, u8 c, size_t len) ...@@ -80,6 +80,8 @@ static int __patch_insn_set(void *addr, u8 c, size_t len)
*/ */
lockdep_assert_held(&text_mutex); lockdep_assert_held(&text_mutex);
preempt_disable();
if (across_pages) if (across_pages)
patch_map(addr + PAGE_SIZE, FIX_TEXT_POKE1); patch_map(addr + PAGE_SIZE, FIX_TEXT_POKE1);
...@@ -92,6 +94,8 @@ static int __patch_insn_set(void *addr, u8 c, size_t len) ...@@ -92,6 +94,8 @@ static int __patch_insn_set(void *addr, u8 c, size_t len)
if (across_pages) if (across_pages)
patch_unmap(FIX_TEXT_POKE1); patch_unmap(FIX_TEXT_POKE1);
preempt_enable();
return 0; return 0;
} }
NOKPROBE_SYMBOL(__patch_insn_set); NOKPROBE_SYMBOL(__patch_insn_set);
...@@ -122,6 +126,8 @@ static int __patch_insn_write(void *addr, const void *insn, size_t len) ...@@ -122,6 +126,8 @@ static int __patch_insn_write(void *addr, const void *insn, size_t len)
if (!riscv_patch_in_stop_machine) if (!riscv_patch_in_stop_machine)
lockdep_assert_held(&text_mutex); lockdep_assert_held(&text_mutex);
preempt_disable();
if (across_pages) if (across_pages)
patch_map(addr + PAGE_SIZE, FIX_TEXT_POKE1); patch_map(addr + PAGE_SIZE, FIX_TEXT_POKE1);
...@@ -134,6 +140,8 @@ static int __patch_insn_write(void *addr, const void *insn, size_t len) ...@@ -134,6 +140,8 @@ static int __patch_insn_write(void *addr, const void *insn, size_t len)
if (across_pages) if (across_pages)
patch_unmap(FIX_TEXT_POKE1); patch_unmap(FIX_TEXT_POKE1);
preempt_enable();
return ret; return ret;
} }
NOKPROBE_SYMBOL(__patch_insn_write); NOKPROBE_SYMBOL(__patch_insn_write);
......
...@@ -27,8 +27,6 @@ ...@@ -27,8 +27,6 @@
#include <asm/vector.h> #include <asm/vector.h>
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
register unsigned long gp_in_global __asm__("gp");
#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK) #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK)
#include <linux/stackprotector.h> #include <linux/stackprotector.h>
unsigned long __stack_chk_guard __read_mostly; unsigned long __stack_chk_guard __read_mostly;
...@@ -37,7 +35,7 @@ EXPORT_SYMBOL(__stack_chk_guard); ...@@ -37,7 +35,7 @@ EXPORT_SYMBOL(__stack_chk_guard);
extern asmlinkage void ret_from_fork(void); extern asmlinkage void ret_from_fork(void);
void arch_cpu_idle(void) void noinstr arch_cpu_idle(void)
{ {
cpu_do_idle(); cpu_do_idle();
} }
...@@ -207,7 +205,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) ...@@ -207,7 +205,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
if (unlikely(args->fn)) { if (unlikely(args->fn)) {
/* Kernel thread */ /* Kernel thread */
memset(childregs, 0, sizeof(struct pt_regs)); memset(childregs, 0, sizeof(struct pt_regs));
childregs->gp = gp_in_global;
/* Supervisor/Machine, irqs on: */ /* Supervisor/Machine, irqs on: */
childregs->status = SR_PP | SR_PIE; childregs->status = SR_PP | SR_PIE;
......
...@@ -119,6 +119,13 @@ static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec) ...@@ -119,6 +119,13 @@ static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec)
struct __sc_riscv_v_state __user *state = sc_vec; struct __sc_riscv_v_state __user *state = sc_vec;
void __user *datap; void __user *datap;
/*
* Mark the vstate as clean prior performing the actual copy,
* to avoid getting the vstate incorrectly clobbered by the
* discarded vector state.
*/
riscv_v_vstate_set_restore(current, regs);
/* Copy everything of __sc_riscv_v_state except datap. */ /* Copy everything of __sc_riscv_v_state except datap. */
err = __copy_from_user(&current->thread.vstate, &state->v_state, err = __copy_from_user(&current->thread.vstate, &state->v_state,
offsetof(struct __riscv_v_ext_state, datap)); offsetof(struct __riscv_v_ext_state, datap));
...@@ -133,13 +140,7 @@ static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec) ...@@ -133,13 +140,7 @@ static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec)
* Copy the whole vector content from user space datap. Use * Copy the whole vector content from user space datap. Use
* copy_from_user to prevent information leak. * copy_from_user to prevent information leak.
*/ */
err = copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize); return copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize);
if (unlikely(err))
return err;
riscv_v_vstate_set_restore(current, regs);
return err;
} }
#else #else
#define save_v_state(task, regs) (0) #define save_v_state(task, regs) (0)
......
...@@ -122,7 +122,7 @@ void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr) ...@@ -122,7 +122,7 @@ void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
print_vma_addr(KERN_CONT " in ", instruction_pointer(regs)); print_vma_addr(KERN_CONT " in ", instruction_pointer(regs));
pr_cont("\n"); pr_cont("\n");
__show_regs(regs); __show_regs(regs);
dump_instr(KERN_EMERG, regs); dump_instr(KERN_INFO, regs);
} }
force_sig_fault(signo, code, (void __user *)addr); force_sig_fault(signo, code, (void __user *)addr);
......
...@@ -37,6 +37,7 @@ endif ...@@ -37,6 +37,7 @@ endif
# Disable -pg to prevent insert call site # Disable -pg to prevent insert call site
CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS) CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS)
CFLAGS_REMOVE_hwprobe.o = $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS)
# Disable profiling and instrumentation for VDSO code # Disable profiling and instrumentation for VDSO code
GCOV_PROFILE := n GCOV_PROFILE := n
......
...@@ -99,7 +99,7 @@ static void __ipi_flush_tlb_range_asid(void *info) ...@@ -99,7 +99,7 @@ static void __ipi_flush_tlb_range_asid(void *info)
local_flush_tlb_range_asid(d->start, d->size, d->stride, d->asid); local_flush_tlb_range_asid(d->start, d->size, d->stride, d->asid);
} }
static void __flush_tlb_range(struct cpumask *cmask, unsigned long asid, static void __flush_tlb_range(const struct cpumask *cmask, unsigned long asid,
unsigned long start, unsigned long size, unsigned long start, unsigned long size,
unsigned long stride) unsigned long stride)
{ {
...@@ -200,7 +200,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, ...@@ -200,7 +200,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
void flush_tlb_kernel_range(unsigned long start, unsigned long end) void flush_tlb_kernel_range(unsigned long start, unsigned long end)
{ {
__flush_tlb_range((struct cpumask *)cpu_online_mask, FLUSH_TLB_NO_ASID, __flush_tlb_range(cpu_online_mask, FLUSH_TLB_NO_ASID,
start, end - start, PAGE_SIZE); start, end - start, PAGE_SIZE);
} }
......
...@@ -313,6 +313,10 @@ static int riscv_pmu_event_init(struct perf_event *event) ...@@ -313,6 +313,10 @@ static int riscv_pmu_event_init(struct perf_event *event)
u64 event_config = 0; u64 event_config = 0;
uint64_t cmask; uint64_t cmask;
/* driver does not support branch stack sampling */
if (has_branch_stack(event))
return -EOPNOTSUPP;
hwc->flags = 0; hwc->flags = 0;
mapped_event = rvpmu->event_map(event, &event_config); mapped_event = rvpmu->event_map(event, &event_config);
if (mapped_event < 0) { if (mapped_event < 0) {
......
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