From 75e29b18d9a46bf3193278e92dc95609a8cca2ab Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Mon, 25 Sep 2006 23:33:08 -0700 Subject: [PATCH] uml: stack usage reduction The KSTK_* macros used an inordinate amount of stack. In order to overcome an impedance mismatch between their interface, which just returns a single register value, and the interface of get_thread_regs, which took a full pt_regs, the implementation created an on-stack pt_regs, filled it in, and returned one field. do_task_stat calls KSTK_* twice, resulting in two local pt_regs, blowing out the stack. This patch changes the interface (and name) of get_thread_regs to just return a single register from a jmp_buf. The include of archsetjmp.h" in registers.h to get the definition of jmp_buf exposed a bogus include of in start_up.c. shouldn't be used anywhere any more since UML uses the klibc setjmp/longjmp. Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/start_up.c | 1 - arch/um/os-Linux/sys-i386/registers.c | 15 +++++++++------ arch/um/os-Linux/sys-x86_64/registers.c | 15 +++++++++------ 3 files changed, 18 insertions(+), 13 deletions(-) (limited to 'arch/um/os-Linux') diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 50314850400..7fe92680c7d 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c index 1f90a2d7138..7cd0369e02b 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/um/os-Linux/sys-i386/registers.c @@ -130,11 +130,14 @@ void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) HOST_FP_SIZE * sizeof(unsigned long)); } -void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) +unsigned long get_thread_reg(int reg, jmp_buf *buf) { - struct __jmp_buf *jmpbuf = buffer; - - UPT_SET(uml_regs, EIP, jmpbuf->__eip); - UPT_SET(uml_regs, UESP, jmpbuf->__esp); - UPT_SET(uml_regs, EBP, jmpbuf->__ebp); + switch(reg){ + case EIP: return buf[0]->__eip; + case UESP: return buf[0]->__esp; + case EBP: return buf[0]->__ebp; + default: + printk("get_thread_regs - unknown register %d\n", reg); + return 0; + } } diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c index e730447d6c0..cb8e8a26328 100644 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ b/arch/um/os-Linux/sys-x86_64/registers.c @@ -78,11 +78,14 @@ void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) HOST_FP_SIZE * sizeof(unsigned long)); } -void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) +unsigned long get_thread_reg(int reg, jmp_buf *buf) { - struct __jmp_buf *jmpbuf = buffer; - - UPT_SET(uml_regs, RIP, jmpbuf->__rip); - UPT_SET(uml_regs, RSP, jmpbuf->__rsp); - UPT_SET(uml_regs, RBP, jmpbuf->__rbp); + switch(reg){ + case RIP: return buf[0]->__rip; + case RSP: return buf[0]->__rsp; + case RBP: return buf[0]->__rbp; + default: + printk("get_thread_regs - unknown register %d\n", reg); + return 0; + } } -- cgit v1.2.3