Skip to content

Commit

Permalink
lockdep: fixup irq tracing
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Peter Zijlstra committed Oct 25, 2007
1 parent c9927c2 commit 143a5d3
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 12 deletions.
7 changes: 1 addition & 6 deletions arch/x86/kernel/kprobes_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
7 changes: 1 addition & 6 deletions arch/x86/kernel/kprobes_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/kernel/traps_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/kernel/traps_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
5 changes: 5 additions & 0 deletions arch/x86/mm/fault_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
5 changes: 5 additions & 0 deletions arch/x86/mm/fault_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
21 changes: 21 additions & 0 deletions include/asm-x86/irqflags_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */

/*
Expand Down
20 changes: 20 additions & 0 deletions include/asm-x86/irqflags_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 143a5d3

Please sign in to comment.