From: Mikhail Ilyin <m.i...@samsung.com> At present there are two copies of TPIDRURO register for secure and unsecure access. TLS is set via a system call __ARM_NR_set_tls and its handler (cpu_set_tls) always assigns a provided value to unsecure register tpidrro_el[0]/tpidruro_ns. But during execution for cortex-a15 mrc instruction returns TLS from secure rigester tpidruro_s which is 0 and causes SIGSEGV.
Signed-off-by: Mikhail Ilyin <m.i...@samsung.com> --- linux-user/arm/target_cpu.h | 15 ++++++++++++++- linux-user/main.c | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h index d8a534d..6832262 100644 --- a/linux-user/arm/target_cpu.h +++ b/linux-user/arm/target_cpu.h @@ -29,7 +29,20 @@ static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp) static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls) { - env->cp15.tpidrro_el[0] = newtls; + if (access_secure_reg(env)) { + env->cp15.tpidruro_s = newtls; + } else { + env->cp15.tpidrro_el[0] = newtls; + } +} + +static inline target_ulong cpu_get_tls(CPUARMState *env) +{ + if (access_secure_reg(env)) { + return env->cp15.tpidruro_s; + } else { + return env->cp15.tpidrro_el[0]; + } } #endif diff --git a/linux-user/main.c b/linux-user/main.c index 6bd23af..6e446de 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -566,7 +566,7 @@ do_kernel_trap(CPUARMState *env) end_exclusive(); break; case 0xffff0fe0: /* __kernel_get_tls */ - env->regs[0] = env->cp15.tpidrro_el[0]; + env->regs[0] = cpu_get_tls(env); break; case 0xffff0f60: /* __kernel_cmpxchg64 */ arm_kernel_cmpxchg64_helper(env); -- 1.9.1