diff options
author | Oleg Nesterov <oleg@redhat.com> | 2012-12-30 09:54:08 -0500 |
---|---|---|
committer | Oleg Nesterov <oleg@redhat.com> | 2013-02-08 11:47:11 -0500 |
commit | 74e59dfc6b19e3472a7c16ad57bc831e6e647895 (patch) | |
tree | 5047f177b6c604f83d4b9f62614acf93a08d34bd /kernel/events | |
parent | cf31ec3f7fece93f3fce3ee5964e27857141ea47 (diff) |
uprobes: Change handle_swbp() to expose bp_vaddr to handler_chain()
Change handle_swbp() to set regs->ip = bp_vaddr in advance, this is
what consumer->handler() needs but uprobe_get_swbp_addr() is not
exported.
This also simplifies the code and makes it more consistent across
the supported architectures. handle_swbp() becomes the only caller
of uprobe_get_swbp_addr().
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Diffstat (limited to 'kernel/events')
-rw-r--r-- | kernel/events/uprobes.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 04c104ad9522..f1b807831fc2 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
@@ -1504,6 +1504,10 @@ static void handle_swbp(struct pt_regs *regs) | |||
1504 | } | 1504 | } |
1505 | return; | 1505 | return; |
1506 | } | 1506 | } |
1507 | |||
1508 | /* change it in advance for ->handler() and restart */ | ||
1509 | instruction_pointer_set(regs, bp_vaddr); | ||
1510 | |||
1507 | /* | 1511 | /* |
1508 | * TODO: move copy_insn/etc into _register and remove this hack. | 1512 | * TODO: move copy_insn/etc into _register and remove this hack. |
1509 | * After we hit the bp, _unregister + _register can install the | 1513 | * After we hit the bp, _unregister + _register can install the |
@@ -1511,14 +1515,14 @@ static void handle_swbp(struct pt_regs *regs) | |||
1511 | */ | 1515 | */ |
1512 | smp_rmb(); /* pairs with wmb() in install_breakpoint() */ | 1516 | smp_rmb(); /* pairs with wmb() in install_breakpoint() */ |
1513 | if (unlikely(!test_bit(UPROBE_COPY_INSN, &uprobe->flags))) | 1517 | if (unlikely(!test_bit(UPROBE_COPY_INSN, &uprobe->flags))) |
1514 | goto restart; | 1518 | goto out; |
1515 | 1519 | ||
1516 | utask = current->utask; | 1520 | utask = current->utask; |
1517 | if (!utask) { | 1521 | if (!utask) { |
1518 | utask = add_utask(); | 1522 | utask = add_utask(); |
1519 | /* Cannot allocate; re-execute the instruction. */ | 1523 | /* Cannot allocate; re-execute the instruction. */ |
1520 | if (!utask) | 1524 | if (!utask) |
1521 | goto restart; | 1525 | goto out; |
1522 | } | 1526 | } |
1523 | 1527 | ||
1524 | handler_chain(uprobe, regs); | 1528 | handler_chain(uprobe, regs); |
@@ -1531,12 +1535,7 @@ static void handle_swbp(struct pt_regs *regs) | |||
1531 | return; | 1535 | return; |
1532 | } | 1536 | } |
1533 | 1537 | ||
1534 | restart: | 1538 | /* can_skip_sstep() succeeded, or restart if can't singlestep */ |
1535 | /* | ||
1536 | * cannot singlestep; cannot skip instruction; | ||
1537 | * re-execute the instruction. | ||
1538 | */ | ||
1539 | instruction_pointer_set(regs, bp_vaddr); | ||
1540 | out: | 1539 | out: |
1541 | put_uprobe(uprobe); | 1540 | put_uprobe(uprobe); |
1542 | } | 1541 | } |