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: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
Max Filippov 2022-03-19 05:52:07 -07:00
parent e6d423aaae
commit e7e9614b6b

View file

@ -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