summaryrefslogtreecommitdiff
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)
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