summaryrefslogtreecommitdiff
path: root/arch/xtensa/kernel/process.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-11-06 14:54:03 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2021-11-06 14:54:03 -0700
commit00f178e15095fbcf04db00486378a6fa416a125e (patch)
treea66dd51d66f2737abac8a14eae2ce8a78828aa2c /arch/xtensa/kernel/process.c
parent0b707e572a1955b892dfcb32e7b573fab78767d9 (diff)
parentbd47cdb78997f83bd170c389ef59de9eec65976a (diff)
downloadlinux-00f178e15095fbcf04db00486378a6fa416a125e.tar.gz
linux-00f178e15095fbcf04db00486378a6fa416a125e.tar.bz2
linux-00f178e15095fbcf04db00486378a6fa416a125e.zip
Merge tag 'xtensa-20211105' of git://github.com/jcmvbkbc/linux-xtensa
Pull xtensa updates from Max Filippov: - add support for xtensa cores without windowed registers option * tag 'xtensa-20211105' of git://github.com/jcmvbkbc/linux-xtensa: xtensa: move section symbols to asm/sections.h xtensa: remove unused variable wmask xtensa: only build windowed register support code when needed xtensa: use register window specific opcodes only when present xtensa: implement call0 ABI support in assembly xtensa: definitions for call0 ABI xtensa: don't use a12 in __xtensa_copy_user in call0 ABI xtensa: don't use a12 in strncpy_user xtensa: use a14 instead of a15 in inline assembly xtensa: move _SimulateUserKernelVectorException out of WindowVectors
Diffstat (limited to 'arch/xtensa/kernel/process.c')
-rw-r--r--arch/xtensa/kernel/process.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 47f933fed870..bd80df890b1e 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -211,11 +211,18 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn,
struct thread_info *ti;
#endif
+#if defined(__XTENSA_WINDOWED_ABI__)
/* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */
SPILL_SLOT(childregs, 1) = (unsigned long)childregs;
SPILL_SLOT(childregs, 0) = 0;
p->thread.sp = (unsigned long)childregs;
+#elif defined(__XTENSA_CALL0_ABI__)
+ /* Reserve 16 bytes for the _switch_to stack frame. */
+ p->thread.sp = (unsigned long)childregs - 16;
+#else
+#error Unsupported Xtensa ABI
+#endif
if (!(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
struct pt_regs *regs = current_pt_regs();
@@ -272,11 +279,25 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn,
p->thread.ra = MAKE_RA_FOR_CALL(
(unsigned long)ret_from_kernel_thread, 1);
- /* pass parameters to ret_from_kernel_thread:
- * a2 = thread_fn, a3 = thread_fn arg
+ /* pass parameters to ret_from_kernel_thread: */
+#if defined(__XTENSA_WINDOWED_ABI__)
+ /*
+ * a2 = thread_fn, a3 = thread_fn arg.
+ * Window underflow will load registers from the
+ * spill slots on the stack on return from _switch_to.
*/
- SPILL_SLOT(childregs, 3) = thread_fn_arg;
SPILL_SLOT(childregs, 2) = usp_thread_fn;
+ SPILL_SLOT(childregs, 3) = thread_fn_arg;
+#elif defined(__XTENSA_CALL0_ABI__)
+ /*
+ * a12 = thread_fn, a13 = thread_fn arg.
+ * _switch_to epilogue will load registers from the stack.
+ */
+ ((unsigned long *)p->thread.sp)[0] = usp_thread_fn;
+ ((unsigned long *)p->thread.sp)[1] = thread_fn_arg;
+#else
+#error Unsupported Xtensa ABI
+#endif
/* Childregs are only used when we're going to userspace
* in which case start_thread will set them up.