mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
Merge patch "drivers: perf: Do not broadcast to other cpus when starting a counter"
This is really just a single patch, but since the offending fix hasn't yet made it to my for-next I'm merging it here. Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
commit
68444b93ed
16 changed files with 78 additions and 43 deletions
|
@ -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
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
|
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)
|
||||||
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);
|
||||||
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 {
|
||||||
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 */
|
||||||
|
|
|
@ -79,7 +79,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
|
||||||
static void ___do_softirq(struct pt_regs *regs)
|
static void ___do_softirq(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
__do_softirq();
|
__do_softirq();
|
||||||
|
@ -92,7 +92,7 @@ void do_softirq_own_stack(void)
|
||||||
else
|
else
|
||||||
__do_softirq();
|
__do_softirq();
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK */
|
#endif /* CONFIG_SOFTIRQ_ON_OWN_STACK */
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static void init_irq_scs(void) {}
|
static void init_irq_scs(void) {}
|
||||||
|
|
|
@ -174,19 +174,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,
|
||||||
/* 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 @@
|
||||||
#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>
|
||||||
|
@ -253,22 +255,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)
|
||||||
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,16 +510,18 @@ static void pmu_sbi_set_scounteren(void *arg)
|
||||||
{
|
{
|
||||||
struct perf_event *event = (struct perf_event *)arg;
|
struct perf_event *event = (struct perf_event *)arg;
|
||||||
|
|
||||||
csr_write(CSR_SCOUNTEREN,
|
if (event->hw.idx != -1)
|
||||||
csr_read(CSR_SCOUNTEREN) | (1 << pmu_sbi_csr_index(event)));
|
csr_write(CSR_SCOUNTEREN,
|
||||||
|
csr_read(CSR_SCOUNTEREN) | (1 << pmu_sbi_csr_index(event)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pmu_sbi_reset_scounteren(void *arg)
|
static void pmu_sbi_reset_scounteren(void *arg)
|
||||||
{
|
{
|
||||||
struct perf_event *event = (struct perf_event *)arg;
|
struct perf_event *event = (struct perf_event *)arg;
|
||||||
|
|
||||||
csr_write(CSR_SCOUNTEREN,
|
if (event->hw.idx != -1)
|
||||||
csr_read(CSR_SCOUNTEREN) & ~(1 << pmu_sbi_csr_index(event)));
|
csr_write(CSR_SCOUNTEREN,
|
||||||
|
csr_read(CSR_SCOUNTEREN) & ~(1 << pmu_sbi_csr_index(event)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pmu_sbi_ctr_start(struct perf_event *event, u64 ival)
|
static void pmu_sbi_ctr_start(struct perf_event *event, u64 ival)
|
||||||
|
|
|
@ -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) $^
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// 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"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// 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"
|
||||||
|
|
Loading…
Add table
Reference in a new issue