summaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/irq.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-06-26 17:35:44 +0200
committerDavid Woodhouse <dwmw2@infradead.org>2006-06-26 17:35:44 +0200
commit62ed948cb1405fe95d61d8c6445c102e0c9da0a6 (patch)
treef139adcc861a05e7cc09cdb387a271a652fc2d07 /arch/i386/kernel/irq.c
parent[MTD] Initialize 'writesize' (diff)
parent[PATCH] uclinux: use PER_LINUX_32BIT in binfmt_flat (diff)
downloadlinux-62ed948cb1405fe95d61d8c6445c102e0c9da0a6.tar.xz
linux-62ed948cb1405fe95d61d8c6445c102e0c9da0a6.zip
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/i386/kernel/irq.c')
-rw-r--r--arch/i386/kernel/irq.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index f3a9c78c4a24..49ce4c31b713 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -42,8 +42,8 @@ union irq_ctx {
u32 stack[THREAD_SIZE/sizeof(u32)];
};
-static union irq_ctx *hardirq_ctx[NR_CPUS];
-static union irq_ctx *softirq_ctx[NR_CPUS];
+static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
+static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
#endif
/*
@@ -95,6 +95,14 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
irqctx->tinfo.task = curctx->tinfo.task;
irqctx->tinfo.previous_esp = current_stack_pointer;
+ /*
+ * Copy the softirq bits in preempt_count so that the
+ * softirq checks work in the hardirq context.
+ */
+ irqctx->tinfo.preempt_count =
+ irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK |
+ curctx->tinfo.preempt_count & SOFTIRQ_MASK;
+
asm volatile(
" xchgl %%ebx,%%esp \n"
" call __do_IRQ \n"