Commit b82fbd8f authored by Linus Torvalds's avatar Linus Torvalds

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

Pull RISC-V fixes from Palmer Dabbelt:

 - A handful of build fixes

 - A fix to avoid mixing up user/kernel-mode breakpoints, which can
   manifest as a hang when mixing k/uprobes with other breakpoint
   sources

 - A fix to avoid double-allocting crash kernel memory

 - A fix for tracefs syscall name mangling, which was causing syscalls
   not to show up in tracefs

 - A fix to the perf driver to enable the hw events when selected, which
   can trigger a BUG on some userspace access patterns

* tag 'riscv-for-linus-6.6-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
  drivers: perf: Fix panic in riscv SBI mmap support
  riscv: Fix ftrace syscall handling which are now prefixed with __riscv_
  RISC-V: Fix wrong use of CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK
  riscv: kdump: fix crashkernel reserving problem on RISC-V
  riscv: Remove duplicate objcopy flag
  riscv: signal: fix sigaltstack frame size checking
  riscv: errata: andes: Makefile: Fix randconfig build issue
  riscv: Only consider swbp/ss handlers for correct privileged mode
  riscv: kselftests: Fix mm build by removing testcases subdirectory
parents 17325a21 3fec3233
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
# for more details. # for more details.
# #
OBJCOPYFLAGS := -O binary
LDFLAGS_vmlinux := -z norelro LDFLAGS_vmlinux := -z norelro
ifeq ($(CONFIG_RELOCATABLE),y) ifeq ($(CONFIG_RELOCATABLE),y)
LDFLAGS_vmlinux += -shared -Bsymbolic -z notext --emit-relocs LDFLAGS_vmlinux += -shared -Bsymbolic -z notext --emit-relocs
......
ifdef CONFIG_RISCV_ALTERNATIVE_EARLY
CFLAGS_errata.o := -mcmodel=medany
endif
obj-y += errata.o obj-y += errata.o
...@@ -31,6 +31,27 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) ...@@ -31,6 +31,27 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
return addr; return addr;
} }
/*
* Let's do like x86/arm64 and ignore the compat syscalls.
*/
#define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
{
return is_compat_task();
}
#define ARCH_HAS_SYSCALL_MATCH_SYM_NAME
static inline bool arch_syscall_match_sym_name(const char *sym,
const char *name)
{
/*
* Since all syscall functions have __riscv_ prefix, we must skip it.
* However, as we described above, we decided to ignore compat
* syscalls, so we don't care about __riscv_compat_ prefix here.
*/
return !strcmp(sym + 8, name);
}
struct dyn_arch_ftrace { struct dyn_arch_ftrace {
}; };
#endif #endif
......
...@@ -40,6 +40,15 @@ void arch_remove_kprobe(struct kprobe *p); ...@@ -40,6 +40,15 @@ void arch_remove_kprobe(struct kprobe *p);
int kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr); int kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr);
bool kprobe_breakpoint_handler(struct pt_regs *regs); bool kprobe_breakpoint_handler(struct pt_regs *regs);
bool kprobe_single_step_handler(struct pt_regs *regs); bool kprobe_single_step_handler(struct pt_regs *regs);
#else
static inline bool kprobe_breakpoint_handler(struct pt_regs *regs)
{
return false;
}
static inline bool kprobe_single_step_handler(struct pt_regs *regs)
{
return false;
}
#endif /* CONFIG_KPROBES */ #endif /* CONFIG_KPROBES */
#endif /* _ASM_RISCV_KPROBES_H */ #endif /* _ASM_RISCV_KPROBES_H */
...@@ -34,7 +34,18 @@ struct arch_uprobe { ...@@ -34,7 +34,18 @@ struct arch_uprobe {
bool simulate; bool simulate;
}; };
#ifdef CONFIG_UPROBES
bool uprobe_breakpoint_handler(struct pt_regs *regs); bool uprobe_breakpoint_handler(struct pt_regs *regs);
bool uprobe_single_step_handler(struct pt_regs *regs); bool uprobe_single_step_handler(struct pt_regs *regs);
#else
static inline bool uprobe_breakpoint_handler(struct pt_regs *regs)
{
return false;
}
static inline bool uprobe_single_step_handler(struct pt_regs *regs)
{
return false;
}
#endif /* CONFIG_UPROBES */
#endif /* _ASM_RISCV_UPROBES_H */ #endif /* _ASM_RISCV_UPROBES_H */
...@@ -60,7 +60,7 @@ static void init_irq_stacks(void) ...@@ -60,7 +60,7 @@ static void init_irq_stacks(void)
} }
#endif /* CONFIG_VMAP_STACK */ #endif /* CONFIG_VMAP_STACK */
#ifdef CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK #ifdef CONFIG_SOFTIRQ_ON_OWN_STACK
void do_softirq_own_stack(void) void do_softirq_own_stack(void)
{ {
#ifdef CONFIG_IRQ_STACKS #ifdef CONFIG_IRQ_STACKS
...@@ -92,7 +92,7 @@ void do_softirq_own_stack(void) ...@@ -92,7 +92,7 @@ void do_softirq_own_stack(void)
#endif #endif
__do_softirq(); __do_softirq();
} }
#endif /* CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK */ #endif /* CONFIG_SOFTIRQ_ON_OWN_STACK */
#else #else
static void init_irq_stacks(void) {} static void init_irq_stacks(void) {}
......
...@@ -173,19 +173,6 @@ static void __init init_resources(void) ...@@ -173,19 +173,6 @@ static void __init init_resources(void)
if (ret < 0) if (ret < 0)
goto error; goto error;
#ifdef CONFIG_KEXEC_CORE
if (crashk_res.start != crashk_res.end) {
ret = add_resource(&iomem_resource, &crashk_res);
if (ret < 0)
goto error;
}
if (crashk_low_res.start != crashk_low_res.end) {
ret = add_resource(&iomem_resource, &crashk_low_res);
if (ret < 0)
goto error;
}
#endif
#ifdef CONFIG_CRASH_DUMP #ifdef CONFIG_CRASH_DUMP
if (elfcorehdr_size > 0) { if (elfcorehdr_size > 0) {
elfcorehdr_res.start = elfcorehdr_addr; elfcorehdr_res.start = elfcorehdr_addr;
......
...@@ -311,13 +311,6 @@ static inline void __user *get_sigframe(struct ksignal *ksig, ...@@ -311,13 +311,6 @@ static inline void __user *get_sigframe(struct ksignal *ksig,
/* Align the stack frame. */ /* Align the stack frame. */
sp &= ~0xfUL; sp &= ~0xfUL;
/*
* Fail if the size of the altstack is not large enough for the
* sigframe construction.
*/
if (current->sas_ss_size && sp < current->sas_ss_sp)
return (void __user __force *)-1UL;
return (void __user *)sp; return (void __user *)sp;
} }
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#include <linux/kdebug.h> #include <linux/kdebug.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/kprobes.h> #include <linux/kprobes.h>
#include <linux/uprobes.h>
#include <asm/uprobes.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/irq.h> #include <linux/irq.h>
...@@ -247,22 +249,28 @@ static inline unsigned long get_break_insn_length(unsigned long pc) ...@@ -247,22 +249,28 @@ static inline unsigned long get_break_insn_length(unsigned long pc)
return GET_INSN_LENGTH(insn); return GET_INSN_LENGTH(insn);
} }
static bool probe_single_step_handler(struct pt_regs *regs)
{
bool user = user_mode(regs);
return user ? uprobe_single_step_handler(regs) : kprobe_single_step_handler(regs);
}
static bool probe_breakpoint_handler(struct pt_regs *regs)
{
bool user = user_mode(regs);
return user ? uprobe_breakpoint_handler(regs) : kprobe_breakpoint_handler(regs);
}
void handle_break(struct pt_regs *regs) void handle_break(struct pt_regs *regs)
{ {
#ifdef CONFIG_KPROBES if (probe_single_step_handler(regs))
if (kprobe_single_step_handler(regs))
return; return;
if (kprobe_breakpoint_handler(regs)) if (probe_breakpoint_handler(regs))
return;
#endif
#ifdef CONFIG_UPROBES
if (uprobe_single_step_handler(regs))
return; return;
if (uprobe_breakpoint_handler(regs))
return;
#endif
current->thread.bad_cause = regs->cause; current->thread.bad_cause = regs->cause;
if (user_mode(regs)) if (user_mode(regs))
......
...@@ -23,7 +23,8 @@ static bool riscv_perf_user_access(struct perf_event *event) ...@@ -23,7 +23,8 @@ static bool riscv_perf_user_access(struct perf_event *event)
return ((event->attr.type == PERF_TYPE_HARDWARE) || return ((event->attr.type == PERF_TYPE_HARDWARE) ||
(event->attr.type == PERF_TYPE_HW_CACHE) || (event->attr.type == PERF_TYPE_HW_CACHE) ||
(event->attr.type == PERF_TYPE_RAW)) && (event->attr.type == PERF_TYPE_RAW)) &&
!!(event->hw.flags & PERF_EVENT_FLAG_USER_READ_CNT); !!(event->hw.flags & PERF_EVENT_FLAG_USER_READ_CNT) &&
(event->hw.idx != -1);
} }
void arch_perf_update_userpage(struct perf_event *event, void arch_perf_update_userpage(struct perf_event *event,
......
...@@ -510,6 +510,7 @@ static void pmu_sbi_set_scounteren(void *arg) ...@@ -510,6 +510,7 @@ static void pmu_sbi_set_scounteren(void *arg)
{ {
struct perf_event *event = (struct perf_event *)arg; struct perf_event *event = (struct perf_event *)arg;
if (event->hw.idx != -1)
csr_write(CSR_SCOUNTEREN, csr_write(CSR_SCOUNTEREN,
csr_read(CSR_SCOUNTEREN) | (1 << pmu_sbi_csr_index(event))); csr_read(CSR_SCOUNTEREN) | (1 << pmu_sbi_csr_index(event)));
} }
...@@ -518,6 +519,7 @@ static void pmu_sbi_reset_scounteren(void *arg) ...@@ -518,6 +519,7 @@ static void pmu_sbi_reset_scounteren(void *arg)
{ {
struct perf_event *event = (struct perf_event *)arg; struct perf_event *event = (struct perf_event *)arg;
if (event->hw.idx != -1)
csr_write(CSR_SCOUNTEREN, csr_write(CSR_SCOUNTEREN,
csr_read(CSR_SCOUNTEREN) & ~(1 << pmu_sbi_csr_index(event))); csr_read(CSR_SCOUNTEREN) & ~(1 << pmu_sbi_csr_index(event)));
} }
...@@ -541,7 +543,8 @@ static void pmu_sbi_ctr_start(struct perf_event *event, u64 ival) ...@@ -541,7 +543,8 @@ static void pmu_sbi_ctr_start(struct perf_event *event, u64 ival)
if ((hwc->flags & PERF_EVENT_FLAG_USER_ACCESS) && if ((hwc->flags & PERF_EVENT_FLAG_USER_ACCESS) &&
(hwc->flags & PERF_EVENT_FLAG_USER_READ_CNT)) (hwc->flags & PERF_EVENT_FLAG_USER_READ_CNT))
pmu_sbi_set_scounteren((void *)event); on_each_cpu_mask(mm_cpumask(event->owner->mm),
pmu_sbi_set_scounteren, (void *)event, 1);
} }
static void pmu_sbi_ctr_stop(struct perf_event *event, unsigned long flag) static void pmu_sbi_ctr_stop(struct perf_event *event, unsigned long flag)
...@@ -551,7 +554,8 @@ static void pmu_sbi_ctr_stop(struct perf_event *event, unsigned long flag) ...@@ -551,7 +554,8 @@ static void pmu_sbi_ctr_stop(struct perf_event *event, unsigned long flag)
if ((hwc->flags & PERF_EVENT_FLAG_USER_ACCESS) && if ((hwc->flags & PERF_EVENT_FLAG_USER_ACCESS) &&
(hwc->flags & PERF_EVENT_FLAG_USER_READ_CNT)) (hwc->flags & PERF_EVENT_FLAG_USER_READ_CNT))
pmu_sbi_reset_scounteren((void *)event); on_each_cpu_mask(mm_cpumask(event->owner->mm),
pmu_sbi_reset_scounteren, (void *)event, 1);
ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP, hwc->idx, 1, flag, 0, 0, 0); ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP, hwc->idx, 1, flag, 0, 0, 0);
if (ret.error && (ret.error != SBI_ERR_ALREADY_STOPPED) && if (ret.error && (ret.error != SBI_ERR_ALREADY_STOPPED) &&
......
...@@ -5,11 +5,11 @@ ...@@ -5,11 +5,11 @@
# Additional include paths needed by kselftest.h and local headers # Additional include paths needed by kselftest.h and local headers
CFLAGS += -D_GNU_SOURCE -std=gnu99 -I. CFLAGS += -D_GNU_SOURCE -std=gnu99 -I.
TEST_GEN_FILES := testcases/mmap_default testcases/mmap_bottomup TEST_GEN_FILES := mmap_default mmap_bottomup
TEST_PROGS := testcases/run_mmap.sh TEST_PROGS := run_mmap.sh
include ../../lib.mk include ../../lib.mk
$(OUTPUT)/mm: testcases/mmap_default.c testcases/mmap_bottomup.c testcases/mmap_tests.h $(OUTPUT)/mm: mmap_default.c mmap_bottomup.c mmap_tests.h
$(CC) -o$@ $(CFLAGS) $(LDFLAGS) $^ $(CC) -o$@ $(CFLAGS) $(LDFLAGS) $^
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
#include <sys/mman.h> #include <sys/mman.h>
#include <testcases/mmap_test.h> #include <mmap_test.h>
#include "../../kselftest_harness.h" #include "../../kselftest_harness.h"
......
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
#include <sys/mman.h> #include <sys/mman.h>
#include <testcases/mmap_test.h> #include <mmap_test.h>
#include "../../kselftest_harness.h" #include "../../kselftest_harness.h"
......
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