Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0806ebd9 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge branch 'perf/core' of...

parents 090f7204 feef47d0
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -137,6 +137,17 @@ config HAVE_HW_BREAKPOINT
	bool
	bool
	depends on PERF_EVENTS
	depends on PERF_EVENTS


config HAVE_MIXED_BREAKPOINTS_REGS
	bool
	depends on HAVE_HW_BREAKPOINT
	help
	  Depending on the arch implementation of hardware breakpoints,
	  some of them have separate registers for data and instruction
	  breakpoints addresses, others have mixed registers to store
	  them but define the access type in a control register.
	  Select this option if your arch implements breakpoints under the
	  latter fashion.

config HAVE_USER_RETURN_NOTIFIER
config HAVE_USER_RETURN_NOTIFIER
	bool
	bool


+1 −0
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@ config SUPERH32
	select HAVE_FUNCTION_GRAPH_TRACER
	select HAVE_FUNCTION_GRAPH_TRACER
	select HAVE_ARCH_KGDB
	select HAVE_ARCH_KGDB
	select HAVE_HW_BREAKPOINT
	select HAVE_HW_BREAKPOINT
	select HAVE_MIXED_BREAKPOINTS_REGS
	select PERF_EVENTS if HAVE_HW_BREAKPOINT
	select PERF_EVENTS if HAVE_HW_BREAKPOINT
	select ARCH_HIBERNATION_POSSIBLE if MMU
	select ARCH_HIBERNATION_POSSIBLE if MMU


+7 −3
Original line number Original line Diff line number Diff line
@@ -46,10 +46,14 @@ struct pmu;
/* Maximum number of UBC channels */
/* Maximum number of UBC channels */
#define HBP_NUM		2
#define HBP_NUM		2


static inline int hw_breakpoint_slots(int type)
{
	return HBP_NUM;
}

/* arch/sh/kernel/hw_breakpoint.c */
/* arch/sh/kernel/hw_breakpoint.c */
extern int arch_check_va_in_userspace(unsigned long va, u16 hbp_len);
extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
					 struct task_struct *tsk);
extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
					   unsigned long val, void *data);
					   unsigned long val, void *data);


+7 −27
Original line number Original line Diff line number Diff line
@@ -119,26 +119,17 @@ static int get_hbp_len(u16 hbp_len)
	return len_in_bytes;
	return len_in_bytes;
}
}


/*
 * Check for virtual address in user space.
 */
int arch_check_va_in_userspace(unsigned long va, u16 hbp_len)
{
	unsigned int len;

	len = get_hbp_len(hbp_len);

	return (va <= TASK_SIZE - len);
}

/*
/*
 * Check for virtual address in kernel space.
 * Check for virtual address in kernel space.
 */
 */
static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
int arch_check_bp_in_kernelspace(struct perf_event *bp)
{
{
	unsigned int len;
	unsigned int len;
	unsigned long va;
	struct arch_hw_breakpoint *info = counter_arch_bp(bp);


	len = get_hbp_len(hbp_len);
	va = info->address;
	len = get_hbp_len(info->len);


	return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
	return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
}
}
@@ -226,8 +217,7 @@ static int arch_build_bp_info(struct perf_event *bp)
/*
/*
 * Validate the arch-specific HW Breakpoint register settings
 * Validate the arch-specific HW Breakpoint register settings
 */
 */
int arch_validate_hwbkpt_settings(struct perf_event *bp,
int arch_validate_hwbkpt_settings(struct perf_event *bp)
				  struct task_struct *tsk)
{
{
	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
	unsigned int align;
	unsigned int align;
@@ -270,15 +260,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
	if (info->address & align)
	if (info->address & align)
		return -EINVAL;
		return -EINVAL;


	/* Check that the virtual address is in the proper range */
	if (tsk) {
		if (!arch_check_va_in_userspace(info->address, info->len))
			return -EFAULT;
	} else {
		if (!arch_check_va_in_kernelspace(info->address, info->len))
			return -EFAULT;
	}

	return 0;
	return 0;
}
}


@@ -363,8 +344,7 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args)
		perf_bp_event(bp, args->regs);
		perf_bp_event(bp, args->regs);


		/* Deliver the signal to userspace */
		/* Deliver the signal to userspace */
		if (arch_check_va_in_userspace(bp->attr.bp_addr,
		if (!arch_check_bp_in_kernelspace(bp)) {
					       bp->attr.bp_len)) {
			siginfo_t info;
			siginfo_t info;


			info.si_signo = args->signr;
			info.si_signo = args->signr;
+1 −1
Original line number Original line Diff line number Diff line
@@ -85,7 +85,7 @@ static int set_single_step(struct task_struct *tsk, unsigned long addr)


	bp = thread->ptrace_bps[0];
	bp = thread->ptrace_bps[0];
	if (!bp) {
	if (!bp) {
		hw_breakpoint_init(&attr);
		ptrace_breakpoint_init(&attr);


		attr.bp_addr = addr;
		attr.bp_addr = addr;
		attr.bp_len = HW_BREAKPOINT_LEN_2;
		attr.bp_len = HW_BREAKPOINT_LEN_2;
Loading