Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] ARM: Remove global nwfpe register variable

Recent changes to nwfpe broke the build with some gcc versions:

In file included from arch/arm/nwfpe/softfloat.c:33:
arch/arm/nwfpe/fpa11.h:32: global register variable follows a function definition
make[1]: *** [arch/arm/nwfpe/softfloat.o] Error 1

Since we now ensure that the kernel stack is empty when returning
to user space, we can now access the userspace registers with
reference to the kernel stack using current_thread_info(), rather
than remembering the stack pointer at the time nwfpe was called.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by

Russell King and committed by
Russell King
b66da4a4 f60f7008

+9 -11
+1 -3
arch/arm/nwfpe/fpa11.h
··· 29 29 * stack+task struct. Use the same method as 'current' uses to 30 30 * reach them. 31 31 */ 32 - register unsigned long *user_registers asm("sl"); 33 - 34 - #define GET_USERREG() (user_registers) 32 + #define GET_USERREG() ((struct pt_regs *)(THREAD_START_SP + (unsigned long)current_thread_info()) - 1) 35 33 36 34 #include <linux/config.h> 37 35 #include <linux/thread_info.h>
+1 -1
arch/arm/nwfpe/fpmodule.c
··· 132 132 printk(KERN_DEBUG 133 133 "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n", 134 134 current->comm, current->pid, flags, 135 - __builtin_return_address(0), GET_USERREG()[15]); 135 + __builtin_return_address(0), GET_USERREG()->ARM_pc); 136 136 #endif 137 137 138 138 /* Keep SoftFloat exception flags up to date. */
+7 -7
arch/arm/nwfpe/fpmodule.inl
··· 28 28 for this in this routine. LDF/STF instructions with Rn = PC 29 29 depend on the PC being correct, as they use PC+8 in their 30 30 address calculations. */ 31 - unsigned long *userRegisters = GET_USERREG(); 32 - unsigned int val = userRegisters[nReg]; 31 + struct pt_regs *regs = GET_USERREG(); 32 + unsigned int val = regs->uregs[nReg]; 33 33 if (REG_PC == nReg) 34 34 val -= 4; 35 35 return val; ··· 38 38 static inline void 39 39 writeRegister(const unsigned int nReg, const unsigned long val) 40 40 { 41 - unsigned long *userRegisters = GET_USERREG(); 42 - userRegisters[nReg] = val; 41 + struct pt_regs *regs = GET_USERREG(); 42 + regs->uregs[nReg] = val; 43 43 } 44 44 45 45 static inline unsigned long readCPSR(void) ··· 63 63 64 64 static inline void writeConditionCodes(const unsigned long val) 65 65 { 66 - unsigned long *userRegisters = GET_USERREG(); 66 + struct pt_regs *regs = GET_USERREG(); 67 67 unsigned long rval; 68 68 /* 69 69 * Operate directly on userRegisters since 70 70 * the CPSR may be the PC register itself. 71 71 */ 72 - rval = userRegisters[REG_CPSR] & ~CC_MASK; 73 - userRegisters[REG_CPSR] = rval | (val & CC_MASK); 72 + rval = regs->ARM_cpsr & ~CC_MASK; 73 + regs->ARM_cpsr = rval | (val & CC_MASK); 74 74 }