Skip to content

Commit e03b4a0

Browse files
mhiramatingomolnar
authored andcommitted
kprobes: Remove NMI context check
The in_nmi() check in pre_handler_kretprobe() is meant to avoid recursion, and blindly assumes that anything NMI is recursive. However, since commit: 9b38cc7 ("kretprobe: Prevent triggering kretprobe from within kprobe_flush_task") there is a better way to detect and avoid actual recursion. By setting a dummy kprobe, any actual exceptions will terminate early (by trying to handle the dummy kprobe), and recursion will not happen. Employ this to avoid the kretprobe_table_lock() recursion, replacing the over-eager in_nmi() check. Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lkml.kernel.org/r/159870615628.1229682.6087311596892125907.stgit@devnote2
1 parent 5e96ce8 commit e03b4a0

1 file changed

Lines changed: 4 additions & 12 deletions

File tree

kernel/kprobes.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,7 +1359,8 @@ static void cleanup_rp_inst(struct kretprobe *rp)
13591359
struct hlist_node *next;
13601360
struct hlist_head *head;
13611361

1362-
/* No race here */
1362+
/* To avoid recursive kretprobe by NMI, set kprobe busy here */
1363+
kprobe_busy_begin();
13631364
for (hash = 0; hash < KPROBE_TABLE_SIZE; hash++) {
13641365
kretprobe_table_lock(hash, &flags);
13651366
head = &kretprobe_inst_table[hash];
@@ -1369,6 +1370,8 @@ static void cleanup_rp_inst(struct kretprobe *rp)
13691370
}
13701371
kretprobe_table_unlock(hash, &flags);
13711372
}
1373+
kprobe_busy_end();
1374+
13721375
free_rp_inst(rp);
13731376
}
13741377
NOKPROBE_SYMBOL(cleanup_rp_inst);
@@ -2035,17 +2038,6 @@ static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
20352038
unsigned long hash, flags = 0;
20362039
struct kretprobe_instance *ri;
20372040

2038-
/*
2039-
* To avoid deadlocks, prohibit return probing in NMI contexts,
2040-
* just skip the probe and increase the (inexact) 'nmissed'
2041-
* statistical counter, so that the user is informed that
2042-
* something happened:
2043-
*/
2044-
if (unlikely(in_nmi())) {
2045-
rp->nmissed++;
2046-
return 0;
2047-
}
2048-
20492041
/* TODO: consider to only swap the RA after the last pre_handler fired */
20502042
hash = hash_ptr(current, KPROBE_HASH_BITS);
20512043
raw_spin_lock_irqsave(&rp->lock, flags);

0 commit comments

Comments
 (0)