diff options
-rw-r--r-- | arch/x86/kernel/uprobes.c | 1 | ||||
-rw-r--r-- | kernel/events/uprobes.c | 15 | ||||
-rw-r--r-- | kernel/trace/trace_uprobe.c | 4 |
3 files changed, 9 insertions, 11 deletions
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index 4e33a35d659e..0ba4cfb4f412 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c | |||
@@ -681,7 +681,6 @@ static bool __skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) | |||
681 | continue; | 681 | continue; |
682 | 682 | ||
683 | if (auprobe->insn[i] == 0x90) { | 683 | if (auprobe->insn[i] == 0x90) { |
684 | regs->ip = uprobe_get_swbp_addr(regs); | ||
685 | regs->ip += i + 1; | 684 | regs->ip += i + 1; |
686 | return true; | 685 | return true; |
687 | } | 686 | } |
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 | } |
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index e668024773d4..17d9b2bcc28d 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c | |||
@@ -492,7 +492,7 @@ static void uprobe_trace_func(struct trace_uprobe *tu, struct pt_regs *regs) | |||
492 | return; | 492 | return; |
493 | 493 | ||
494 | entry = ring_buffer_event_data(event); | 494 | entry = ring_buffer_event_data(event); |
495 | entry->ip = uprobe_get_swbp_addr(task_pt_regs(current)); | 495 | entry->ip = instruction_pointer(task_pt_regs(current)); |
496 | data = (u8 *)&entry[1]; | 496 | data = (u8 *)&entry[1]; |
497 | for (i = 0; i < tu->nr_args; i++) | 497 | for (i = 0; i < tu->nr_args; i++) |
498 | call_fetch(&tu->args[i].fetch, regs, data + tu->args[i].offset); | 498 | call_fetch(&tu->args[i].fetch, regs, data + tu->args[i].offset); |
@@ -667,7 +667,7 @@ static void uprobe_perf_func(struct trace_uprobe *tu, struct pt_regs *regs) | |||
667 | if (!entry) | 667 | if (!entry) |
668 | goto out; | 668 | goto out; |
669 | 669 | ||
670 | entry->ip = uprobe_get_swbp_addr(task_pt_regs(current)); | 670 | entry->ip = instruction_pointer(task_pt_regs(current)); |
671 | data = (u8 *)&entry[1]; | 671 | data = (u8 *)&entry[1]; |
672 | for (i = 0; i < tu->nr_args; i++) | 672 | for (i = 0; i < tu->nr_args; i++) |
673 | call_fetch(&tu->args[i].fetch, regs, data + tu->args[i].offset); | 673 | call_fetch(&tu->args[i].fetch, regs, data + tu->args[i].offset); |