aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/uprobes.c1
-rw-r--r--kernel/events/uprobes.c15
-rw-r--r--kernel/trace/trace_uprobe.c4
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
1534restart: 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);
1540out: 1539out:
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);