forked from Minki/linux
lockdep: fixup irq tracing
Ensure we fixup the IRQ state before we hit any locking code. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
c9927c2bf4
commit
143a5d325d
@ -564,12 +564,7 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
|
||||
|
||||
resume_execution(cur, regs, kcb);
|
||||
regs->eflags |= kcb->kprobe_saved_eflags;
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
|
||||
if (raw_irqs_disabled_flags(regs->eflags))
|
||||
trace_hardirqs_off();
|
||||
else
|
||||
trace_hardirqs_on();
|
||||
#endif
|
||||
trace_hardirqs_fixup_flags(regs->eflags);
|
||||
|
||||
/*Restore back the original saved kprobes variables and continue. */
|
||||
if (kcb->kprobe_status == KPROBE_REENTER) {
|
||||
|
@ -551,12 +551,7 @@ int __kprobes post_kprobe_handler(struct pt_regs *regs)
|
||||
|
||||
resume_execution(cur, regs, kcb);
|
||||
regs->eflags |= kcb->kprobe_saved_rflags;
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
|
||||
if (raw_irqs_disabled_flags(regs->eflags))
|
||||
trace_hardirqs_off();
|
||||
else
|
||||
trace_hardirqs_on();
|
||||
#endif
|
||||
trace_hardirqs_fixup_flags(regs->eflags);
|
||||
|
||||
/* Restore the original saved kprobes variables and continue. */
|
||||
if (kcb->kprobe_status == KPROBE_REENTER) {
|
||||
|
@ -789,6 +789,8 @@ void restart_nmi(void)
|
||||
#ifdef CONFIG_KPROBES
|
||||
fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
|
||||
{
|
||||
trace_hardirqs_fixup();
|
||||
|
||||
if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
|
||||
== NOTIFY_STOP)
|
||||
return;
|
||||
|
@ -807,6 +807,8 @@ asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs)
|
||||
/* runs on IST stack. */
|
||||
asmlinkage void __kprobes do_int3(struct pt_regs * regs, long error_code)
|
||||
{
|
||||
trace_hardirqs_fixup();
|
||||
|
||||
if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) {
|
||||
return;
|
||||
}
|
||||
|
@ -303,6 +303,11 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
|
||||
int write, si_code;
|
||||
int fault;
|
||||
|
||||
/*
|
||||
* We can fault from pretty much anywhere, with unknown IRQ state.
|
||||
*/
|
||||
trace_hardirqs_fixup();
|
||||
|
||||
/* get the address */
|
||||
address = read_cr2();
|
||||
|
||||
|
@ -304,6 +304,11 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
|
||||
unsigned long flags;
|
||||
siginfo_t info;
|
||||
|
||||
/*
|
||||
* We can fault from pretty much anywhere, with unknown IRQ state.
|
||||
*/
|
||||
trace_hardirqs_fixup();
|
||||
|
||||
tsk = current;
|
||||
mm = tsk->mm;
|
||||
prefetchw(&mm->mmap_sem);
|
||||
|
@ -129,6 +129,27 @@ static inline int raw_irqs_disabled(void)
|
||||
|
||||
return raw_irqs_disabled_flags(flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* makes the traced hardirq state match with the machine state
|
||||
*
|
||||
* should be a rarely used function, only in places where its
|
||||
* otherwise impossible to know the irq state, like in traps.
|
||||
*/
|
||||
static inline void trace_hardirqs_fixup_flags(unsigned long flags)
|
||||
{
|
||||
if (raw_irqs_disabled_flags(flags))
|
||||
trace_hardirqs_off();
|
||||
else
|
||||
trace_hardirqs_on();
|
||||
}
|
||||
|
||||
static inline void trace_hardirqs_fixup(void)
|
||||
{
|
||||
unsigned long flags = __raw_local_save_flags();
|
||||
|
||||
trace_hardirqs_fixup_flags(flags);
|
||||
}
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
|
@ -111,6 +111,26 @@ static inline int raw_irqs_disabled(void)
|
||||
return raw_irqs_disabled_flags(flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* makes the traced hardirq state match with the machine state
|
||||
*
|
||||
* should be a rarely used function, only in places where its
|
||||
* otherwise impossible to know the irq state, like in traps.
|
||||
*/
|
||||
static inline void trace_hardirqs_fixup_flags(unsigned long flags)
|
||||
{
|
||||
if (raw_irqs_disabled_flags(flags))
|
||||
trace_hardirqs_off();
|
||||
else
|
||||
trace_hardirqs_on();
|
||||
}
|
||||
|
||||
static inline void trace_hardirqs_fixup(void)
|
||||
{
|
||||
unsigned long flags = __raw_local_save_flags();
|
||||
|
||||
trace_hardirqs_fixup_flags(flags);
|
||||
}
|
||||
/*
|
||||
* Used in the idle loop; sti takes one instruction cycle
|
||||
* to complete:
|
||||
|
Loading…
Reference in New Issue
Block a user