summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid 'Digit' Turner <digit@google.com>2009-09-18 13:35:05 -0700
committerDavid 'Digit' Turner <digit@google.com>2009-09-22 10:03:59 -0700
commit4a05d12cf52a9a40759f11f28543bd75715c8f00 (patch)
tree2d0beafae4775320beea102649b491b05fa50f8e
parent916edf2a3fc60e08a5f29cd322d9f2a04d15cb49 (diff)
downloadbionic-4a05d12cf52a9a40759f11f28543bd75715c8f00.zip
bionic-4a05d12cf52a9a40759f11f28543bd75715c8f00.tar.gz
bionic-4a05d12cf52a9a40759f11f28543bd75715c8f00.tar.bz2
Fix TLS access for ARMv6 and beyond.
For performance reasons, we don't call the kernel helper. Instead, we directly access the TLS register on ARMv6 and higher. For ARMv5TE, keep using the hard-coded address populated by the kernel on each task switch. NOTE: Since we don't call the kernel helper, this must precisely match your kernel configuration. This is controlled by setting the ARCH_ARM_HAVE_TLS_REGISTER variable to 'true' in your board configuration file.
-rw-r--r--libc/Android.mk10
-rw-r--r--libc/arch-arm/include/machine/cpu-features.h1
-rw-r--r--libc/private/bionic_tls.h13
3 files changed, 22 insertions, 2 deletions
diff --git a/libc/Android.mk b/libc/Android.mk
index 59a4c6b..12d5c92 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -366,6 +366,16 @@ endif
ifeq ($(TARGET_ARCH),arm)
libc_common_cflags += -fstrict-aliasing
libc_crt_target_cflags := -mthumb-interwork
+ #
+ # Define HAVE_ARM_TLS_REGISTER macro to indicate to the C library
+ # that it should access the hardware TLS register directly in
+ # private/bionic_tls.h
+ #
+ # The value must match your kernel configuration
+ #
+ ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
+ libc_common_cflags += -DHAVE_ARM_TLS_REGISTER
+ endif
else # !arm
ifeq ($(TARGET_ARCH),x86)
libc_crt_target_cflags := -m32
diff --git a/libc/arch-arm/include/machine/cpu-features.h b/libc/arch-arm/include/machine/cpu-features.h
index f836006..925067e 100644
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ b/libc/arch-arm/include/machine/cpu-features.h
@@ -149,7 +149,6 @@
# define __ARM_HAVE_PC_INTERWORK
#endif
-
/* Assembly-only macros */
/* define a handy PLD(address) macro since the cache preload
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 82c8cd9..2e7a82b 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -88,7 +88,18 @@ extern int __set_tls(void *ptr);
/* get the TLS */
#ifdef __arm__
-# define __get_tls() ( *((volatile void **) 0xffff0ff0) )
+/* For performance reasons, avoid calling the kernel helper
+ * Note that HAVE_ARM_TLS_REGISTER is build-specific
+ * (it must match your kernel configuration)
+ */
+# ifdef HAVE_ARM_TLS_REGISTER
+# define __get_tls() \
+ ({ register unsigned int __val asm("r0"); \
+ asm ("mrc p15, 0, r0, c13, c0, 3" : "=r"(__val) ); \
+ (volatile void*)__val; })
+# else /* !HAVE_ARM_TLS_REGISTER */
+# define __get_tls() ( *((volatile void **) 0xffff0ff0) )
+# endif
#else
extern void* __get_tls( void );
#endif