diff options
Diffstat (limited to 'arch/x86_64/kernel/traps.c')
-rw-r--r-- | arch/x86_64/kernel/traps.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index ee1b2da9e5e7..28d50dc540e8 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -90,6 +90,20 @@ static inline void conditional_sti(struct pt_regs *regs) | |||
90 | local_irq_enable(); | 90 | local_irq_enable(); |
91 | } | 91 | } |
92 | 92 | ||
93 | static inline void preempt_conditional_sti(struct pt_regs *regs) | ||
94 | { | ||
95 | preempt_disable(); | ||
96 | if (regs->eflags & X86_EFLAGS_IF) | ||
97 | local_irq_enable(); | ||
98 | } | ||
99 | |||
100 | static inline void preempt_conditional_cli(struct pt_regs *regs) | ||
101 | { | ||
102 | if (regs->eflags & X86_EFLAGS_IF) | ||
103 | local_irq_disable(); | ||
104 | preempt_enable_no_resched(); | ||
105 | } | ||
106 | |||
93 | static int kstack_depth_to_print = 10; | 107 | static int kstack_depth_to_print = 10; |
94 | 108 | ||
95 | #ifdef CONFIG_KALLSYMS | 109 | #ifdef CONFIG_KALLSYMS |
@@ -693,7 +707,7 @@ asmlinkage void __kprobes do_debug(struct pt_regs * regs, | |||
693 | SIGTRAP) == NOTIFY_STOP) | 707 | SIGTRAP) == NOTIFY_STOP) |
694 | return; | 708 | return; |
695 | 709 | ||
696 | conditional_sti(regs); | 710 | preempt_conditional_sti(regs); |
697 | 711 | ||
698 | /* Mask out spurious debug traps due to lazy DR7 setting */ | 712 | /* Mask out spurious debug traps due to lazy DR7 setting */ |
699 | if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { | 713 | if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { |
@@ -738,11 +752,13 @@ asmlinkage void __kprobes do_debug(struct pt_regs * regs, | |||
738 | 752 | ||
739 | clear_dr7: | 753 | clear_dr7: |
740 | set_debugreg(0UL, 7); | 754 | set_debugreg(0UL, 7); |
755 | preempt_conditional_cli(regs); | ||
741 | return; | 756 | return; |
742 | 757 | ||
743 | clear_TF_reenable: | 758 | clear_TF_reenable: |
744 | set_tsk_thread_flag(tsk, TIF_SINGLESTEP); | 759 | set_tsk_thread_flag(tsk, TIF_SINGLESTEP); |
745 | regs->eflags &= ~TF_MASK; | 760 | regs->eflags &= ~TF_MASK; |
761 | preempt_conditional_cli(regs); | ||
746 | } | 762 | } |
747 | 763 | ||
748 | static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr) | 764 | static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr) |