xtensa: userspace: calculate PC earlier at syscall entry
This moves the calculation of the return PC earlier in syscall entry. There is no need to stash it into BSA, load it, do the calculation and save it back. We can do the calculation first and save it in BSA at the same time. Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
parent
1203ed05d9
commit
d725f37d5e
1 changed files with 32 additions and 25 deletions
|
@ -74,8 +74,38 @@ _not_checking_user_context:
|
|||
movi a3, ~PS_OWB_MASK
|
||||
and a2, a2, a3
|
||||
s32i a2, a0, ___xtensa_irq_bsa_t_ps_OFFSET
|
||||
rsr.epc1 a2
|
||||
s32i a2, a0, ___xtensa_irq_bsa_t_pc_OFFSET
|
||||
|
||||
/* Manipulate PC where we will return to after syscall.
|
||||
* This is needed as syscall will stash the PC where
|
||||
* the syscall instruction locates, instead of
|
||||
* the instruction after it.
|
||||
*/
|
||||
rsr.epc1 a3
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
/* If the syscall instruction was the last instruction in the body of
|
||||
* a zero-overhead loop, and the loop will execute again, decrement
|
||||
* the loop count and resume execution at the head of the loop.
|
||||
*/
|
||||
rsr.lend a2
|
||||
addi a3, a3, 3
|
||||
bne a2, a3, end_loop
|
||||
rsr.lcount a2
|
||||
beqz a2, end_loop
|
||||
addi a2, a2, -1
|
||||
wsr.lcount a2
|
||||
rsr.lbeg a3
|
||||
|
||||
/* Make sure WSR above is synced before RSR in ODD_REG_SAVE. */
|
||||
isync
|
||||
end_loop:
|
||||
#else
|
||||
/* EPC1 (and now a3) contains the address that invoked syscall.
|
||||
* We need to increment it to execute the next instruction when
|
||||
* we return. The instruction size is 3 bytes, so lets just add it.
|
||||
*/
|
||||
addi a3, a3, 3
|
||||
#endif
|
||||
s32i a3, a0, ___xtensa_irq_bsa_t_pc_OFFSET
|
||||
|
||||
/* Need to setup PS so we can spill all registers.
|
||||
* EXCM and RING bits need to be cleared as CPU
|
||||
|
@ -98,29 +128,6 @@ _not_checking_user_context:
|
|||
|
||||
mov a1, a0
|
||||
|
||||
l32i a3, a1, ___xtensa_irq_bsa_t_pc_OFFSET
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
/* If the syscall instruction was the last instruction in the body of
|
||||
* a zero-overhead loop, and the loop will execute again, decrement
|
||||
* the loop count and resume execution at the head of the loop.
|
||||
*/
|
||||
rsr.lend a2
|
||||
addi a3, a3, 3
|
||||
bne a2, a3, end_loop
|
||||
rsr.lcount a2
|
||||
beqz a2, end_loop
|
||||
addi a2, a2, -1
|
||||
wsr.lcount a2
|
||||
rsr.lbeg a3
|
||||
end_loop:
|
||||
#else
|
||||
/* EPC1 (and now a3) contains the address that invoked syscall.
|
||||
* We need to increment it to execute the next instruction when
|
||||
* we return. The instruction size is 3 bytes, so lets just add it.
|
||||
*/
|
||||
addi a3, a3, 3
|
||||
#endif
|
||||
s32i a3, a1, ___xtensa_irq_bsa_t_pc_OFFSET
|
||||
ODD_REG_SAVE a0, a1
|
||||
|
||||
call0 xtensa_save_high_regs
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue