summary refs log tree commit diff
path: root/arch/xtensa/kernel/signal.c
diff options
context:
space:
mode:
authorChris Zankel <chris@zankel.net>2013-02-23 19:35:57 -0800
committerChris Zankel <chris@zankel.net>2013-02-23 19:35:57 -0800
commitc50842df47970eab459f13490c152aac85fc02f2 (patch)
treed2933b4d9641067002ba6d662b0abf6ee3011375 /arch/xtensa/kernel/signal.c
parentb0c438e642699f8c47b84de957f30cf586cdbebd (diff)
downloadlinux-c50842df47970eab459f13490c152aac85fc02f2.tar.gz
xtensa: add support for TLS
The Xtensa architecture provides a global register called THREADPTR
for the purpose of Thread Local Storage (TLS) support. This allows us
to use a fairly simple implementation, keeping the thread pointer in
the regset and simply saving and restoring it upon entering/exiting
the from user space.

Signed-off-by: Chris Zankel <chris@zankel.net>
Diffstat (limited to 'arch/xtensa/kernel/signal.c')
-rw-r--r--arch/xtensa/kernel/signal.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index de34d6be91cd..6952d8959236 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -337,7 +337,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	struct rt_sigframe *frame;
 	int err = 0;
 	int signal;
-	unsigned long sp, ra;
+	unsigned long sp, ra, tp;
 
 	sp = regs->areg[1];
 
@@ -395,7 +395,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	 * Return context not modified until this point.
 	 */
 
-	/* Set up registers for signal handler */
+	/* Set up registers for signal handler; preserve the threadptr */
+	tp = regs->threadptr;
 	start_thread(regs, (unsigned long) ka->sa.sa_handler,
 		     (unsigned long) frame);
 
@@ -406,6 +407,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	regs->areg[6] = (unsigned long) signal;
 	regs->areg[7] = (unsigned long) &frame->info;
 	regs->areg[8] = (unsigned long) &frame->uc;
+	regs->threadptr = tp;
 
 	/* Set access mode to USER_DS.  Nomenclature is outdated, but
 	 * functionality is used in uaccess.h