aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/xtensa/kernel')
-rw-r--r--arch/xtensa/kernel/asm-offsets.c1
-rw-r--r--arch/xtensa/kernel/entry.S12
-rw-r--r--arch/xtensa/kernel/process.c5
-rw-r--r--arch/xtensa/kernel/ptrace.c2
-rw-r--r--arch/xtensa/kernel/signal.c6
5 files changed, 21 insertions, 5 deletions
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c
index 0701fad170db..1915c7c889ba 100644
--- a/arch/xtensa/kernel/asm-offsets.c
+++ b/arch/xtensa/kernel/asm-offsets.c
@@ -42,6 +42,7 @@ int main(void)
42 DEFINE(PT_ICOUNTLEVEL, offsetof (struct pt_regs, icountlevel)); 42 DEFINE(PT_ICOUNTLEVEL, offsetof (struct pt_regs, icountlevel));
43 DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall)); 43 DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall));
44 DEFINE(PT_SCOMPARE1, offsetof(struct pt_regs, scompare1)); 44 DEFINE(PT_SCOMPARE1, offsetof(struct pt_regs, scompare1));
45 DEFINE(PT_THREADPTR, offsetof(struct pt_regs, threadptr));
45 DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0])); 46 DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0]));
46 DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0])); 47 DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0]));
47 DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1])); 48 DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1]));
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 70d5a9e33573..63845f950792 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -130,6 +130,11 @@ _user_exception:
130 s32i a3, a1, PT_SAR 130 s32i a3, a1, PT_SAR
131 s32i a2, a1, PT_ICOUNTLEVEL 131 s32i a2, a1, PT_ICOUNTLEVEL
132 132
133#if XCHAL_HAVE_THREADPTR
134 rur a2, threadptr
135 s32i a2, a1, PT_THREADPTR
136#endif
137
133 /* Rotate ws so that the current windowbase is at bit0. */ 138 /* Rotate ws so that the current windowbase is at bit0. */
134 /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */ 139 /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */
135 140
@@ -510,6 +515,11 @@ user_exception_exit:
510 * (if we have restored WSBITS-1 frames). 515 * (if we have restored WSBITS-1 frames).
511 */ 516 */
512 517
518#if XCHAL_HAVE_THREADPTR
519 l32i a3, a1, PT_THREADPTR
520 wur a3, threadptr
521#endif
522
5132: j common_exception_exit 5232: j common_exception_exit
514 524
515 /* This is the kernel exception exit. 525 /* This is the kernel exception exit.
@@ -1955,7 +1965,7 @@ ENTRY(_switch_to)
1955 s32i a6, a3, EXC_TABLE_FIXUP 1965 s32i a6, a3, EXC_TABLE_FIXUP
1956 s32i a7, a3, EXC_TABLE_KSTK 1966 s32i a7, a3, EXC_TABLE_KSTK
1957 1967
1958 /* restore context of the task that 'next' addresses */ 1968 /* restore context of the task 'next' */
1959 1969
1960 l32i a0, a13, THREAD_RA # restore return address 1970 l32i a0, a13, THREAD_RA # restore return address
1961 l32i a1, a13, THREAD_SP # restore stack pointer 1971 l32i a1, a13, THREAD_SP # restore stack pointer
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 0dd5784416d3..5cd82e9f601c 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -259,9 +259,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn,
259 memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], 259 memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4],
260 &regs->areg[XCHAL_NUM_AREGS - len/4], len); 260 &regs->areg[XCHAL_NUM_AREGS - len/4], len);
261 } 261 }
262// FIXME: we need to set THREADPTR in thread_info... 262
263 /* The thread pointer is passed in the '4th argument' (= a5) */
263 if (clone_flags & CLONE_SETTLS) 264 if (clone_flags & CLONE_SETTLS)
264 childregs->areg[2] = childregs->areg[6]; 265 childregs->threadptr = childregs->areg[5];
265 } else { 266 } else {
266 p->thread.ra = MAKE_RA_FOR_CALL( 267 p->thread.ra = MAKE_RA_FOR_CALL(
267 (unsigned long)ret_from_kernel_thread, 1); 268 (unsigned long)ret_from_kernel_thread, 1);
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index a8b0d5795571..562fac664751 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -66,6 +66,7 @@ int ptrace_getregs(struct task_struct *child, void __user *uregs)
66 __put_user(regs->lcount, &gregset->lcount); 66 __put_user(regs->lcount, &gregset->lcount);
67 __put_user(regs->windowstart, &gregset->windowstart); 67 __put_user(regs->windowstart, &gregset->windowstart);
68 __put_user(regs->windowbase, &gregset->windowbase); 68 __put_user(regs->windowbase, &gregset->windowbase);
69 __put_user(regs->threadptr, &gregset->threadptr);
69 70
70 for (i = 0; i < XCHAL_NUM_AREGS; i++) 71 for (i = 0; i < XCHAL_NUM_AREGS; i++)
71 __put_user(regs->areg[i], 72 __put_user(regs->areg[i],
@@ -92,6 +93,7 @@ int ptrace_setregs(struct task_struct *child, void __user *uregs)
92 __get_user(regs->lcount, &gregset->lcount); 93 __get_user(regs->lcount, &gregset->lcount);
93 __get_user(ws, &gregset->windowstart); 94 __get_user(ws, &gregset->windowstart);
94 __get_user(wb, &gregset->windowbase); 95 __get_user(wb, &gregset->windowbase);
96 __get_user(regs->threadptr, &gregset->threadptr);
95 97
96 regs->ps = (regs->ps & ~ps_mask) | (ps & ps_mask) | (1 << PS_EXCM_BIT); 98 regs->ps = (regs->ps & ~ps_mask) | (ps & ps_mask) | (1 << PS_EXCM_BIT);
97 99
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,
337 struct rt_sigframe *frame; 337 struct rt_sigframe *frame;
338 int err = 0; 338 int err = 0;
339 int signal; 339 int signal;
340 unsigned long sp, ra; 340 unsigned long sp, ra, tp;
341 341
342 sp = regs->areg[1]; 342 sp = regs->areg[1];
343 343
@@ -395,7 +395,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
395 * Return context not modified until this point. 395 * Return context not modified until this point.
396 */ 396 */
397 397
398 /* Set up registers for signal handler */ 398 /* Set up registers for signal handler; preserve the threadptr */
399 tp = regs->threadptr;
399 start_thread(regs, (unsigned long) ka->sa.sa_handler, 400 start_thread(regs, (unsigned long) ka->sa.sa_handler,
400 (unsigned long) frame); 401 (unsigned long) frame);
401 402
@@ -406,6 +407,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
406 regs->areg[6] = (unsigned long) signal; 407 regs->areg[6] = (unsigned long) signal;
407 regs->areg[7] = (unsigned long) &frame->info; 408 regs->areg[7] = (unsigned long) &frame->info;
408 regs->areg[8] = (unsigned long) &frame->uc; 409 regs->areg[8] = (unsigned long) &frame->uc;
410 regs->threadptr = tp;
409 411
410 /* Set access mode to USER_DS. Nomenclature is outdated, but 412 /* Set access mode to USER_DS. Nomenclature is outdated, but
411 * functionality is used in uaccess.h 413 * functionality is used in uaccess.h