generate incorrect output with certain kernel constructs when
-mregparm=3 is used.
+config IRQSTACKS
+ bool "Use separate IRQ stacks"
+ help
+ If you say Y here the kernel will use a separate IRQ stack on each
+ cpu to handle interrupts.
+
+config STACK_SIZE_SHIFT
+ int "Kernel stack size (12 => 4KB, 13 => 8KB, 14 => 16KB)"
+ range 12 14
+ default 12 if IRQSTACKS
+ default 13
+ help
+ Select kernel stack size. 4KB stacks are best as they let
+ the system scale further. Use 8KB stacks if you have an
+ experimental kernel where a stack overlow with a 4KB stack
+ might occur. Use 16KB stacks if you want to safely support
+ Windows device drivers using either Linuxant or ndiswrapper.
+
+config STACK_WARN
+ int "Print stack trace when stack grows beyond specified bytes"
+ default 4096 if IRQSTACKS
+ default 4096
+ help
+ The kernel will print a stack trace when the current stack exceeds
+ the specified size.
+
endmenu
CONFIG_EARLY_PRINTK=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_FRAME_POINTER is not set
-CONFIG_4KSTACKS=y
+# CONFIG_4KSTACKS is not set
CONFIG_X86_FIND_SMP_CONFIG=y
CONFIG_X86_MPPARSE=y
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/personality.h>
+#include <linux/thread_info.h>
#include <asm/ucontext.h>
#include "sigframe.h"
#include <asm/fixmap.h>
#include <asm/processor.h>
-#include <asm/thread_info.h>
#define DEFINE(sym, val) \
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
/*
* per-CPU IRQ handling stacks
*/
+#ifdef CONFIG_IRQSTACKS
union irq_ctx *hardirq_ctx[NR_CPUS];
union irq_ctx *softirq_ctx[NR_CPUS];
+#endif
/*
* Special irq handlers.
int status = 1; /* Force the "do bottom halves" bit */
int retval = 0;
+ if (!(action->flags & SA_INTERRUPT))
+ local_irq_enable();
+
do {
status |= action->flags;
retval |= action->handler(irq, action->dev_id, regs);
u32 *isp;
union irq_ctx * curctx;
union irq_ctx * irqctx;
-
+#ifdef CONFIG_IRQSTACKS
curctx = (union irq_ctx *) current_thread_info();
irqctx = hardirq_ctx[smp_processor_id()];
-
+#else
+ curctx = irqctx = (union irq_ctx *)0;
+#endif
spin_unlock(&desc->lock);
/*
break;
desc->status &= ~IRQ_PENDING;
}
-
desc->status &= ~IRQ_INPROGRESS;
out:
}
+#ifdef CONFIG_IRQSTACKS
/*
* These should really be __section__(".bss.page_aligned") as well, but
* gcc's 3.0 and earlier don't handle that correctly.
}
EXPORT_SYMBOL(do_softirq);
+#endif
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
CONFIG_X86_GENERIC=y
+# CONFIG_QEMU is not set
CONFIG_X86_CMPXCHG=y
CONFIG_X86_XADD=y
CONFIG_X86_L1_CACHE_SHIFT=7
# CONFIG_MATH_EMULATION is not set
CONFIG_MTRR=y
CONFIG_REGPARM=y
+CONFIG_IRQSTACKS=y
+CONFIG_STACK_SIZE_SHIFT=13
+CONFIG_STACK_WARN=4000
#
# Power management options (ACPI, APM)
u32 stack[THREAD_SIZE/sizeof(u32)];
};
+#ifdef CONFIG_IRQSTACKS
extern union irq_ctx *hardirq_ctx[NR_CPUS];
extern union irq_ctx *softirq_ctx[NR_CPUS];
#define __ARCH_HAS_DO_SOFTIRQ
+#else
+#define irq_ctx_init(cpu) do { ; } while (0)
+#endif
+
struct irqaction;
struct pt_regs;
asmlinkage int handle_IRQ_event(unsigned int, struct pt_regs *,
#define MODULE_REGPARM ""
#endif
+#if (CONFIG_STACK_SIZE_SHIFT < 12)
+#define MODULE_STACKSIZE "TINYSTACKS "
+#elif (CONFIG_STACK_SIZE_SHIFT == 12)
#define MODULE_STACKSIZE "4KSTACKS "
+#elif (CONFIG_STACK_SIZE_SHIFT == 13)
+#define MODULE_STACKSIZE "8KSTACKS "
+#elif (CONFIG_STACK_SIZE_SHIFT == 14)
+#define MODULE_STACKSIZE "16KSTACKS "
+#elif (CONFIG_STACK_SIZE_SHIFT > 14)
+#define MODULE_STACKSIZE "HUGESTACKS "
+#else
+#define MODULE_STACKSIZE ""
+#endif
#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
#define ARCH_MIN_TASKALIGN 16
-
-#define STACK_PAGE_COUNT (4096/PAGE_SIZE)
-
-
+#if ((1<<CONFIG_STACK_SIZE_SHIFT) < PAGE_SIZE)
+#error (1<<CONFIG_STACK_SIZE_SHIFT) must be at least PAGE_SIZE
+#endif
+#define STACK_PAGE_COUNT ((1<<CONFIG_STACK_SIZE_SHIFT)/PAGE_SIZE)
struct thread_struct {
#endif
#define PREEMPT_ACTIVE 0x4000000
-#define THREAD_SIZE (4096)
+#define THREAD_SIZE (1<<CONFIG_STACK_SIZE_SHIFT)
+#define STACK_WARN (CONFIG_STACK_WARN)
-#define STACK_WARN (THREAD_SIZE/8)
/*
* macros/functions for gaining access to the thread information structure
*