diff options
Diffstat (limited to 'arch/arm/kernel/traps.c')
| -rw-r--r-- | arch/arm/kernel/traps.c | 41 | 
1 files changed, 30 insertions, 11 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 1621e5327b2..cda78d59aa3 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -30,6 +30,7 @@  #include <asm/unistd.h>  #include <asm/traps.h>  #include <asm/unwind.h> +#include <asm/tls.h>  #include "ptrace.h"  #include "signal.h" @@ -518,17 +519,20 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)  	case NR(set_tls):  		thread->tp_value = regs->ARM_r0; -#if defined(CONFIG_HAS_TLS_REG) -		asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) ); -#elif !defined(CONFIG_TLS_REG_EMUL) -		/* -		 * User space must never try to access this directly. -		 * Expect your app to break eventually if you do so. -		 * The user helper at 0xffff0fe0 must be used instead. -		 * (see entry-armv.S for details) -		 */ -		*((unsigned int *)0xffff0ff0) = regs->ARM_r0; -#endif +		if (tls_emu) +			return 0; +		if (has_tls_reg) { +			asm ("mcr p15, 0, %0, c13, c0, 3" +				: : "r" (regs->ARM_r0)); +		} else { +			/* +			 * User space must never try to access this directly. +			 * Expect your app to break eventually if you do so. +			 * The user helper at 0xffff0fe0 must be used instead. +			 * (see entry-armv.S for details) +			 */ +			*((unsigned int *)0xffff0ff0) = regs->ARM_r0; +		}  		return 0;  #ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG @@ -743,6 +747,16 @@ void __init trap_init(void)  	return;  } +static void __init kuser_get_tls_init(unsigned long vectors) +{ +	/* +	 * vectors + 0xfe0 = __kuser_get_tls +	 * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8 +	 */ +	if (tls_emu || has_tls_reg) +		memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4); +} +  void __init early_trap_init(void)  {  	unsigned long vectors = CONFIG_VECTORS_BASE; @@ -761,6 +775,11 @@ void __init early_trap_init(void)  	memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);  	/* +	 * Do processor specific fixups for the kuser helpers +	 */ +	kuser_get_tls_init(vectors); + +	/*  	 * Copy signal return handlers into the vector page, and  	 * set sigreturn to be a pointer to these.  	 */  |