Commit e7e9614b authored by Max Filippov's avatar Max Filippov
Browse files

xtensa: clean up kernel exit assembly code



Don't use numeric labels for complex branching logic. Mark each branch
with named local label and use them. Rearrange exit back to kernel mode
to avoid conditional label definition.

Signed-off-by: default avatarMax Filippov <jcmvbkbc@gmail.com>
parent e6d423aa
Loading
Loading
Loading
Loading
+25 −25
Original line number Diff line number Diff line
@@ -491,9 +491,9 @@ common_exception_return:
	l32i	abi_tmp0, a1, PT_EXCCAUSE
	movi	abi_tmp1, EXCCAUSE_MAPPED_NMI
	l32i	abi_saved1, a1, PT_PS
	beq	abi_tmp0, abi_tmp1, 4f
	beq	abi_tmp0, abi_tmp1, .Lrestore_state
#endif
1:
.Ltif_loop:
	irq_save a2, a3
#ifdef CONFIG_TRACE_IRQFLAGS
	abi_call	trace_hardirqs_off
@@ -504,7 +504,7 @@ common_exception_return:
	l32i	abi_saved1, a1, PT_PS
	GET_THREAD_INFO(a2, a1)
	l32i	a4, a2, TI_FLAGS
	_bbci.l	abi_saved1, PS_UM_BIT, 6f
	_bbci.l	abi_saved1, PS_UM_BIT, .Lexit_tif_loop_kernel

	/* Specific to a user exception exit:
	 * We need to check some flags for signal handling and rescheduling,
@@ -513,12 +513,12 @@ common_exception_return:
	 * Note that we don't disable interrupts here. 
	 */

	_bbsi.l	a4, TIF_NEED_RESCHED, 3f
	_bbsi.l	a4, TIF_NEED_RESCHED, .Lresched
	movi	a2, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL
	bnone	a4, a2, 5f
	bnone	a4, a2, .Lexit_tif_loop_user

2:	l32i	a4, a1, PT_DEPC
	bgeui	a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
	l32i	a4, a1, PT_DEPC
	bgeui	a4, VALID_DOUBLE_EXCEPTION_ADDRESS, .Lrestore_state

	/* Call do_signal() */

@@ -528,42 +528,41 @@ common_exception_return:
	rsil	a2, 0
	mov	abi_arg0, a1
	abi_call	do_notify_resume	# int do_notify_resume(struct pt_regs*)
	j	1b

3:	/* Reschedule */
	j	.Ltif_loop

.Lresched:
#ifdef CONFIG_TRACE_IRQFLAGS
	abi_call	trace_hardirqs_on
#endif
	rsil	a2, 0
	abi_call	schedule	# void schedule (void)
	j	1b
	j	.Ltif_loop

.Lexit_tif_loop_kernel:
#ifdef CONFIG_PREEMPTION
6:
	_bbci.l	a4, TIF_NEED_RESCHED, 4f
	_bbci.l	a4, TIF_NEED_RESCHED, .Lrestore_state

	/* Check current_thread_info->preempt_count */

	l32i	a4, a2, TI_PRE_COUNT
	bnez	a4, 4f
	bnez	a4, .Lrestore_state
	abi_call	preempt_schedule_irq
	j	4f
#endif
	j	.Lrestore_state

5:
.Lexit_tif_loop_user:
#ifdef CONFIG_HAVE_HW_BREAKPOINT
	_bbci.l	a4, TIF_DB_DISABLED, 7f
	_bbci.l	a4, TIF_DB_DISABLED, 1f
	abi_call	restore_dbreak
7:
1:
#endif
#ifdef CONFIG_DEBUG_TLB_SANITY
	l32i	a4, a1, PT_DEPC
	bgeui	a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
	bgeui	a4, VALID_DOUBLE_EXCEPTION_ADDRESS, .Lrestore_state
	abi_call	check_tlb_sanity
#endif
6:
4:

.Lrestore_state:
#ifdef CONFIG_TRACE_IRQFLAGS
	extui	a4, abi_saved1, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH
	bgei	a4, LOCKLEVEL, 1f
@@ -601,7 +600,7 @@ user_exception_exit:
	rsr	a1, depc		# restore stack pointer
	l32i	a2, a1, PT_WMASK	# register frames saved (in bits 4...9)
	rotw	-1			# we restore a4..a7
	_bltui	a6, 16, 1f		# only have to restore current window?
	_bltui	a6, 16, .Lclear_regs	# only have to restore current window?

	/* The working registers are a0 and a3.  We are restoring to
	 * a4..a7.  Be careful not to destroy what we have just restored.
@@ -613,18 +612,19 @@ user_exception_exit:
	mov	a2, a6
	mov	a3, a5

2:	rotw	-1			# a0..a3 become a4..a7
1:	rotw	-1			# a0..a3 become a4..a7
	addi	a3, a7, -4*4		# next iteration
	addi	a2, a6, -16		# decrementing Y in WMASK
	l32i	a4, a3, PT_AREG_END + 0
	l32i	a5, a3, PT_AREG_END + 4
	l32i	a6, a3, PT_AREG_END + 8
	l32i	a7, a3, PT_AREG_END + 12
	_bgeui	a2, 16, 2b
	_bgeui	a2, 16, 1b

	/* Clear unrestored registers (don't leak anything to user-land */

1:	rsr	a0, windowbase
.Lclear_regs:
	rsr	a0, windowbase
	rsr	a3, sar
	sub	a3, a0, a3
	beqz	a3, 2f