public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
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 2/8] xtensa: keep exception/interrupt stack continuous
Date: Mon,  6 Jul 2015 16:32:43 +0300	[thread overview]
Message-ID: <1436189569-28802-3-git-send-email-jcmvbkbc@gmail.com> (raw)
In-Reply-To: <1436189569-28802-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>
---
 arch/xtensa/kernel/entry.S | 60 +++++++++++++++++++++++++++-------------------
 1 file changed, 35 insertions(+), 25 deletions(-)

diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 82bbfa5..ab6a857 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -218,7 +218,7 @@ _user_exception:
 	/* We are back to the original stack pointer (a1) */
 
 2:	/* Now, jump to the common exception handler. */
-
+	movi	a0, 0			# terminate user stack trace with 0
 	j	common_exception
 
 ENDPROC(user_exception)
@@ -264,6 +264,19 @@ 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
+	 */
+	l32i	a0, a1, PT_AREG1
+	addi	a2, a1, -16
+	addi	a0, a0, -16
+	l32i	a3, a0, 0
+	l32i	a0, a0, 4
+	s32i	a3, a2, 0
+	s32i	a0, a2, 4
+
+	l32i	a0, a1, PT_AREG0	# restore saved a0
+
 	/* Save SAR and turn off single stepping */
 
 	movi	a2, 0
@@ -338,52 +351,50 @@ common_exception:
 	xsr	a2, lcount
 	s32i	a2, a1, PT_LCOUNT
 
-	/* It is now save to restore the EXC_TABLE_FIXUP variable. */
+	/* It is now safe to restore the EXC_TABLE_FIXUP variable. */
 
-	rsr	a0, exccause
 	movi	a3, 0
 	rsr	a2, excsave1
-	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)
+	/* Save remaining unrecoverable states (exccause, ps) on stack.
+	 * 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
-	addi	a0, a0, -EXCCAUSE_LEVEL1_INTERRUPT
-	movi	a2, LOCKLEVEL
+	movi	a2, (1 << PS_WOE_BIT)
 	extui	a3, a3, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH
-					# a3 = PS.INTLEVEL
-	moveqz	a3, a2, a0		# a3 = LOCKLEVEL iff interrupt
-	movi	a2, 1 << PS_WOE_BIT
 	or	a3, a3, a2
-	rsr	a0, exccause
-	xsr	a3, ps
 
+	rsr	a2, exccause
+	bnei	a2, EXCCAUSE_LEVEL1_INTERRUPT, 1f
+	movi	a3, (1 << PS_WOE_BIT) | LOCKLEVEL
+1:
+	xsr	a3, ps
+	s32i	a2, a1, PT_EXCCAUSE
 	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 +402,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 +417,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


  parent reply	other threads:[~2015-07-06 13:35 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-06 13:32 [PATCH 0/8] Support hardware perf counters on xtensa Max Filippov
2015-07-06 13:32 ` [PATCH 1/8] xtensa: clean up Kconfig dependencies for custom cores Max Filippov
2015-07-07  9:18   ` Paul Bolle
2015-07-06 13:32 ` Max Filippov [this message]
2015-07-07 18:47   ` [PATCH 2/8] xtensa: keep exception/interrupt stack continuous Chris Zankel
2015-07-07 19:46     ` Max Filippov
2015-07-07 19:47       ` Max Filippov
2015-07-06 13:32 ` [PATCH 3/8] xtensa: move oprofile stack tracing to stacktrace.c Max Filippov
2015-07-06 13:32 ` [PATCH 4/8] xtensa: select PERF_USE_VMALLOC for cache-aliasing configurations Max Filippov
2015-07-06 13:32 ` [PATCH 5/8] xtensa: add profiling IRQ type to xtensa_irq_map Max Filippov
2015-07-06 13:32 ` [PATCH 6/8] xtensa: count software page fault perf events Max Filippov
2015-07-06 13:32 ` [PATCH 7/8] xtensa: implement counting and sampling " Max Filippov
2015-07-06 13:41   ` Peter Zijlstra
2015-07-06 13:49     ` Max Filippov
2015-07-06 13:47   ` Peter Zijlstra
2015-07-06 13:56     ` Max Filippov
2015-07-06 14:05       ` Peter Zijlstra
2015-07-06 14:22         ` Max Filippov
2015-07-07  3:56           ` Chris Zankel
2015-07-06 13:32 ` [PATCH 8/8] perf tools: xtensa: add DWARF register names 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=1436189569-28802-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