Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/x86/kernel/hw_breakpoint.c
10817 views
1
/*
2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
6
*
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* GNU General Public License for more details.
11
*
12
* You should have received a copy of the GNU General Public License
13
* along with this program; if not, write to the Free Software
14
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15
*
16
* Copyright (C) 2007 Alan Stern
17
* Copyright (C) 2009 IBM Corporation
18
* Copyright (C) 2009 Frederic Weisbecker <[email protected]>
19
*
20
* Authors: Alan Stern <[email protected]>
21
* K.Prasad <[email protected]>
22
* Frederic Weisbecker <[email protected]>
23
*/
24
25
/*
26
* HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
27
* using the CPU's debug registers.
28
*/
29
30
#include <linux/perf_event.h>
31
#include <linux/hw_breakpoint.h>
32
#include <linux/irqflags.h>
33
#include <linux/notifier.h>
34
#include <linux/kallsyms.h>
35
#include <linux/kprobes.h>
36
#include <linux/percpu.h>
37
#include <linux/kdebug.h>
38
#include <linux/kernel.h>
39
#include <linux/module.h>
40
#include <linux/sched.h>
41
#include <linux/init.h>
42
#include <linux/smp.h>
43
44
#include <asm/hw_breakpoint.h>
45
#include <asm/processor.h>
46
#include <asm/debugreg.h>
47
48
/* Per cpu debug control register value */
49
DEFINE_PER_CPU(unsigned long, cpu_dr7);
50
EXPORT_PER_CPU_SYMBOL(cpu_dr7);
51
52
/* Per cpu debug address registers values */
53
static DEFINE_PER_CPU(unsigned long, cpu_debugreg[HBP_NUM]);
54
55
/*
56
* Stores the breakpoints currently in use on each breakpoint address
57
* register for each cpus
58
*/
59
static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]);
60
61
62
static inline unsigned long
63
__encode_dr7(int drnum, unsigned int len, unsigned int type)
64
{
65
unsigned long bp_info;
66
67
bp_info = (len | type) & 0xf;
68
bp_info <<= (DR_CONTROL_SHIFT + drnum * DR_CONTROL_SIZE);
69
bp_info |= (DR_GLOBAL_ENABLE << (drnum * DR_ENABLE_SIZE));
70
71
return bp_info;
72
}
73
74
/*
75
* Encode the length, type, Exact, and Enable bits for a particular breakpoint
76
* as stored in debug register 7.
77
*/
78
unsigned long encode_dr7(int drnum, unsigned int len, unsigned int type)
79
{
80
return __encode_dr7(drnum, len, type) | DR_GLOBAL_SLOWDOWN;
81
}
82
83
/*
84
* Decode the length and type bits for a particular breakpoint as
85
* stored in debug register 7. Return the "enabled" status.
86
*/
87
int decode_dr7(unsigned long dr7, int bpnum, unsigned *len, unsigned *type)
88
{
89
int bp_info = dr7 >> (DR_CONTROL_SHIFT + bpnum * DR_CONTROL_SIZE);
90
91
*len = (bp_info & 0xc) | 0x40;
92
*type = (bp_info & 0x3) | 0x80;
93
94
return (dr7 >> (bpnum * DR_ENABLE_SIZE)) & 0x3;
95
}
96
97
/*
98
* Install a perf counter breakpoint.
99
*
100
* We seek a free debug address register and use it for this
101
* breakpoint. Eventually we enable it in the debug control register.
102
*
103
* Atomic: we hold the counter->ctx->lock and we only handle variables
104
* and registers local to this cpu.
105
*/
106
int arch_install_hw_breakpoint(struct perf_event *bp)
107
{
108
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
109
unsigned long *dr7;
110
int i;
111
112
for (i = 0; i < HBP_NUM; i++) {
113
struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
114
115
if (!*slot) {
116
*slot = bp;
117
break;
118
}
119
}
120
121
if (WARN_ONCE(i == HBP_NUM, "Can't find any breakpoint slot"))
122
return -EBUSY;
123
124
set_debugreg(info->address, i);
125
__this_cpu_write(cpu_debugreg[i], info->address);
126
127
dr7 = &__get_cpu_var(cpu_dr7);
128
*dr7 |= encode_dr7(i, info->len, info->type);
129
130
set_debugreg(*dr7, 7);
131
132
return 0;
133
}
134
135
/*
136
* Uninstall the breakpoint contained in the given counter.
137
*
138
* First we search the debug address register it uses and then we disable
139
* it.
140
*
141
* Atomic: we hold the counter->ctx->lock and we only handle variables
142
* and registers local to this cpu.
143
*/
144
void arch_uninstall_hw_breakpoint(struct perf_event *bp)
145
{
146
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
147
unsigned long *dr7;
148
int i;
149
150
for (i = 0; i < HBP_NUM; i++) {
151
struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
152
153
if (*slot == bp) {
154
*slot = NULL;
155
break;
156
}
157
}
158
159
if (WARN_ONCE(i == HBP_NUM, "Can't find any breakpoint slot"))
160
return;
161
162
dr7 = &__get_cpu_var(cpu_dr7);
163
*dr7 &= ~__encode_dr7(i, info->len, info->type);
164
165
set_debugreg(*dr7, 7);
166
}
167
168
static int get_hbp_len(u8 hbp_len)
169
{
170
unsigned int len_in_bytes = 0;
171
172
switch (hbp_len) {
173
case X86_BREAKPOINT_LEN_1:
174
len_in_bytes = 1;
175
break;
176
case X86_BREAKPOINT_LEN_2:
177
len_in_bytes = 2;
178
break;
179
case X86_BREAKPOINT_LEN_4:
180
len_in_bytes = 4;
181
break;
182
#ifdef CONFIG_X86_64
183
case X86_BREAKPOINT_LEN_8:
184
len_in_bytes = 8;
185
break;
186
#endif
187
}
188
return len_in_bytes;
189
}
190
191
/*
192
* Check for virtual address in kernel space.
193
*/
194
int arch_check_bp_in_kernelspace(struct perf_event *bp)
195
{
196
unsigned int len;
197
unsigned long va;
198
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
199
200
va = info->address;
201
len = get_hbp_len(info->len);
202
203
return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
204
}
205
206
int arch_bp_generic_fields(int x86_len, int x86_type,
207
int *gen_len, int *gen_type)
208
{
209
/* Type */
210
switch (x86_type) {
211
case X86_BREAKPOINT_EXECUTE:
212
if (x86_len != X86_BREAKPOINT_LEN_X)
213
return -EINVAL;
214
215
*gen_type = HW_BREAKPOINT_X;
216
*gen_len = sizeof(long);
217
return 0;
218
case X86_BREAKPOINT_WRITE:
219
*gen_type = HW_BREAKPOINT_W;
220
break;
221
case X86_BREAKPOINT_RW:
222
*gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
223
break;
224
default:
225
return -EINVAL;
226
}
227
228
/* Len */
229
switch (x86_len) {
230
case X86_BREAKPOINT_LEN_1:
231
*gen_len = HW_BREAKPOINT_LEN_1;
232
break;
233
case X86_BREAKPOINT_LEN_2:
234
*gen_len = HW_BREAKPOINT_LEN_2;
235
break;
236
case X86_BREAKPOINT_LEN_4:
237
*gen_len = HW_BREAKPOINT_LEN_4;
238
break;
239
#ifdef CONFIG_X86_64
240
case X86_BREAKPOINT_LEN_8:
241
*gen_len = HW_BREAKPOINT_LEN_8;
242
break;
243
#endif
244
default:
245
return -EINVAL;
246
}
247
248
return 0;
249
}
250
251
252
static int arch_build_bp_info(struct perf_event *bp)
253
{
254
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
255
256
info->address = bp->attr.bp_addr;
257
258
/* Type */
259
switch (bp->attr.bp_type) {
260
case HW_BREAKPOINT_W:
261
info->type = X86_BREAKPOINT_WRITE;
262
break;
263
case HW_BREAKPOINT_W | HW_BREAKPOINT_R:
264
info->type = X86_BREAKPOINT_RW;
265
break;
266
case HW_BREAKPOINT_X:
267
info->type = X86_BREAKPOINT_EXECUTE;
268
/*
269
* x86 inst breakpoints need to have a specific undefined len.
270
* But we still need to check userspace is not trying to setup
271
* an unsupported length, to get a range breakpoint for example.
272
*/
273
if (bp->attr.bp_len == sizeof(long)) {
274
info->len = X86_BREAKPOINT_LEN_X;
275
return 0;
276
}
277
default:
278
return -EINVAL;
279
}
280
281
/* Len */
282
switch (bp->attr.bp_len) {
283
case HW_BREAKPOINT_LEN_1:
284
info->len = X86_BREAKPOINT_LEN_1;
285
break;
286
case HW_BREAKPOINT_LEN_2:
287
info->len = X86_BREAKPOINT_LEN_2;
288
break;
289
case HW_BREAKPOINT_LEN_4:
290
info->len = X86_BREAKPOINT_LEN_4;
291
break;
292
#ifdef CONFIG_X86_64
293
case HW_BREAKPOINT_LEN_8:
294
info->len = X86_BREAKPOINT_LEN_8;
295
break;
296
#endif
297
default:
298
return -EINVAL;
299
}
300
301
return 0;
302
}
303
/*
304
* Validate the arch-specific HW Breakpoint register settings
305
*/
306
int arch_validate_hwbkpt_settings(struct perf_event *bp)
307
{
308
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
309
unsigned int align;
310
int ret;
311
312
313
ret = arch_build_bp_info(bp);
314
if (ret)
315
return ret;
316
317
ret = -EINVAL;
318
319
switch (info->len) {
320
case X86_BREAKPOINT_LEN_1:
321
align = 0;
322
break;
323
case X86_BREAKPOINT_LEN_2:
324
align = 1;
325
break;
326
case X86_BREAKPOINT_LEN_4:
327
align = 3;
328
break;
329
#ifdef CONFIG_X86_64
330
case X86_BREAKPOINT_LEN_8:
331
align = 7;
332
break;
333
#endif
334
default:
335
return ret;
336
}
337
338
/*
339
* Check that the low-order bits of the address are appropriate
340
* for the alignment implied by len.
341
*/
342
if (info->address & align)
343
return -EINVAL;
344
345
return 0;
346
}
347
348
/*
349
* Dump the debug register contents to the user.
350
* We can't dump our per cpu values because it
351
* may contain cpu wide breakpoint, something that
352
* doesn't belong to the current task.
353
*
354
* TODO: include non-ptrace user breakpoints (perf)
355
*/
356
void aout_dump_debugregs(struct user *dump)
357
{
358
int i;
359
int dr7 = 0;
360
struct perf_event *bp;
361
struct arch_hw_breakpoint *info;
362
struct thread_struct *thread = &current->thread;
363
364
for (i = 0; i < HBP_NUM; i++) {
365
bp = thread->ptrace_bps[i];
366
367
if (bp && !bp->attr.disabled) {
368
dump->u_debugreg[i] = bp->attr.bp_addr;
369
info = counter_arch_bp(bp);
370
dr7 |= encode_dr7(i, info->len, info->type);
371
} else {
372
dump->u_debugreg[i] = 0;
373
}
374
}
375
376
dump->u_debugreg[4] = 0;
377
dump->u_debugreg[5] = 0;
378
dump->u_debugreg[6] = current->thread.debugreg6;
379
380
dump->u_debugreg[7] = dr7;
381
}
382
EXPORT_SYMBOL_GPL(aout_dump_debugregs);
383
384
/*
385
* Release the user breakpoints used by ptrace
386
*/
387
void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
388
{
389
int i;
390
struct thread_struct *t = &tsk->thread;
391
392
for (i = 0; i < HBP_NUM; i++) {
393
unregister_hw_breakpoint(t->ptrace_bps[i]);
394
t->ptrace_bps[i] = NULL;
395
}
396
}
397
398
void hw_breakpoint_restore(void)
399
{
400
set_debugreg(__this_cpu_read(cpu_debugreg[0]), 0);
401
set_debugreg(__this_cpu_read(cpu_debugreg[1]), 1);
402
set_debugreg(__this_cpu_read(cpu_debugreg[2]), 2);
403
set_debugreg(__this_cpu_read(cpu_debugreg[3]), 3);
404
set_debugreg(current->thread.debugreg6, 6);
405
set_debugreg(__this_cpu_read(cpu_dr7), 7);
406
}
407
EXPORT_SYMBOL_GPL(hw_breakpoint_restore);
408
409
/*
410
* Handle debug exception notifications.
411
*
412
* Return value is either NOTIFY_STOP or NOTIFY_DONE as explained below.
413
*
414
* NOTIFY_DONE returned if one of the following conditions is true.
415
* i) When the causative address is from user-space and the exception
416
* is a valid one, i.e. not triggered as a result of lazy debug register
417
* switching
418
* ii) When there are more bits than trap<n> set in DR6 register (such
419
* as BD, BS or BT) indicating that more than one debug condition is
420
* met and requires some more action in do_debug().
421
*
422
* NOTIFY_STOP returned for all other cases
423
*
424
*/
425
static int __kprobes hw_breakpoint_handler(struct die_args *args)
426
{
427
int i, cpu, rc = NOTIFY_STOP;
428
struct perf_event *bp;
429
unsigned long dr7, dr6;
430
unsigned long *dr6_p;
431
432
/* The DR6 value is pointed by args->err */
433
dr6_p = (unsigned long *)ERR_PTR(args->err);
434
dr6 = *dr6_p;
435
436
/* If it's a single step, TRAP bits are random */
437
if (dr6 & DR_STEP)
438
return NOTIFY_DONE;
439
440
/* Do an early return if no trap bits are set in DR6 */
441
if ((dr6 & DR_TRAP_BITS) == 0)
442
return NOTIFY_DONE;
443
444
get_debugreg(dr7, 7);
445
/* Disable breakpoints during exception handling */
446
set_debugreg(0UL, 7);
447
/*
448
* Assert that local interrupts are disabled
449
* Reset the DRn bits in the virtualized register value.
450
* The ptrace trigger routine will add in whatever is needed.
451
*/
452
current->thread.debugreg6 &= ~DR_TRAP_BITS;
453
cpu = get_cpu();
454
455
/* Handle all the breakpoints that were triggered */
456
for (i = 0; i < HBP_NUM; ++i) {
457
if (likely(!(dr6 & (DR_TRAP0 << i))))
458
continue;
459
460
/*
461
* The counter may be concurrently released but that can only
462
* occur from a call_rcu() path. We can then safely fetch
463
* the breakpoint, use its callback, touch its counter
464
* while we are in an rcu_read_lock() path.
465
*/
466
rcu_read_lock();
467
468
bp = per_cpu(bp_per_reg[i], cpu);
469
/*
470
* Reset the 'i'th TRAP bit in dr6 to denote completion of
471
* exception handling
472
*/
473
(*dr6_p) &= ~(DR_TRAP0 << i);
474
/*
475
* bp can be NULL due to lazy debug register switching
476
* or due to concurrent perf counter removing.
477
*/
478
if (!bp) {
479
rcu_read_unlock();
480
break;
481
}
482
483
perf_bp_event(bp, args->regs);
484
485
/*
486
* Set up resume flag to avoid breakpoint recursion when
487
* returning back to origin.
488
*/
489
if (bp->hw.info.type == X86_BREAKPOINT_EXECUTE)
490
args->regs->flags |= X86_EFLAGS_RF;
491
492
rcu_read_unlock();
493
}
494
/*
495
* Further processing in do_debug() is needed for a) user-space
496
* breakpoints (to generate signals) and b) when the system has
497
* taken exception due to multiple causes
498
*/
499
if ((current->thread.debugreg6 & DR_TRAP_BITS) ||
500
(dr6 & (~DR_TRAP_BITS)))
501
rc = NOTIFY_DONE;
502
503
set_debugreg(dr7, 7);
504
put_cpu();
505
506
return rc;
507
}
508
509
/*
510
* Handle debug exception notifications.
511
*/
512
int __kprobes hw_breakpoint_exceptions_notify(
513
struct notifier_block *unused, unsigned long val, void *data)
514
{
515
if (val != DIE_DEBUG)
516
return NOTIFY_DONE;
517
518
return hw_breakpoint_handler(data);
519
}
520
521
void hw_breakpoint_pmu_read(struct perf_event *bp)
522
{
523
/* TODO */
524
}
525
526