summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/hw_breakpoint.c
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2012-09-06 21:24:56 +0000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-09-10 09:59:10 +1000
commit4474ef055c5d8cb8eaf002d69e49af71e3aa3a88 (patch)
treee57b99bfa78d7c3faf4125ab4a08f17fed2c41d8 /arch/powerpc/kernel/hw_breakpoint.c
parent3ab96a02e829131c19db8ed99239289acdb4e3dc (diff)
downloadlinux-4474ef055c5d8cb8eaf002d69e49af71e3aa3a88.tar.gz
linux-4474ef055c5d8cb8eaf002d69e49af71e3aa3a88.tar.bz2
linux-4474ef055c5d8cb8eaf002d69e49af71e3aa3a88.zip
powerpc: Rework set_dabr so it can take a DABRX value as well
Rework set_dabr to take a DABRX value as well. Both the pseries and PS3 hypervisors do some checks on the DABRX values that are passed in the hcall. This patch stops bogus values from being passed to hypervisor. Also, in the case where we are clearing the breakpoint, where DABR and DABRX are zero, we modify the DABRX value to make it valid so that the hcall won't fail. Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/hw_breakpoint.c')
-rw-r--r--arch/powerpc/kernel/hw_breakpoint.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index 6767445ecb45..6891d79ecef6 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -73,7 +73,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
* If so, DABR will be populated in single_step_dabr_instruction().
*/
if (current->thread.last_hit_ubp != bp)
- set_dabr(info->address | info->type | DABR_TRANSLATION);
+ set_dabr(info->address | info->type | DABR_TRANSLATION, DABRX_ALL);
return 0;
}
@@ -97,7 +97,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
}
*slot = NULL;
- set_dabr(0);
+ set_dabr(0, 0);
}
/*
@@ -197,7 +197,7 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
info = counter_arch_bp(tsk->thread.last_hit_ubp);
regs->msr &= ~MSR_SE;
- set_dabr(info->address | info->type | DABR_TRANSLATION);
+ set_dabr(info->address | info->type | DABR_TRANSLATION, DABRX_ALL);
tsk->thread.last_hit_ubp = NULL;
}
@@ -215,7 +215,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
unsigned long dar = regs->dar;
/* Disable breakpoints during exception handling */
- set_dabr(0);
+ set_dabr(0, 0);
/*
* The counter may be concurrently released but that can only
@@ -281,7 +281,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
if (!info->extraneous_interrupt)
perf_bp_event(bp, regs);
- set_dabr(info->address | info->type | DABR_TRANSLATION);
+ set_dabr(info->address | info->type | DABR_TRANSLATION, DABRX_ALL);
out:
rcu_read_unlock();
return rc;
@@ -313,7 +313,7 @@ int __kprobes single_step_dabr_instruction(struct die_args *args)
if (!info->extraneous_interrupt)
perf_bp_event(bp, regs);
- set_dabr(info->address | info->type | DABR_TRANSLATION);
+ set_dabr(info->address | info->type | DABR_TRANSLATION, DABRX_ALL);
current->thread.last_hit_ubp = NULL;
/*