From: Arjan van de Ven I have 4Kb stacks + IRQ stacks working in my tree. The biggest part of the 4K-stacks work is changing hardcoded 8Kb assumptions to the proper, pre-existing define for this. That part of the patch is appropriate in general, even when 4Kb stacks might not be. --- arch/i386/kernel/entry.S | 4 ++-- arch/i386/kernel/head.S | 4 +++- arch/i386/kernel/irq.c | 2 +- arch/i386/kernel/process.c | 6 ++++-- arch/i386/kernel/traps.c | 2 +- include/asm-i386/thread_info.h | 9 ++++++--- 6 files changed, 17 insertions(+), 10 deletions(-) diff -puN arch/i386/kernel/entry.S~use-THREAD_SIZE arch/i386/kernel/entry.S --- 25/arch/i386/kernel/entry.S~use-THREAD_SIZE 2004-02-11 23:09:56.000000000 -0800 +++ 25-akpm/arch/i386/kernel/entry.S 2004-02-11 23:18:47.000000000 -0800 @@ -541,8 +541,8 @@ ENTRY(nmi) /* Do not access memory above the end of our stack page, * it might not exist. */ - andl $0x1fff,%eax - cmpl $0x1fec,%eax + andl $(THREAD_SIZE-1),%eax + cmpl $(THREAD_SIZE-20),%eax popl %eax jae nmi_stack_correct cmpl $sysenter_entry,12(%esp) diff -puN arch/i386/kernel/head.S~use-THREAD_SIZE arch/i386/kernel/head.S --- 25/arch/i386/kernel/head.S~use-THREAD_SIZE 2004-02-11 23:09:56.000000000 -0800 +++ 25-akpm/arch/i386/kernel/head.S 2004-02-11 23:18:47.000000000 -0800 @@ -16,6 +16,8 @@ #include #include #include +#include + #define OLD_CL_MAGIC_ADDR 0x90020 #define OLD_CL_MAGIC 0xA33F @@ -325,7 +327,7 @@ rp_sidt: ret ENTRY(stack_start) - .long init_thread_union+8192 + .long init_thread_union+THREAD_SIZE .long __BOOT_DS /* This is the default interrupt "handler" :-) */ diff -puN arch/i386/kernel/irq.c~use-THREAD_SIZE arch/i386/kernel/irq.c --- 25/arch/i386/kernel/irq.c~use-THREAD_SIZE 2004-02-11 23:09:56.000000000 -0800 +++ 25-akpm/arch/i386/kernel/irq.c 2004-02-11 23:09:56.000000000 -0800 @@ -437,7 +437,7 @@ asmlinkage unsigned int do_IRQ(struct pt long esp; __asm__ __volatile__("andl %%esp,%0" : - "=r" (esp) : "0" (8191)); + "=r" (esp) : "0" (THREAD_SIZE - 1)); if (unlikely(esp < (sizeof(struct thread_info) + 1024))) { printk("do_IRQ: stack overflow: %ld\n", esp - sizeof(struct thread_info)); diff -puN arch/i386/kernel/process.c~use-THREAD_SIZE arch/i386/kernel/process.c --- 25/arch/i386/kernel/process.c~use-THREAD_SIZE 2004-02-11 23:09:56.000000000 -0800 +++ 25-akpm/arch/i386/kernel/process.c 2004-02-11 23:18:48.000000000 -0800 @@ -696,6 +696,8 @@ extern void scheduling_functions_start_h extern void scheduling_functions_end_here(void); #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) +#define top_esp (THREAD_SIZE - sizeof(unsigned long)) +#define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long)) unsigned long get_wchan(struct task_struct *p) { @@ -706,12 +708,12 @@ unsigned long get_wchan(struct task_stru return 0; stack_page = (unsigned long)p->thread_info; esp = p->thread.esp; - if (!stack_page || esp < stack_page || esp > 8188+stack_page) + if (!stack_page || esp < stack_page || esp > top_esp+stack_page) return 0; /* include/asm-i386/system.h:switch_to() pushes ebp last. */ ebp = *(unsigned long *) esp; do { - if (ebp < stack_page || ebp > 8184+stack_page) + if (ebp < stack_page || ebp > top_ebp+stack_page) return 0; eip = *(unsigned long *) (ebp+4); if (eip < first_sched || eip >= last_sched) diff -puN arch/i386/kernel/traps.c~use-THREAD_SIZE arch/i386/kernel/traps.c --- 25/arch/i386/kernel/traps.c~use-THREAD_SIZE 2004-02-11 23:09:56.000000000 -0800 +++ 25-akpm/arch/i386/kernel/traps.c 2004-02-11 23:18:49.000000000 -0800 @@ -155,7 +155,7 @@ void show_trace_task(struct task_struct unsigned long esp = tsk->thread.esp; /* User space on another CPU? */ - if ((esp ^ (unsigned long)tsk->thread_info) & (PAGE_MASK<<1)) + if ((esp ^ (unsigned long)tsk->thread_info) & ~(THREAD_SIZE - 1)) return; show_trace(tsk, (unsigned long *)esp); } diff -puN include/asm-i386/thread_info.h~use-THREAD_SIZE include/asm-i386/thread_info.h --- 25/include/asm-i386/thread_info.h~use-THREAD_SIZE 2004-02-11 23:09:56.000000000 -0800 +++ 25-akpm/include/asm-i386/thread_info.h 2004-02-11 23:21:26.000000000 -0800 @@ -77,16 +77,17 @@ struct thread_info { #define init_thread_info (init_thread_union.thread_info) #define init_stack (init_thread_union.stack) +#define THREAD_SIZE (2*PAGE_SIZE) + /* how to get the thread information struct from C */ static inline struct thread_info *current_thread_info(void) { struct thread_info *ti; - __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~8191UL)); + __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~(THREAD_SIZE - 1))); return ti; } /* thread information allocation */ -#define THREAD_SIZE (2*PAGE_SIZE) #define alloc_thread_info(task) ((struct thread_info *)kmalloc(THREAD_SIZE, GFP_KERNEL)) #define free_thread_info(info) kfree(info) #define get_thread_info(ti) get_task_struct((ti)->task) @@ -94,9 +95,11 @@ static inline struct thread_info *curren #else /* !__ASSEMBLY__ */ +#define THREAD_SIZE 8192 + /* how to get the thread information struct from ASM */ #define GET_THREAD_INFO(reg) \ - movl $-8192, reg; \ + movl $-THREAD_SIZE, reg; \ andl %esp, reg #endif _