diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2012-08-07 12:12:28 -0400 |
---|---|---|
committer | Oleg Nesterov <oleg@redhat.com> | 2012-09-15 11:37:28 -0400 |
commit | 9d778782266f95e5c6ec43ed8195ba331c821018 (patch) | |
tree | 99872945803a76d1ff9e438cf48864cd0a5d9bf4 /kernel | |
parent | 499a4f3ec057a0f79636cc3c1e581bb6e977a30f (diff) |
uprobes: Introduce arch_uprobe_enable/disable_step()
As Oleg pointed out in [0] uprobe should not use the ptrace interface
for enabling/disabling single stepping.
[0] http://lkml.kernel.org/r/20120730141638.GA5306@redhat.com
Add the new "__weak arch" helpers which simply call user_*_single_step()
as a preparation. This is only needed to not break the powerpc port, we
will fold this logic into arch_uprobe_pre/post_xol() hooks later.
We should also change handle_singlestep(), _disable_step(&uprobe->arch)
should be called before put_uprobe().
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/events/uprobes.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index e4a906ce2e1d..912ef48d28ab 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
@@ -1444,6 +1444,16 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp) | |||
1444 | return uprobe; | 1444 | return uprobe; |
1445 | } | 1445 | } |
1446 | 1446 | ||
1447 | void __weak arch_uprobe_enable_step(struct arch_uprobe *arch) | ||
1448 | { | ||
1449 | user_enable_single_step(current); | ||
1450 | } | ||
1451 | |||
1452 | void __weak arch_uprobe_disable_step(struct arch_uprobe *arch) | ||
1453 | { | ||
1454 | user_disable_single_step(current); | ||
1455 | } | ||
1456 | |||
1447 | /* | 1457 | /* |
1448 | * Run handler and ask thread to singlestep. | 1458 | * Run handler and ask thread to singlestep. |
1449 | * Ensure all non-fatal signals cannot interrupt thread while it singlesteps. | 1459 | * Ensure all non-fatal signals cannot interrupt thread while it singlesteps. |
@@ -1490,7 +1500,7 @@ static void handle_swbp(struct pt_regs *regs) | |||
1490 | 1500 | ||
1491 | utask->state = UTASK_SSTEP; | 1501 | utask->state = UTASK_SSTEP; |
1492 | if (!pre_ssout(uprobe, regs, bp_vaddr)) { | 1502 | if (!pre_ssout(uprobe, regs, bp_vaddr)) { |
1493 | user_enable_single_step(current); | 1503 | arch_uprobe_enable_step(&uprobe->arch); |
1494 | return; | 1504 | return; |
1495 | } | 1505 | } |
1496 | 1506 | ||
@@ -1526,10 +1536,10 @@ static void handle_singlestep(struct uprobe_task *utask, struct pt_regs *regs) | |||
1526 | else | 1536 | else |
1527 | WARN_ON_ONCE(1); | 1537 | WARN_ON_ONCE(1); |
1528 | 1538 | ||
1539 | arch_uprobe_disable_step(&uprobe->arch); | ||
1529 | put_uprobe(uprobe); | 1540 | put_uprobe(uprobe); |
1530 | utask->active_uprobe = NULL; | 1541 | utask->active_uprobe = NULL; |
1531 | utask->state = UTASK_RUNNING; | 1542 | utask->state = UTASK_RUNNING; |
1532 | user_disable_single_step(current); | ||
1533 | xol_free_insn_slot(current); | 1543 | xol_free_insn_slot(current); |
1534 | 1544 | ||
1535 | spin_lock_irq(¤t->sighand->siglock); | 1545 | spin_lock_irq(¤t->sighand->siglock); |