diff options
| author | Max Filippov <jcmvbkbc@gmail.com> | 2013-10-30 08:18:25 -0400 |
|---|---|---|
| committer | Max Filippov <jcmvbkbc@gmail.com> | 2014-01-25 14:24:38 -0500 |
| commit | 3251f1e27a5a17f0efd436cfd1e7b9896cfab0a0 (patch) | |
| tree | bbc623531e4ef45620b84d37ca5325605b12c2f4 | |
| parent | e2fd1374c705abe4661df3fb6fadb3879c7c1846 (diff) | |
xtensa: save current register frame in fast_syscall_spill_registers_fixup
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.
Cc: stable@vger.kernel.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
| -rw-r--r-- | arch/xtensa/kernel/entry.S | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 0489918e40d2..b61e25146a2f 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
| @@ -1117,6 +1117,13 @@ ENDPROC(fast_syscall_spill_registers) | |||
| 1117 | * We basically restore WINDOWBASE and WINDOWSTART to the condition when | 1117 | * We basically restore WINDOWBASE and WINDOWSTART to the condition when |
| 1118 | * we entered the spill routine and jump to the user exception handler. | 1118 | * we entered the spill routine and jump to the user exception handler. |
| 1119 | * | 1119 | * |
| 1120 | * Note that we only need to restore the bits in windowstart that have not | ||
| 1121 | * been spilled yet by the _spill_register routine. Luckily, a3 contains a | ||
| 1122 | * rotated windowstart with only those bits set for frames that haven't been | ||
| 1123 | * spilled yet. Because a3 is rotated such that bit 0 represents the register | ||
| 1124 | * frame for the current windowbase - 1, we need to rotate a3 left by the | ||
| 1125 | * value of the current windowbase + 1 and move it to windowstart. | ||
| 1126 | * | ||
| 1120 | * a0: value of depc, original value in depc | 1127 | * a0: value of depc, original value in depc |
| 1121 | * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE | 1128 | * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE |
| 1122 | * a3: exctable, original value in excsave1 | 1129 | * a3: exctable, original value in excsave1 |
| @@ -1131,10 +1138,15 @@ ENTRY(fast_syscall_spill_registers_fixup) | |||
| 1131 | /* We need to make sure the current registers (a0-a3) are preserved. | 1138 | /* We need to make sure the current registers (a0-a3) are preserved. |
| 1132 | * To do this, we simply set the bit for the current window frame | 1139 | * To do this, we simply set the bit for the current window frame |
| 1133 | * in WS, so that the exception handlers save them to the task stack. | 1140 | * in WS, so that the exception handlers save them to the task stack. |
| 1141 | * | ||
| 1142 | * Note: we use a3 to set the windowbase, so we take a special care | ||
| 1143 | * of it, saving it in the original _spill_registers frame across | ||
| 1144 | * the exception handler call. | ||
| 1134 | */ | 1145 | */ |
| 1135 | 1146 | ||
| 1136 | xsr a3, excsave1 # get spill-mask | 1147 | xsr a3, excsave1 # get spill-mask |
| 1137 | slli a3, a3, 1 # shift left by one | 1148 | slli a3, a3, 1 # shift left by one |
| 1149 | addi a3, a3, 1 # set the bit for the current window frame | ||
| 1138 | 1150 | ||
| 1139 | slli a2, a3, 32-WSBITS | 1151 | slli a2, a3, 32-WSBITS |
| 1140 | src a2, a3, a2 # a2 = xxwww1yyxxxwww1yy...... | 1152 | src a2, a3, a2 # a2 = xxwww1yyxxxwww1yy...... |
