blob: ed98400e051257be7d5b597e1e15daa88b071048 [file] [log] [blame]
From 3251f1e27a5a17f0efd436cfd1e7b9896cfab0a0 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
Date: Wed, 30 Oct 2013 16:18:25 +0400
Subject: xtensa: save current register frame in fast_syscall_spill_registers_fixup
From: Max Filippov <jcmvbkbc@gmail.com>
commit 3251f1e27a5a17f0efd436cfd1e7b9896cfab0a0 upstream.
We need it saved because it contains a3 where we track which register
windows we still need to spill, and fixup handler may call C exception
handlers. Also fix comments.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/xtensa/kernel/entry.S | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -1117,6 +1117,13 @@ ENDPROC(fast_syscall_spill_registers)
* We basically restore WINDOWBASE and WINDOWSTART to the condition when
* we entered the spill routine and jump to the user exception handler.
*
+ * Note that we only need to restore the bits in windowstart that have not
+ * been spilled yet by the _spill_register routine. Luckily, a3 contains a
+ * rotated windowstart with only those bits set for frames that haven't been
+ * spilled yet. Because a3 is rotated such that bit 0 represents the register
+ * frame for the current windowbase - 1, we need to rotate a3 left by the
+ * value of the current windowbase + 1 and move it to windowstart.
+ *
* a0: value of depc, original value in depc
* a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE
* a3: exctable, original value in excsave1
@@ -1131,10 +1138,15 @@ ENTRY(fast_syscall_spill_registers_fixup
/* We need to make sure the current registers (a0-a3) are preserved.
* To do this, we simply set the bit for the current window frame
* in WS, so that the exception handlers save them to the task stack.
+ *
+ * Note: we use a3 to set the windowbase, so we take a special care
+ * of it, saving it in the original _spill_registers frame across
+ * the exception handler call.
*/
xsr a3, excsave1 # get spill-mask
slli a3, a3, 1 # shift left by one
+ addi a3, a3, 1 # set the bit for the current window frame
slli a2, a3, 32-WSBITS
src a2, a3, a2 # a2 = xxwww1yyxxxwww1yy......