aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/events/uprobes.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index a2ed82b4808c..1f02e3bbfc1d 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1530,14 +1530,26 @@ static void handle_swbp(struct pt_regs *regs)
1530 struct uprobe_task *utask; 1530 struct uprobe_task *utask;
1531 struct uprobe *uprobe; 1531 struct uprobe *uprobe;
1532 unsigned long bp_vaddr; 1532 unsigned long bp_vaddr;
1533 int is_swbp; 1533 int uninitialized_var(is_swbp);
1534 1534
1535 bp_vaddr = uprobe_get_swbp_addr(regs); 1535 bp_vaddr = uprobe_get_swbp_addr(regs);
1536 uprobe = find_active_uprobe(bp_vaddr, &is_swbp); 1536 uprobe = find_active_uprobe(bp_vaddr, &is_swbp);
1537 1537
1538 if (!uprobe) { 1538 if (!uprobe) {
1539 /* No matching uprobe; signal SIGTRAP. */ 1539 if (is_swbp > 0) {
1540 send_sig(SIGTRAP, current, 0); 1540 /* No matching uprobe; signal SIGTRAP. */
1541 send_sig(SIGTRAP, current, 0);
1542 } else {
1543 /*
1544 * Either we raced with uprobe_unregister() or we can't
1545 * access this memory. The latter is only possible if
1546 * another thread plays with our ->mm. In both cases
1547 * we can simply restart. If this vma was unmapped we
1548 * can pretend this insn was not executed yet and get
1549 * the (correct) SIGSEGV after restart.
1550 */
1551 instruction_pointer_set(regs, bp_vaddr);
1552 }
1541 return; 1553 return;
1542 } 1554 }
1543 1555