-
Nicolas Pitre authored
Patch from Nicolas Pitre This implements TLS support in the most efficient way for all ARM processors in use today. The trick is to define a specific address in kernel area that is made readable from user space to hold the TLS pointer so it is highly efficient to retrieve it with no overhead. Since the kernel already maps a page at 0xffff0000 to hold the exception vectors, we can use the top of that page for storing the TLS ptr at 0xffff0ffc. This address has the advantage of fitting optimally with the ARM load addressing mode as follows: mov rd, #0xffff0fff ldr rd, [rd, #-3] Considering load scheduling, this means 2 cycles to retrieve the TLS value which is even faster than a coprocessor access. Even gcc generates the above assembly when given: void *tls = *((void **)0xffff0ffc); This is fine to make the vector page readable from user space since it contains nothing that could compromize security and doesn't require an extra memory page to be allocated. On SMP (which should be ARMv6 and above only) the special reg for TLS will be available. Since ARMv6 binaries are most likely to use strex/ldrex insns instead of swp to implement user space atomic primitives, those ARMv6 binaries won't execute on pre ARMv6 processors anyway. So the abscence of a tls reg is a non issue for them already. Also on SMP targets, since the hivec page can't be relied upon to get the TLS value, we'll have the kernel emulate access to it through the data abort vector for backward compatibility with pre ARMv6 binaries. Otherwise, non SMP ARMv6 kernels will support both methods simultaneously. So the decision to use hivec or tlsreg could depend on whether given library is optimized for ARMv6+ or not. And since ARM SMP devices are still far from becoming mainstream we can safely go with the hivec (and hivec emulation on SMP) for the time being. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King
f5e58aa1