xref: /linux/arch/sh/kernel/hw_breakpoint.c (revision 105244ec95590f5f12a90d974650ab5c7bc8ec79)
109a07294SPaul Mundt /*
209a07294SPaul Mundt  * arch/sh/kernel/hw_breakpoint.c
309a07294SPaul Mundt  *
409a07294SPaul Mundt  * Unified kernel/user-space hardware breakpoint facility for the on-chip UBC.
509a07294SPaul Mundt  *
64352fc1bSPaul Mundt  * Copyright (C) 2009 - 2010  Paul Mundt
709a07294SPaul Mundt  *
809a07294SPaul Mundt  * This file is subject to the terms and conditions of the GNU General Public
909a07294SPaul Mundt  * License.  See the file "COPYING" in the main directory of this archive
1009a07294SPaul Mundt  * for more details.
1109a07294SPaul Mundt  */
1209a07294SPaul Mundt #include <linux/init.h>
1309a07294SPaul Mundt #include <linux/perf_event.h>
1409a07294SPaul Mundt #include <linux/hw_breakpoint.h>
1509a07294SPaul Mundt #include <linux/percpu.h>
1609a07294SPaul Mundt #include <linux/kallsyms.h>
1709a07294SPaul Mundt #include <linux/notifier.h>
1809a07294SPaul Mundt #include <linux/kprobes.h>
1909a07294SPaul Mundt #include <linux/kdebug.h>
2009a07294SPaul Mundt #include <linux/io.h>
214352fc1bSPaul Mundt #include <linux/clk.h>
2209a07294SPaul Mundt #include <asm/hw_breakpoint.h>
2309a07294SPaul Mundt #include <asm/mmu_context.h>
2434d0b5afSPaul Mundt #include <asm/ptrace.h>
2509a07294SPaul Mundt 
2609a07294SPaul Mundt /*
2709a07294SPaul Mundt  * Stores the breakpoints currently in use on each breakpoint address
2809a07294SPaul Mundt  * register for each cpus
2909a07294SPaul Mundt  */
3009a07294SPaul Mundt static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]);
3109a07294SPaul Mundt 
324352fc1bSPaul Mundt /*
334352fc1bSPaul Mundt  * A dummy placeholder for early accesses until the CPUs get a chance to
344352fc1bSPaul Mundt  * register their UBCs later in the boot process.
354352fc1bSPaul Mundt  */
364352fc1bSPaul Mundt static struct sh_ubc ubc_dummy = { .num_events = 0 };
3709a07294SPaul Mundt 
384352fc1bSPaul Mundt static struct sh_ubc *sh_ubc __read_mostly = &ubc_dummy;
3909a07294SPaul Mundt 
4009a07294SPaul Mundt /*
4109a07294SPaul Mundt  * Install a perf counter breakpoint.
4209a07294SPaul Mundt  *
4309a07294SPaul Mundt  * We seek a free UBC channel and use it for this breakpoint.
4409a07294SPaul Mundt  *
4509a07294SPaul Mundt  * Atomic: we hold the counter->ctx->lock and we only handle variables
4609a07294SPaul Mundt  * and registers local to this cpu.
4709a07294SPaul Mundt  */
4809a07294SPaul Mundt int arch_install_hw_breakpoint(struct perf_event *bp)
4909a07294SPaul Mundt {
5009a07294SPaul Mundt 	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
5109a07294SPaul Mundt 	int i;
5209a07294SPaul Mundt 
534352fc1bSPaul Mundt 	for (i = 0; i < sh_ubc->num_events; i++) {
5409a07294SPaul Mundt 		struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
5509a07294SPaul Mundt 
5609a07294SPaul Mundt 		if (!*slot) {
5709a07294SPaul Mundt 			*slot = bp;
5809a07294SPaul Mundt 			break;
5909a07294SPaul Mundt 		}
6009a07294SPaul Mundt 	}
6109a07294SPaul Mundt 
624352fc1bSPaul Mundt 	if (WARN_ONCE(i == sh_ubc->num_events, "Can't find any breakpoint slot"))
6309a07294SPaul Mundt 		return -EBUSY;
6409a07294SPaul Mundt 
654352fc1bSPaul Mundt 	clk_enable(sh_ubc->clk);
664352fc1bSPaul Mundt 	sh_ubc->enable(info, i);
6709a07294SPaul Mundt 
6809a07294SPaul Mundt 	return 0;
6909a07294SPaul Mundt }
7009a07294SPaul Mundt 
7109a07294SPaul Mundt /*
7209a07294SPaul Mundt  * Uninstall the breakpoint contained in the given counter.
7309a07294SPaul Mundt  *
7409a07294SPaul Mundt  * First we search the debug address register it uses and then we disable
7509a07294SPaul Mundt  * it.
7609a07294SPaul Mundt  *
7709a07294SPaul Mundt  * Atomic: we hold the counter->ctx->lock and we only handle variables
7809a07294SPaul Mundt  * and registers local to this cpu.
7909a07294SPaul Mundt  */
8009a07294SPaul Mundt void arch_uninstall_hw_breakpoint(struct perf_event *bp)
8109a07294SPaul Mundt {
8209a07294SPaul Mundt 	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
8309a07294SPaul Mundt 	int i;
8409a07294SPaul Mundt 
854352fc1bSPaul Mundt 	for (i = 0; i < sh_ubc->num_events; i++) {
8609a07294SPaul Mundt 		struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
8709a07294SPaul Mundt 
8809a07294SPaul Mundt 		if (*slot == bp) {
8909a07294SPaul Mundt 			*slot = NULL;
9009a07294SPaul Mundt 			break;
9109a07294SPaul Mundt 		}
9209a07294SPaul Mundt 	}
9309a07294SPaul Mundt 
944352fc1bSPaul Mundt 	if (WARN_ONCE(i == sh_ubc->num_events, "Can't find any breakpoint slot"))
9509a07294SPaul Mundt 		return;
9609a07294SPaul Mundt 
974352fc1bSPaul Mundt 	sh_ubc->disable(info, i);
984352fc1bSPaul Mundt 	clk_disable(sh_ubc->clk);
9909a07294SPaul Mundt }
10009a07294SPaul Mundt 
10109a07294SPaul Mundt static int get_hbp_len(u16 hbp_len)
10209a07294SPaul Mundt {
10309a07294SPaul Mundt 	unsigned int len_in_bytes = 0;
10409a07294SPaul Mundt 
10509a07294SPaul Mundt 	switch (hbp_len) {
10609a07294SPaul Mundt 	case SH_BREAKPOINT_LEN_1:
10709a07294SPaul Mundt 		len_in_bytes = 1;
10809a07294SPaul Mundt 		break;
10909a07294SPaul Mundt 	case SH_BREAKPOINT_LEN_2:
11009a07294SPaul Mundt 		len_in_bytes = 2;
11109a07294SPaul Mundt 		break;
11209a07294SPaul Mundt 	case SH_BREAKPOINT_LEN_4:
11309a07294SPaul Mundt 		len_in_bytes = 4;
11409a07294SPaul Mundt 		break;
11509a07294SPaul Mundt 	case SH_BREAKPOINT_LEN_8:
11609a07294SPaul Mundt 		len_in_bytes = 8;
11709a07294SPaul Mundt 		break;
11809a07294SPaul Mundt 	}
11909a07294SPaul Mundt 	return len_in_bytes;
12009a07294SPaul Mundt }
12109a07294SPaul Mundt 
12209a07294SPaul Mundt /*
12309a07294SPaul Mundt  * Check for virtual address in user space.
12409a07294SPaul Mundt  */
12509a07294SPaul Mundt int arch_check_va_in_userspace(unsigned long va, u16 hbp_len)
12609a07294SPaul Mundt {
12709a07294SPaul Mundt 	unsigned int len;
12809a07294SPaul Mundt 
12909a07294SPaul Mundt 	len = get_hbp_len(hbp_len);
13009a07294SPaul Mundt 
13109a07294SPaul Mundt 	return (va <= TASK_SIZE - len);
13209a07294SPaul Mundt }
13309a07294SPaul Mundt 
13409a07294SPaul Mundt /*
13509a07294SPaul Mundt  * Check for virtual address in kernel space.
13609a07294SPaul Mundt  */
13709a07294SPaul Mundt static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
13809a07294SPaul Mundt {
13909a07294SPaul Mundt 	unsigned int len;
14009a07294SPaul Mundt 
14109a07294SPaul Mundt 	len = get_hbp_len(hbp_len);
14209a07294SPaul Mundt 
14309a07294SPaul Mundt 	return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
14409a07294SPaul Mundt }
14509a07294SPaul Mundt 
14609a07294SPaul Mundt int arch_bp_generic_fields(int sh_len, int sh_type,
14709a07294SPaul Mundt 			   int *gen_len, int *gen_type)
14809a07294SPaul Mundt {
14909a07294SPaul Mundt 	/* Len */
15009a07294SPaul Mundt 	switch (sh_len) {
15109a07294SPaul Mundt 	case SH_BREAKPOINT_LEN_1:
15209a07294SPaul Mundt 		*gen_len = HW_BREAKPOINT_LEN_1;
15309a07294SPaul Mundt 		break;
15409a07294SPaul Mundt 	case SH_BREAKPOINT_LEN_2:
15509a07294SPaul Mundt 		*gen_len = HW_BREAKPOINT_LEN_2;
15609a07294SPaul Mundt 		break;
15709a07294SPaul Mundt 	case SH_BREAKPOINT_LEN_4:
15809a07294SPaul Mundt 		*gen_len = HW_BREAKPOINT_LEN_4;
15909a07294SPaul Mundt 		break;
16009a07294SPaul Mundt 	case SH_BREAKPOINT_LEN_8:
16109a07294SPaul Mundt 		*gen_len = HW_BREAKPOINT_LEN_8;
16209a07294SPaul Mundt 		break;
16309a07294SPaul Mundt 	default:
16409a07294SPaul Mundt 		return -EINVAL;
16509a07294SPaul Mundt 	}
16609a07294SPaul Mundt 
16709a07294SPaul Mundt 	/* Type */
16809a07294SPaul Mundt 	switch (sh_type) {
16909a07294SPaul Mundt 	case SH_BREAKPOINT_READ:
17009a07294SPaul Mundt 		*gen_type = HW_BREAKPOINT_R;
17109a07294SPaul Mundt 	case SH_BREAKPOINT_WRITE:
17209a07294SPaul Mundt 		*gen_type = HW_BREAKPOINT_W;
17309a07294SPaul Mundt 		break;
17409a07294SPaul Mundt 	case SH_BREAKPOINT_RW:
17509a07294SPaul Mundt 		*gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
17609a07294SPaul Mundt 		break;
17709a07294SPaul Mundt 	default:
17809a07294SPaul Mundt 		return -EINVAL;
17909a07294SPaul Mundt 	}
18009a07294SPaul Mundt 
18109a07294SPaul Mundt 	return 0;
18209a07294SPaul Mundt }
18309a07294SPaul Mundt 
18409a07294SPaul Mundt static int arch_build_bp_info(struct perf_event *bp)
18509a07294SPaul Mundt {
18609a07294SPaul Mundt 	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
18709a07294SPaul Mundt 
18809a07294SPaul Mundt 	info->address = bp->attr.bp_addr;
18909a07294SPaul Mundt 
19009a07294SPaul Mundt 	/* Len */
19109a07294SPaul Mundt 	switch (bp->attr.bp_len) {
19209a07294SPaul Mundt 	case HW_BREAKPOINT_LEN_1:
19309a07294SPaul Mundt 		info->len = SH_BREAKPOINT_LEN_1;
19409a07294SPaul Mundt 		break;
19509a07294SPaul Mundt 	case HW_BREAKPOINT_LEN_2:
19609a07294SPaul Mundt 		info->len = SH_BREAKPOINT_LEN_2;
19709a07294SPaul Mundt 		break;
19809a07294SPaul Mundt 	case HW_BREAKPOINT_LEN_4:
19909a07294SPaul Mundt 		info->len = SH_BREAKPOINT_LEN_4;
20009a07294SPaul Mundt 		break;
20109a07294SPaul Mundt 	case HW_BREAKPOINT_LEN_8:
20209a07294SPaul Mundt 		info->len = SH_BREAKPOINT_LEN_8;
20309a07294SPaul Mundt 		break;
20409a07294SPaul Mundt 	default:
20509a07294SPaul Mundt 		return -EINVAL;
20609a07294SPaul Mundt 	}
20709a07294SPaul Mundt 
20809a07294SPaul Mundt 	/* Type */
20909a07294SPaul Mundt 	switch (bp->attr.bp_type) {
21009a07294SPaul Mundt 	case HW_BREAKPOINT_R:
21109a07294SPaul Mundt 		info->type = SH_BREAKPOINT_READ;
21209a07294SPaul Mundt 		break;
21309a07294SPaul Mundt 	case HW_BREAKPOINT_W:
21409a07294SPaul Mundt 		info->type = SH_BREAKPOINT_WRITE;
21509a07294SPaul Mundt 		break;
21609a07294SPaul Mundt 	case HW_BREAKPOINT_W | HW_BREAKPOINT_R:
21709a07294SPaul Mundt 		info->type = SH_BREAKPOINT_RW;
21809a07294SPaul Mundt 		break;
21909a07294SPaul Mundt 	default:
22009a07294SPaul Mundt 		return -EINVAL;
22109a07294SPaul Mundt 	}
22209a07294SPaul Mundt 
22309a07294SPaul Mundt 	return 0;
22409a07294SPaul Mundt }
22509a07294SPaul Mundt 
22609a07294SPaul Mundt /*
22709a07294SPaul Mundt  * Validate the arch-specific HW Breakpoint register settings
22809a07294SPaul Mundt  */
22909a07294SPaul Mundt int arch_validate_hwbkpt_settings(struct perf_event *bp,
23009a07294SPaul Mundt 				  struct task_struct *tsk)
23109a07294SPaul Mundt {
23209a07294SPaul Mundt 	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
23309a07294SPaul Mundt 	unsigned int align;
23409a07294SPaul Mundt 	int ret;
23509a07294SPaul Mundt 
23609a07294SPaul Mundt 	ret = arch_build_bp_info(bp);
23709a07294SPaul Mundt 	if (ret)
23809a07294SPaul Mundt 		return ret;
23909a07294SPaul Mundt 
24009a07294SPaul Mundt 	ret = -EINVAL;
24109a07294SPaul Mundt 
24209a07294SPaul Mundt 	switch (info->len) {
24309a07294SPaul Mundt 	case SH_BREAKPOINT_LEN_1:
24409a07294SPaul Mundt 		align = 0;
24509a07294SPaul Mundt 		break;
24609a07294SPaul Mundt 	case SH_BREAKPOINT_LEN_2:
24709a07294SPaul Mundt 		align = 1;
24809a07294SPaul Mundt 		break;
24909a07294SPaul Mundt 	case SH_BREAKPOINT_LEN_4:
25009a07294SPaul Mundt 		align = 3;
25109a07294SPaul Mundt 		break;
25209a07294SPaul Mundt 	case SH_BREAKPOINT_LEN_8:
25309a07294SPaul Mundt 		align = 7;
25409a07294SPaul Mundt 		break;
25509a07294SPaul Mundt 	default:
25609a07294SPaul Mundt 		return ret;
25709a07294SPaul Mundt 	}
25809a07294SPaul Mundt 
259*105244ecSPaul Mundt 	/*
260*105244ecSPaul Mundt 	 * For kernel-addresses, either the address or symbol name can be
261*105244ecSPaul Mundt 	 * specified.
262*105244ecSPaul Mundt 	 */
263*105244ecSPaul Mundt 	if (info->name)
264*105244ecSPaul Mundt 		info->address = (unsigned long)kallsyms_lookup_name(info->name);
26509a07294SPaul Mundt 
26609a07294SPaul Mundt 	/*
26709a07294SPaul Mundt 	 * Check that the low-order bits of the address are appropriate
26809a07294SPaul Mundt 	 * for the alignment implied by len.
26909a07294SPaul Mundt 	 */
27009a07294SPaul Mundt 	if (info->address & align)
27109a07294SPaul Mundt 		return -EINVAL;
27209a07294SPaul Mundt 
27309a07294SPaul Mundt 	/* Check that the virtual address is in the proper range */
27409a07294SPaul Mundt 	if (tsk) {
27509a07294SPaul Mundt 		if (!arch_check_va_in_userspace(info->address, info->len))
27609a07294SPaul Mundt 			return -EFAULT;
27709a07294SPaul Mundt 	} else {
27809a07294SPaul Mundt 		if (!arch_check_va_in_kernelspace(info->address, info->len))
27909a07294SPaul Mundt 			return -EFAULT;
28009a07294SPaul Mundt 	}
28109a07294SPaul Mundt 
28209a07294SPaul Mundt 	return 0;
28309a07294SPaul Mundt }
28409a07294SPaul Mundt 
28509a07294SPaul Mundt /*
28609a07294SPaul Mundt  * Release the user breakpoints used by ptrace
28709a07294SPaul Mundt  */
28809a07294SPaul Mundt void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
28909a07294SPaul Mundt {
29009a07294SPaul Mundt 	int i;
29109a07294SPaul Mundt 	struct thread_struct *t = &tsk->thread;
29209a07294SPaul Mundt 
2934352fc1bSPaul Mundt 	for (i = 0; i < sh_ubc->num_events; i++) {
29409a07294SPaul Mundt 		unregister_hw_breakpoint(t->ptrace_bps[i]);
29509a07294SPaul Mundt 		t->ptrace_bps[i] = NULL;
29609a07294SPaul Mundt 	}
29709a07294SPaul Mundt }
29809a07294SPaul Mundt 
29909a07294SPaul Mundt static int __kprobes hw_breakpoint_handler(struct die_args *args)
30009a07294SPaul Mundt {
30109a07294SPaul Mundt 	int cpu, i, rc = NOTIFY_STOP;
30209a07294SPaul Mundt 	struct perf_event *bp;
3034352fc1bSPaul Mundt 	unsigned int cmf, resume_mask;
30409a07294SPaul Mundt 
3054352fc1bSPaul Mundt 	/*
3064352fc1bSPaul Mundt 	 * Do an early return if none of the channels triggered.
3074352fc1bSPaul Mundt 	 */
3084352fc1bSPaul Mundt 	cmf = sh_ubc->triggered_mask();
3094352fc1bSPaul Mundt 	if (unlikely(!cmf))
3104352fc1bSPaul Mundt 		return NOTIFY_DONE;
3114352fc1bSPaul Mundt 
3124352fc1bSPaul Mundt 	/*
3134352fc1bSPaul Mundt 	 * By default, resume all of the active channels.
3144352fc1bSPaul Mundt 	 */
3154352fc1bSPaul Mundt 	resume_mask = sh_ubc->active_mask();
3164352fc1bSPaul Mundt 
3174352fc1bSPaul Mundt 	/*
3184352fc1bSPaul Mundt 	 * Disable breakpoints during exception handling.
3194352fc1bSPaul Mundt 	 */
3204352fc1bSPaul Mundt 	sh_ubc->disable_all();
32109a07294SPaul Mundt 
32209a07294SPaul Mundt 	cpu = get_cpu();
3234352fc1bSPaul Mundt 	for (i = 0; i < sh_ubc->num_events; i++) {
3244352fc1bSPaul Mundt 		unsigned long event_mask = (1 << i);
3254352fc1bSPaul Mundt 
3264352fc1bSPaul Mundt 		if (likely(!(cmf & event_mask)))
3274352fc1bSPaul Mundt 			continue;
3284352fc1bSPaul Mundt 
32909a07294SPaul Mundt 		/*
33009a07294SPaul Mundt 		 * The counter may be concurrently released but that can only
33109a07294SPaul Mundt 		 * occur from a call_rcu() path. We can then safely fetch
33209a07294SPaul Mundt 		 * the breakpoint, use its callback, touch its counter
33309a07294SPaul Mundt 		 * while we are in an rcu_read_lock() path.
33409a07294SPaul Mundt 		 */
33509a07294SPaul Mundt 		rcu_read_lock();
33609a07294SPaul Mundt 
33709a07294SPaul Mundt 		bp = per_cpu(bp_per_reg[i], cpu);
3384352fc1bSPaul Mundt 		if (bp)
33909a07294SPaul Mundt 			rc = NOTIFY_DONE;
3404352fc1bSPaul Mundt 
3414352fc1bSPaul Mundt 		/*
3424352fc1bSPaul Mundt 		 * Reset the condition match flag to denote completion of
3434352fc1bSPaul Mundt 		 * exception handling.
3444352fc1bSPaul Mundt 		 */
3454352fc1bSPaul Mundt 		sh_ubc->clear_triggered_mask(event_mask);
3464352fc1bSPaul Mundt 
3474352fc1bSPaul Mundt 		/*
3484352fc1bSPaul Mundt 		 * bp can be NULL due to concurrent perf counter
3494352fc1bSPaul Mundt 		 * removing.
3504352fc1bSPaul Mundt 		 */
3514352fc1bSPaul Mundt 		if (!bp) {
35209a07294SPaul Mundt 			rcu_read_unlock();
35309a07294SPaul Mundt 			break;
35409a07294SPaul Mundt 		}
35509a07294SPaul Mundt 
3564352fc1bSPaul Mundt 		/*
3574352fc1bSPaul Mundt 		 * Don't restore the channel if the breakpoint is from
3584352fc1bSPaul Mundt 		 * ptrace, as it always operates in one-shot mode.
3594352fc1bSPaul Mundt 		 */
3604352fc1bSPaul Mundt 		if (bp->overflow_handler == ptrace_triggered)
3614352fc1bSPaul Mundt 			resume_mask &= ~(1 << i);
3624352fc1bSPaul Mundt 
363a28b460eSPaul Mundt 		perf_bp_event(bp, args->regs);
36409a07294SPaul Mundt 
3654352fc1bSPaul Mundt 		/* Deliver the signal to userspace */
3664352fc1bSPaul Mundt 		if (arch_check_va_in_userspace(bp->attr.bp_addr,
3674352fc1bSPaul Mundt 					       bp->attr.bp_len)) {
3684352fc1bSPaul Mundt 			siginfo_t info;
3694352fc1bSPaul Mundt 
3704352fc1bSPaul Mundt 			info.si_signo = args->signr;
3714352fc1bSPaul Mundt 			info.si_errno = notifier_to_errno(rc);
3724352fc1bSPaul Mundt 			info.si_code = TRAP_HWBKPT;
3734352fc1bSPaul Mundt 
3744352fc1bSPaul Mundt 			force_sig_info(args->signr, &info, current);
3754352fc1bSPaul Mundt 		}
3764352fc1bSPaul Mundt 
37709a07294SPaul Mundt 		rcu_read_unlock();
37809a07294SPaul Mundt 	}
37909a07294SPaul Mundt 
3804352fc1bSPaul Mundt 	if (cmf == 0)
3814352fc1bSPaul Mundt 		rc = NOTIFY_DONE;
38209a07294SPaul Mundt 
3834352fc1bSPaul Mundt 	sh_ubc->enable_all(resume_mask);
38409a07294SPaul Mundt 
38509a07294SPaul Mundt 	put_cpu();
38609a07294SPaul Mundt 
38709a07294SPaul Mundt 	return rc;
38809a07294SPaul Mundt }
38909a07294SPaul Mundt 
39009a07294SPaul Mundt BUILD_TRAP_HANDLER(breakpoint)
39109a07294SPaul Mundt {
39209a07294SPaul Mundt 	unsigned long ex = lookup_exception_vector();
39309a07294SPaul Mundt 	TRAP_HANDLER_DECL;
39409a07294SPaul Mundt 
3954352fc1bSPaul Mundt 	notify_die(DIE_BREAKPOINT, "breakpoint", regs, 0, ex, SIGTRAP);
39609a07294SPaul Mundt }
39709a07294SPaul Mundt 
39809a07294SPaul Mundt /*
39909a07294SPaul Mundt  * Handle debug exception notifications.
40009a07294SPaul Mundt  */
40109a07294SPaul Mundt int __kprobes hw_breakpoint_exceptions_notify(struct notifier_block *unused,
40209a07294SPaul Mundt 				    unsigned long val, void *data)
40309a07294SPaul Mundt {
404b74ab703SPaul Mundt 	struct die_args *args = data;
405b74ab703SPaul Mundt 
40609a07294SPaul Mundt 	if (val != DIE_BREAKPOINT)
40709a07294SPaul Mundt 		return NOTIFY_DONE;
40809a07294SPaul Mundt 
409b74ab703SPaul Mundt 	/*
410b74ab703SPaul Mundt 	 * If the breakpoint hasn't been triggered by the UBC, it's
411b74ab703SPaul Mundt 	 * probably from a debugger, so don't do anything more here.
4124352fc1bSPaul Mundt 	 *
4134352fc1bSPaul Mundt 	 * This also permits the UBC interface clock to remain off for
4144352fc1bSPaul Mundt 	 * non-UBC breakpoints, as we don't need to check the triggered
4154352fc1bSPaul Mundt 	 * or active channel masks.
416b74ab703SPaul Mundt 	 */
4174352fc1bSPaul Mundt 	if (args->trapnr != sh_ubc->trap_nr)
418b74ab703SPaul Mundt 		return NOTIFY_DONE;
419b74ab703SPaul Mundt 
42009a07294SPaul Mundt 	return hw_breakpoint_handler(data);
42109a07294SPaul Mundt }
42209a07294SPaul Mundt 
42309a07294SPaul Mundt void hw_breakpoint_pmu_read(struct perf_event *bp)
42409a07294SPaul Mundt {
42509a07294SPaul Mundt 	/* TODO */
42609a07294SPaul Mundt }
42709a07294SPaul Mundt 
42809a07294SPaul Mundt void hw_breakpoint_pmu_unthrottle(struct perf_event *bp)
42909a07294SPaul Mundt {
43009a07294SPaul Mundt 	/* TODO */
43109a07294SPaul Mundt }
4324352fc1bSPaul Mundt 
4334352fc1bSPaul Mundt int register_sh_ubc(struct sh_ubc *ubc)
4344352fc1bSPaul Mundt {
4354352fc1bSPaul Mundt 	/* Bail if it's already assigned */
4364352fc1bSPaul Mundt 	if (sh_ubc != &ubc_dummy)
4374352fc1bSPaul Mundt 		return -EBUSY;
4384352fc1bSPaul Mundt 	sh_ubc = ubc;
4394352fc1bSPaul Mundt 
4404352fc1bSPaul Mundt 	pr_info("HW Breakpoints: %s UBC support registered\n", ubc->name);
4414352fc1bSPaul Mundt 
4424352fc1bSPaul Mundt 	WARN_ON(ubc->num_events > HBP_NUM);
4434352fc1bSPaul Mundt 
4444352fc1bSPaul Mundt 	return 0;
4454352fc1bSPaul Mundt }
446