From: Max Filippov <jcmvbkbc@gmail.com>
To: linux-xtensa@linux-xtensa.org, linux-kernel@vger.kernel.org
Cc: Chris Zankel <chris@zankel.net>, Marc Gauthier <marc@cadence.com>,
Max Filippov <jcmvbkbc@gmail.com>
Subject: [PATCH v2 02/13] xtensa: keep exception/interrupt stack continuous
Date: Sat, 18 Jul 2015 11:30:05 +0300 [thread overview]
Message-ID: <1437208216-15729-3-git-send-email-jcmvbkbc@gmail.com> (raw)
In-Reply-To: <1437208216-15729-1-git-send-email-jcmvbkbc@gmail.com>
Restore original a0 in the kernel exception stack frame. This way it
looks like the frame that got interrupt/exception did alloca (copy a0 and
a1 potentially spilled under old stack to the new location as well) to
save registers and then did a call to handler. The point where
interrupt/exception was taken is not in the stack chain, only in pt_regs
(call4 from that address can be simulated to keep it in the stack trace).
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Changes v1->v2:
- make continuous stack changes conditional;
- replace l32i/s32i + add used to access spilled registers with l32e/s32e.
arch/xtensa/kernel/entry.S | 59 ++++++++++++++++++++++++++++++++++------------
1 file changed, 44 insertions(+), 15 deletions(-)
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 82bbfa5..b64075f 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -28,6 +28,10 @@
#include <asm/tlbflush.h>
#include <variant/tie-asm.h>
+#if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_STACKTRACE_SUPPORT)
+#define XTENSA_CONTINUOUS_STACK
+#endif
+
/* Unimplemented features. */
#undef KERNEL_STACK_OVERFLOW_CHECK
@@ -219,6 +223,10 @@ _user_exception:
2: /* Now, jump to the common exception handler. */
+#ifdef XTENSA_CONTINUOUS_STACK
+ movi a0, 0 # terminate user stack trace with 0
+ wsr a0, depc
+#endif
j common_exception
ENDPROC(user_exception)
@@ -264,6 +272,24 @@ ENTRY(kernel_exception)
.globl _kernel_exception
_kernel_exception:
+ /* Copy spill slots of a0 and a1 to imitate movsp
+ * in order to keep exception stack continuous
+ */
+#ifdef XTENSA_CONTINUOUS_STACK
+ /* Reload previous stack pointer: l32e relative to the current stack
+ * won't reach it, because kernel exception stack frame is definitely
+ * larger than l32e range (64 bytes).
+ */
+ l32i a0, a1, PT_AREG1
+ l32e a3, a0, -16
+ l32e a0, a0, -12
+ s32e a3, a1, -16
+ s32e a0, a1, -12
+
+ l32i a0, a1, PT_AREG0 # restore saved a0
+ wsr a0, depc
+#endif
+
/* Save SAR and turn off single stepping */
movi a2, 0
@@ -346,12 +372,12 @@ common_exception:
s32i a0, a1, PT_EXCCAUSE
s32i a3, a2, EXC_TABLE_FIXUP
- /* All unrecoverable states are saved on stack, now, and a1 is valid,
- * so we can allow exceptions and interrupts (*) again.
- * Set PS(EXCM = 0, UM = 0, RING = 0, OWB = 0, WOE = 1, INTLEVEL = X)
+ /* All unrecoverable states are saved on stack, now, and a1 is valid.
+ * Now we can allow exceptions again. In case we've got an interrupt
+ * PS.INTLEVEL is set to LOCKLEVEL disabling furhter interrupts,
+ * otherwise it's left unchanged.
*
- * (*) We only allow interrupts if they were previously enabled and
- * we're not handling an IRQ
+ * Set PS(EXCM = 0, UM = 0, RING = 0, OWB = 0, WOE = 1, INTLEVEL = X)
*/
rsr a3, ps
@@ -362,28 +388,32 @@ common_exception:
moveqz a3, a2, a0 # a3 = LOCKLEVEL iff interrupt
movi a2, 1 << PS_WOE_BIT
or a3, a3, a2
- rsr a0, exccause
+ rsr a2, exccause
+#ifdef XTENSA_CONTINUOUS_STACK
+ /* restore return address (or 0 if return to userspace) */
+ rsr a0, depc
+#endif
xsr a3, ps
s32i a3, a1, PT_PS # save ps
/* Save lbeg, lend */
- rsr a2, lbeg
+ rsr a4, lbeg
rsr a3, lend
- s32i a2, a1, PT_LBEG
+ s32i a4, a1, PT_LBEG
s32i a3, a1, PT_LEND
/* Save SCOMPARE1 */
#if XCHAL_HAVE_S32C1I
- rsr a2, scompare1
- s32i a2, a1, PT_SCOMPARE1
+ rsr a3, scompare1
+ s32i a3, a1, PT_SCOMPARE1
#endif
/* Save optional registers. */
- save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
+ save_xtregs_opt a1 a3 a4 a5 a6 a7 PT_XTREGS_OPT
#ifdef CONFIG_TRACE_IRQFLAGS
l32i a4, a1, PT_DEPC
@@ -391,8 +421,7 @@ common_exception:
* while PS.EXCM was set, i.e. interrupts disabled.
*/
bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
- l32i a4, a1, PT_EXCCAUSE
- bnei a4, EXCCAUSE_LEVEL1_INTERRUPT, 1f
+ bnei a2, EXCCAUSE_LEVEL1_INTERRUPT, 1f
/* We came here with an interrupt means interrupts were enabled
* and we've just disabled them.
*/
@@ -407,8 +436,8 @@ common_exception:
rsr a4, excsave1
mov a6, a1 # pass stack frame
- mov a7, a0 # pass EXCCAUSE
- addx4 a4, a0, a4
+ mov a7, a2 # pass EXCCAUSE
+ addx4 a4, a2, a4
l32i a4, a4, EXC_TABLE_DEFAULT # load handler
/* Call the second-level handler */
--
1.8.1.4
next prev parent reply other threads:[~2015-07-18 8:30 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-18 8:30 [PATCH v2 00/13] Support hardware perf counters on xtensa Max Filippov
2015-07-18 8:30 ` [PATCH v2 01/13] xtensa: clean up Kconfig dependencies for custom cores Max Filippov
2015-07-18 8:30 ` Max Filippov [this message]
2015-07-18 8:30 ` [PATCH v2 03/13] xtensa: move oprofile stack tracing to stacktrace.c Max Filippov
2015-07-18 8:30 ` [PATCH v2 04/13] xtensa: select PERF_USE_VMALLOC for cache-aliasing configurations Max Filippov
2015-07-18 8:30 ` [PATCH v2 05/13] xtensa: add profiling IRQ type to xtensa_irq_map Max Filippov
2015-07-18 8:30 ` [PATCH v2 06/13] xtensa: count software page fault perf events Max Filippov
2015-07-18 8:30 ` [PATCH v2 07/13] xtensa: implement counting and sampling " Max Filippov
2015-08-06 19:46 ` Arnaldo Carvalho de Melo
2015-08-07 9:13 ` Peter Zijlstra
2015-08-07 12:03 ` Max Filippov
2015-08-07 13:12 ` Arnaldo Carvalho de Melo
2015-07-18 8:30 ` [PATCH v2 08/13] perf tools: xtensa: add DWARF register names Max Filippov
2015-08-07 7:22 ` [tip:perf/core] perf tools xtensa: Add " tip-bot for Max Filippov
2015-07-18 8:30 ` [PATCH v2 09/13] xtensa: reorganize irq flags tracing Max Filippov
2015-07-18 8:30 ` [PATCH v2 10/13] xtensa: fix kernel register spilling Max Filippov
2015-07-18 8:30 ` [PATCH v2 11/13] xtensa: don't touch EXC_TABLE_FIXUP in _switch_to Max Filippov
2015-07-18 8:30 ` [PATCH v2 12/13] xtensa: implement fake NMI Max Filippov
2015-07-27 14:36 ` Max Filippov
2015-07-27 15:14 ` Peter Zijlstra
2015-07-18 8:30 ` [PATCH v2 13/13] xtensa: drop unused irq_err_count Max Filippov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1437208216-15729-3-git-send-email-jcmvbkbc@gmail.com \
--to=jcmvbkbc@gmail.com \
--cc=chris@zankel.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-xtensa@linux-xtensa.org \
--cc=marc@cadence.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox