diff options
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/kernel/kprobes.c | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index 76a28b007be9..ebfa2c9241ca 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c | |||
@@ -302,9 +302,6 @@ int __kprobes kprobe_handler(struct pt_regs *regs) | |||
302 | int ret = 0; | 302 | int ret = 0; |
303 | kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->rip - sizeof(kprobe_opcode_t)); | 303 | kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->rip - sizeof(kprobe_opcode_t)); |
304 | 304 | ||
305 | /* We're in an interrupt, but this is clear and BUG()-safe. */ | ||
306 | preempt_disable(); | ||
307 | |||
308 | /* Check we're not actually recursing */ | 305 | /* Check we're not actually recursing */ |
309 | if (kprobe_running()) { | 306 | if (kprobe_running()) { |
310 | /* We *are* holding lock here, so this is safe. | 307 | /* We *are* holding lock here, so this is safe. |
@@ -372,6 +369,11 @@ int __kprobes kprobe_handler(struct pt_regs *regs) | |||
372 | goto no_kprobe; | 369 | goto no_kprobe; |
373 | } | 370 | } |
374 | 371 | ||
372 | /* | ||
373 | * This preempt_disable() matches the preempt_enable_no_resched() | ||
374 | * in post_kprobe_handler() | ||
375 | */ | ||
376 | preempt_disable(); | ||
375 | kprobe_status = KPROBE_HIT_ACTIVE; | 377 | kprobe_status = KPROBE_HIT_ACTIVE; |
376 | set_current_kprobe(p, regs); | 378 | set_current_kprobe(p, regs); |
377 | 379 | ||
@@ -385,7 +387,6 @@ ss_probe: | |||
385 | return 1; | 387 | return 1; |
386 | 388 | ||
387 | no_kprobe: | 389 | no_kprobe: |
388 | preempt_enable_no_resched(); | ||
389 | return ret; | 390 | return ret; |
390 | } | 391 | } |
391 | 392 | ||
@@ -456,7 +457,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
456 | /* | 457 | /* |
457 | * By returning a non-zero value, we are telling | 458 | * By returning a non-zero value, we are telling |
458 | * kprobe_handler() that we have handled unlocking | 459 | * kprobe_handler() that we have handled unlocking |
459 | * and re-enabling preemption. | 460 | * and re-enabling preemption |
460 | */ | 461 | */ |
461 | return 1; | 462 | return 1; |
462 | } | 463 | } |
@@ -599,29 +600,29 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
599 | unsigned long val, void *data) | 600 | unsigned long val, void *data) |
600 | { | 601 | { |
601 | struct die_args *args = (struct die_args *)data; | 602 | struct die_args *args = (struct die_args *)data; |
603 | int ret = NOTIFY_DONE; | ||
604 | |||
605 | preempt_disable(); | ||
602 | switch (val) { | 606 | switch (val) { |
603 | case DIE_INT3: | 607 | case DIE_INT3: |
604 | if (kprobe_handler(args->regs)) | 608 | if (kprobe_handler(args->regs)) |
605 | return NOTIFY_STOP; | 609 | ret = NOTIFY_STOP; |
606 | break; | 610 | break; |
607 | case DIE_DEBUG: | 611 | case DIE_DEBUG: |
608 | if (post_kprobe_handler(args->regs)) | 612 | if (post_kprobe_handler(args->regs)) |
609 | return NOTIFY_STOP; | 613 | ret = NOTIFY_STOP; |
610 | break; | 614 | break; |
611 | case DIE_GPF: | 615 | case DIE_GPF: |
612 | if (kprobe_running() && | ||
613 | kprobe_fault_handler(args->regs, args->trapnr)) | ||
614 | return NOTIFY_STOP; | ||
615 | break; | ||
616 | case DIE_PAGE_FAULT: | 616 | case DIE_PAGE_FAULT: |
617 | if (kprobe_running() && | 617 | if (kprobe_running() && |
618 | kprobe_fault_handler(args->regs, args->trapnr)) | 618 | kprobe_fault_handler(args->regs, args->trapnr)) |
619 | return NOTIFY_STOP; | 619 | ret = NOTIFY_STOP; |
620 | break; | 620 | break; |
621 | default: | 621 | default: |
622 | break; | 622 | break; |
623 | } | 623 | } |
624 | return NOTIFY_DONE; | 624 | preempt_enable(); |
625 | return ret; | ||
625 | } | 626 | } |
626 | 627 | ||
627 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | 628 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) |
@@ -647,7 +648,6 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
647 | 648 | ||
648 | void __kprobes jprobe_return(void) | 649 | void __kprobes jprobe_return(void) |
649 | { | 650 | { |
650 | preempt_enable_no_resched(); | ||
651 | asm volatile (" xchg %%rbx,%%rsp \n" | 651 | asm volatile (" xchg %%rbx,%%rsp \n" |
652 | " int3 \n" | 652 | " int3 \n" |
653 | " .globl jprobe_return_end \n" | 653 | " .globl jprobe_return_end \n" |