diff options
-rw-r--r-- | arch/x86/kernel/kprobes.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index f0f2b98b9e20..7dd918633c30 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c | |||
@@ -427,6 +427,20 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, | |||
427 | /* Replace the return addr with trampoline addr */ | 427 | /* Replace the return addr with trampoline addr */ |
428 | *sara = (unsigned long) &kretprobe_trampoline; | 428 | *sara = (unsigned long) &kretprobe_trampoline; |
429 | } | 429 | } |
430 | /* | ||
431 | * We have reentered the kprobe_handler(), since another probe was hit while | ||
432 | * within the handler. We save the original kprobes variables and just single | ||
433 | * step on the instruction of the new probe without calling any user handlers. | ||
434 | */ | ||
435 | static void __kprobes reenter_kprobe(struct kprobe *p, struct pt_regs *regs, | ||
436 | struct kprobe_ctlblk *kcb) | ||
437 | { | ||
438 | save_previous_kprobe(kcb); | ||
439 | set_current_kprobe(p, regs, kcb); | ||
440 | kprobes_inc_nmissed_count(p); | ||
441 | prepare_singlestep(p, regs); | ||
442 | kcb->kprobe_status = KPROBE_REENTER; | ||
443 | } | ||
430 | 444 | ||
431 | /* | 445 | /* |
432 | * Interrupts are disabled on entry as trap3 is an interrupt gate and they | 446 | * Interrupts are disabled on entry as trap3 is an interrupt gate and they |
@@ -471,17 +485,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
471 | goto no_kprobe; | 485 | goto no_kprobe; |
472 | #endif | 486 | #endif |
473 | } | 487 | } |
474 | /* We have reentered the kprobe_handler(), since | 488 | reenter_kprobe(p, regs, kcb); |
475 | * another probe was hit while within the handler. | ||
476 | * We here save the original kprobes variables and | ||
477 | * just single step on the instruction of the new probe | ||
478 | * without calling any user handlers. | ||
479 | */ | ||
480 | save_previous_kprobe(kcb); | ||
481 | set_current_kprobe(p, regs, kcb); | ||
482 | kprobes_inc_nmissed_count(p); | ||
483 | prepare_singlestep(p, regs); | ||
484 | kcb->kprobe_status = KPROBE_REENTER; | ||
485 | return 1; | 489 | return 1; |
486 | } else { | 490 | } else { |
487 | if (*addr != BREAKPOINT_INSTRUCTION) { | 491 | if (*addr != BREAKPOINT_INSTRUCTION) { |