aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/hw_breakpoint.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/hw_breakpoint.c')
-rw-r--r--arch/powerpc/kernel/hw_breakpoint.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index 956a4c496de..a89cae481b0 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)
73 * If so, DABR will be populated in single_step_dabr_instruction(). 73 * If so, DABR will be populated in single_step_dabr_instruction().
74 */ 74 */
75 if (current->thread.last_hit_ubp != bp) 75 if (current->thread.last_hit_ubp != bp)
76 set_dabr(info->address | info->type | DABR_TRANSLATION); 76 set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx);
77 77
78 return 0; 78 return 0;
79} 79}
@@ -97,7 +97,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
97 } 97 }
98 98
99 *slot = NULL; 99 *slot = NULL;
100 set_dabr(0); 100 set_dabr(0, 0);
101} 101}
102 102
103/* 103/*
@@ -170,6 +170,13 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
170 170
171 info->address = bp->attr.bp_addr; 171 info->address = bp->attr.bp_addr;
172 info->len = bp->attr.bp_len; 172 info->len = bp->attr.bp_len;
173 info->dabrx = DABRX_ALL;
174 if (bp->attr.exclude_user)
175 info->dabrx &= ~DABRX_USER;
176 if (bp->attr.exclude_kernel)
177 info->dabrx &= ~DABRX_KERNEL;
178 if (bp->attr.exclude_hv)
179 info->dabrx &= ~DABRX_HYP;
173 180
174 /* 181 /*
175 * Since breakpoint length can be a maximum of HW_BREAKPOINT_LEN(8) 182 * Since breakpoint length can be a maximum of HW_BREAKPOINT_LEN(8)
@@ -197,7 +204,7 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
197 204
198 info = counter_arch_bp(tsk->thread.last_hit_ubp); 205 info = counter_arch_bp(tsk->thread.last_hit_ubp);
199 regs->msr &= ~MSR_SE; 206 regs->msr &= ~MSR_SE;
200 set_dabr(info->address | info->type | DABR_TRANSLATION); 207 set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx);
201 tsk->thread.last_hit_ubp = NULL; 208 tsk->thread.last_hit_ubp = NULL;
202} 209}
203 210
@@ -215,7 +222,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
215 unsigned long dar = regs->dar; 222 unsigned long dar = regs->dar;
216 223
217 /* Disable breakpoints during exception handling */ 224 /* Disable breakpoints during exception handling */
218 set_dabr(0); 225 set_dabr(0, 0);
219 226
220 /* 227 /*
221 * The counter may be concurrently released but that can only 228 * The counter may be concurrently released but that can only
@@ -281,7 +288,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
281 if (!info->extraneous_interrupt) 288 if (!info->extraneous_interrupt)
282 perf_bp_event(bp, regs); 289 perf_bp_event(bp, regs);
283 290
284 set_dabr(info->address | info->type | DABR_TRANSLATION); 291 set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx);
285out: 292out:
286 rcu_read_unlock(); 293 rcu_read_unlock();
287 return rc; 294 return rc;
@@ -294,7 +301,7 @@ int __kprobes single_step_dabr_instruction(struct die_args *args)
294{ 301{
295 struct pt_regs *regs = args->regs; 302 struct pt_regs *regs = args->regs;
296 struct perf_event *bp = NULL; 303 struct perf_event *bp = NULL;
297 struct arch_hw_breakpoint *bp_info; 304 struct arch_hw_breakpoint *info;
298 305
299 bp = current->thread.last_hit_ubp; 306 bp = current->thread.last_hit_ubp;
300 /* 307 /*
@@ -304,16 +311,16 @@ int __kprobes single_step_dabr_instruction(struct die_args *args)
304 if (!bp) 311 if (!bp)
305 return NOTIFY_DONE; 312 return NOTIFY_DONE;
306 313
307 bp_info = counter_arch_bp(bp); 314 info = counter_arch_bp(bp);
308 315
309 /* 316 /*
310 * We shall invoke the user-defined callback function in the single 317 * We shall invoke the user-defined callback function in the single
311 * stepping handler to confirm to 'trigger-after-execute' semantics 318 * stepping handler to confirm to 'trigger-after-execute' semantics
312 */ 319 */
313 if (!bp_info->extraneous_interrupt) 320 if (!info->extraneous_interrupt)
314 perf_bp_event(bp, regs); 321 perf_bp_event(bp, regs);
315 322
316 set_dabr(bp_info->address | bp_info->type | DABR_TRANSLATION); 323 set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx);
317 current->thread.last_hit_ubp = NULL; 324 current->thread.last_hit_ubp = NULL;
318 325
319 /* 326 /*