Eric Sandeen <sandeen@sandeen.net> writes:That could be easily fixed by executing the printk on the interrupt stack on i386. Currently it is before the stack switch which is wrong agreed. On x86-64 it should already execute on the interrupt stack. Or perhaps it would be better to just move the stack switch on i386 into entry.S too similar to 64bit. That wouldn't help without interrupt stacks of course, but these should be always on anyways even with 8k stacks. Experimental patch appended to do this. -Andi --- i386: Execute stack overflow warning on interrupt stack Previously it would run on the process stack, which risks overflow an already low stack. Instead execute it on the interrupt stack. Based on an observation by Eric Sandeen. Signed-off-by: Andi Kleen <andi@firstfloor.org> Index: linux/arch/x86/kernel/irq_32.c =================================================================== --- linux.orig/arch/x86/kernel/irq_32.c +++ linux/arch/x86/kernel/irq_32.c @@ -61,6 +61,26 @@ static union irq_ctx *hardirq_ctx[NR_CPU static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; #endif +static void stack_overflow(void) +{ + printk("low stack detected by irq handler\n"); + dump_stack(); +} + +static inline void call_on_stack2(void *func, unsigned long stack, + unsigned long arg1, unsigned long arg2) +{ + unsigned long bx; + asm volatile( + " xchgl %%ebx,%%esp \n" + " call *%%edi \n" + " movl %%ebx,%%esp \n" + : "=a" (arg1), "=d" (arg2), "=b" (bx) + : "0" (arg1), "1" (arg2), "2" (stack), + "D" (func) + : "memory", "cc"); +} + /* * do_IRQ handles all normal device IRQ's (the special * SMP cross-CPU interrupts have their own specific @@ -76,6 +96,7 @@ unsigned int do_IRQ(struct pt_regs *regs union irq_ctx *curctx, *irqctx; u32 *isp; #endif + int overflow = 0; if (unlikely((unsigned)irq >= NR_IRQS)) { printk(KERN_EMERG "%s: cannot handle IRQ %d\n", @@ -92,11 +113,8 @@ unsigned int do_IRQ(struct pt_regs *regs __asm__ __volatile__("andl %%esp,%0" : "=r" (sp) : "0" (THREAD_SIZE - 1)); - if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) { - printk("do_IRQ: stack overflow: %ld\n", - sp - sizeof(struct thread_info)); - dump_stack(); - } + if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) + overflow = 1; } #endif @@ -112,8 +130,6 @@ unsigned int do_IRQ(struct pt_regs *regs * current stack (which is the irq stack already after all) */ if (curctx != irqctx) { - int arg1, arg2, bx; - /* build the stack frame on the IRQ stack */ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)); irqctx->tinfo.task = curctx->tinfo.task; @@ -127,18 +143,20 @@ unsigned int do_IRQ(struct pt_regs *regs (irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK) | (curctx->tinfo.preempt_count & SOFTIRQ_MASK); - asm volatile( - " xchgl %%ebx,%%esp \n" - " call *%%edi \n" - " movl %%ebx,%%esp \n" - : "=a" (arg1), "=d" (arg2), "=b" (bx) - : "0" (irq), "1" (desc), "2" (isp), - "D" (desc->handle_irq) - : "memory", "cc" - ); + /* Execute warning on interrupt stack */ + if (unlikely(overflow)) + call_on_stack2(stack_overflow, isp, 0, 0); + + call_on_stack2(desc->handle_irq, isp, irq, desc); + } else #endif + { + /* AK: Slightly bogus here */ + if (overflow) + stack_overflow(); desc->handle_irq(irq, desc); + } irq_exit(); set_irq_regs(old_regs); --
| Andrew Morton | 2.6.22-rc6-mm1 |
| Avi Kivity | [PATCH 002/104] KVM: SMP: Add vcpu_id field in struct vcpu |
| Pavel Machek | Re: suspend2 merge (was Re: [Suspend2-devel] Re: CFS and suspend2: hang in atomic ... |
| Con Kolivas | Re: -mm merge plans for 2.6.23 |
git: | |
| Junio C Hamano | What's cooking in git.git (topics) |
| Pazu | qgit on Mac OS X |
| Junio C Hamano | Re: [PATCH] Deprecate git-lost-found |
| Steffen Prohaska | Re: CVS -> SVN -> Git |
| Richard Stallman | Real men don't attack straw men |
| Siju George | Dell Latitude D820 |
| Lars Noodén | Call for testing - uvideo(4) |
| peter | ntpd not synching |
| Stephen Pierce | SLS |
| Dave `geek' Gymer | WARNING (was Re: New afio release) |
| Theodore Ts'o | Re: Splitting comp.os.linux |
| Goetz Schuchart | Re: [?] df: cannot read table of mounted filesystems |
| magical mounts | 9 hours ago | Linux kernel |
| Problem in scim in Fedora 9 | 9 hours ago | Linux general |
| The new Western Digital power saving drives | 10 hours ago | Hardware |
| Battery Maximizer Software | 1 day ago | Linux kernel |
| windows folder creation surprise | 1 day ago | Windows |
| Firewall | 1 day ago | OpenBSD |
| IP layer send packet | 2 days ago | Linux kernel |
| dtrace for linux available | 2 days ago | Linux kernel |
| Unable to mount ramdisk image using UBoot while upgrading to 2.6.15 kernel for a MPC8540 based target | 3 days ago | Linux kernel |
| RealTek RTL8169 - can't connect | 3 days ago | NetBSD |
