--- arch/x86/kernel/setup64.c | 2 +- include/asm-x86/irqflags_64.h | 22 ++++++++-------------- kernel/irq/handle.c | 2 ++ 3 files changed, 11 insertions(+), 15 deletions(-) Index: linux-2.6/arch/x86/kernel/setup64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup64.c 2007-11-09 22:51:34.000000000 -0800 +++ linux-2.6/arch/x86/kernel/setup64.c 2007-11-09 22:52:36.000000000 -0800 @@ -126,7 +126,7 @@ void pda_init(int cpu) mb(); pda->cpunumber = cpu; - pda->irqcount = -1; + pda->irqcount = 0; pda->kernelstack = (unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; pda->active_mm = &init_mm; Index: linux-2.6/include/asm-x86/irqflags_64.h =================================================================== --- linux-2.6.orig/include/asm-x86/irqflags_64.h 2007-11-09 22:51:34.000000000 -0800 +++ linux-2.6/include/asm-x86/irqflags_64.h 2007-11-09 22:52:36.000000000 -0800 @@ -10,6 +10,7 @@ #ifndef _ASM_IRQFLAGS_H #define _ASM_IRQFLAGS_H #include +#include #ifndef __ASSEMBLY__ /* @@ -36,12 +37,9 @@ static inline unsigned long __raw_local_ static inline void raw_local_irq_restore(unsigned long flags) { - __asm__ __volatile__( - "pushq %0 ; popfq" - : /* no output */ - :"g" (flags) - :"memory", "cc" - ); + sub_pda(irqcount, 1); + if (!read_pda(irqcount)) + __asm__ __volatile__("sti" : : : "memory"); } #ifdef CONFIG_X86_VSMP @@ -94,11 +92,9 @@ static inline int raw_irqs_disabled_flag static inline unsigned long __raw_local_irq_save(void) { - unsigned long flags = __raw_local_save_flags(); - - raw_local_irq_disable(); - - return flags; + add_pda(irqcount, 1); + __asm__ __volatile__("cli" : : : "memory"); + return 0; } #define raw_local_irq_save(flags) \ @@ -106,9 +102,7 @@ static inline unsigned long __raw_local_ static inline int raw_irqs_disabled(void) { - unsigned long flags = __raw_local_save_flags(); - - return raw_irqs_disabled_flags(flags); + return read_pda(irqcount) != 0; } /* Index: linux-2.6/kernel/irq/handle.c =================================================================== --- linux-2.6.orig/kernel/irq/handle.c 2007-11-09 22:57:53.000000000 -0800 +++ linux-2.6/kernel/irq/handle.c 2007-11-09 23:01:26.000000000 -0800 @@ -135,6 +135,8 @@ irqreturn_t handle_IRQ_event(unsigned in if (!(action->flags & IRQF_DISABLED)) local_irq_enable_in_hardirq(); + else + write_pda(irqcount, 1); do { ret = action->handler(irq, action->dev_id);