30 #include <linux/perf_event.h>
31 #include <linux/hw_breakpoint.h>
38 #include <linux/kernel.h>
39 #include <linux/module.h>
40 #include <linux/sched.h>
44 #include <asm/hw_breakpoint.h>
45 #include <asm/processor.h>
62 static inline unsigned long
63 __encode_dr7(
int drnum,
unsigned int len,
unsigned int type)
67 bp_info = (len |
type) & 0xf;
91 *len = (bp_info & 0xc) | 0x40;
92 *type = (bp_info & 0x3) | 0x80;
112 for (i = 0; i <
HBP_NUM; i++) {
121 if (
WARN_ONCE(i == HBP_NUM,
"Can't find any breakpoint slot"))
124 set_debugreg(info->
address, i);
130 set_debugreg(*dr7, 7);
150 for (i = 0; i <
HBP_NUM; i++) {
159 if (
WARN_ONCE(i == HBP_NUM,
"Can't find any breakpoint slot"))
163 *dr7 &= ~__encode_dr7(i, info->
len, info->
type);
165 set_debugreg(*dr7, 7);
168 static int get_hbp_len(
u8 hbp_len)
170 unsigned int len_in_bytes = 0;
173 case X86_BREAKPOINT_LEN_1:
176 case X86_BREAKPOINT_LEN_2:
179 case X86_BREAKPOINT_LEN_4:
183 case X86_BREAKPOINT_LEN_8:
201 len = get_hbp_len(info->
len);
207 int *gen_len,
int *gen_type)
211 case X86_BREAKPOINT_EXECUTE:
212 if (x86_len != X86_BREAKPOINT_LEN_X)
216 *gen_len =
sizeof(
long);
218 case X86_BREAKPOINT_WRITE:
221 case X86_BREAKPOINT_RW:
230 case X86_BREAKPOINT_LEN_1:
233 case X86_BREAKPOINT_LEN_2:
236 case X86_BREAKPOINT_LEN_4:
240 case X86_BREAKPOINT_LEN_8:
252 static int arch_build_bp_info(
struct perf_event *bp)
259 switch (bp->
attr.bp_type) {
261 info->
type = X86_BREAKPOINT_WRITE;
264 info->
type = X86_BREAKPOINT_RW;
267 info->
type = X86_BREAKPOINT_EXECUTE;
273 if (bp->
attr.bp_len ==
sizeof(
long)) {
274 info->
len = X86_BREAKPOINT_LEN_X;
282 switch (bp->
attr.bp_len) {
284 info->
len = X86_BREAKPOINT_LEN_1;
287 info->
len = X86_BREAKPOINT_LEN_2;
290 info->
len = X86_BREAKPOINT_LEN_4;
294 info->
len = X86_BREAKPOINT_LEN_8;
313 ret = arch_build_bp_info(bp);
320 case X86_BREAKPOINT_LEN_1:
323 case X86_BREAKPOINT_LEN_2:
326 case X86_BREAKPOINT_LEN_4:
330 case X86_BREAKPOINT_LEN_8:
364 for (i = 0; i <
HBP_NUM; i++) {
367 if (bp && !bp->
attr.disabled) {
369 info = counter_arch_bp(bp);
392 for (i = 0; i <
HBP_NUM; i++) {
404 set_debugreg(
current->thread.debugreg6, 6);
427 int i,
cpu,
rc = NOTIFY_STOP;
429 unsigned long dr7, dr6;
430 unsigned long *dr6_p;
433 dr6_p = (
unsigned long *)ERR_PTR(args->
err);
444 get_debugreg(dr7, 7);
446 set_debugreg(0
UL, 7);
452 current->thread.debugreg6 &= ~DR_TRAP_BITS;
468 bp =
per_cpu(bp_per_reg[i], cpu);
483 perf_bp_event(bp, args->
regs);
489 if (bp->hw.info.type == X86_BREAKPOINT_EXECUTE)
499 if ((
current->thread.debugreg6 & DR_TRAP_BITS) ||
500 (dr6 & (~DR_TRAP_BITS)))
503 set_debugreg(dr7, 7);