Skip to content

Commit

Permalink
xtensa: make fast_unaligned store restartable
Browse files Browse the repository at this point in the history
fast_unaligned may encounter DTLB miss or SEGFAULT during the store
emulation. Don't update epc1 and lcount until after the store emulation
is complete, so that the faulting store instruction could be replayed.
Remove duplicate code handling zero overhead loops and calculate new
epc1 and lcount in one place.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
  • Loading branch information
Max Filippov committed Aug 14, 2014
1 parent c3ef1f4 commit e9500dd
Showing 1 changed file with 19 additions and 32 deletions.
51 changes: 19 additions & 32 deletions arch/xtensa/kernel/align.S
Original file line number Diff line number Diff line change
Expand Up @@ -277,18 +277,6 @@ ENTRY(fast_unaligned)
/* Set target register. */

1:

#if XCHAL_HAVE_LOOPS
rsr a5, lend # check if we reached LEND
bne a7, a5, 1f
rsr a5, lcount # and LCOUNT != 0
beqz a5, 1f
addi a5, a5, -1 # decrement LCOUNT and set
rsr a7, lbeg # set PC to LBEGIN
wsr a5, lcount
#endif

1: wsr a7, epc1 # skip load instruction
extui a4, a4, INSN_T, 4 # extract target register
movi a5, .Lload_table
addx8 a4, a4, a5
Expand Down Expand Up @@ -358,17 +346,6 @@ ENTRY(fast_unaligned)
/* Get memory address */

1:
#if XCHAL_HAVE_LOOPS
rsr a4, lend # check if we reached LEND
bne a7, a4, 1f
rsr a4, lcount # and LCOUNT != 0
beqz a4, 1f
addi a4, a4, -1 # decrement LCOUNT and set
rsr a7, lbeg # set PC to LBEGIN
wsr a4, lcount
#endif

1: wsr a7, epc1 # skip store instruction
movi a4, ~3
and a4, a4, a8 # align memory address

Expand All @@ -380,35 +357,45 @@ ENTRY(fast_unaligned)
#endif

__ssa8r a8
__src_b a7, a5, a6 # lo-mask F..F0..0 (BE) 0..0F..F (LE)
__src_b a8, a5, a6 # lo-mask F..F0..0 (BE) 0..0F..F (LE)
__src_b a6, a6, a5 # hi-mask 0..0F..F (BE) F..F0..0 (LE)
#ifdef UNALIGNED_USER_EXCEPTION
l32e a5, a4, -8
#else
l32i a5, a4, 0 # load lower address word
#endif
and a5, a5, a7 # mask
__sh a7, a3 # shift value
or a5, a5, a7 # or with original value
and a5, a5, a8 # mask
__sh a8, a3 # shift value
or a5, a5, a8 # or with original value
#ifdef UNALIGNED_USER_EXCEPTION
s32e a5, a4, -8
l32e a7, a4, -4
l32e a8, a4, -4
#else
s32i a5, a4, 0 # store
l32i a7, a4, 4 # same for upper address word
l32i a8, a4, 4 # same for upper address word
#endif
__sl a5, a3
and a6, a7, a6
and a6, a8, a6
or a6, a6, a5
#ifdef UNALIGNED_USER_EXCEPTION
s32e a6, a4, -4
#else
s32i a6, a4, 4
#endif

/* Done. restore stack and return */

.Lexit:
#if XCHAL_HAVE_LOOPS
rsr a4, lend # check if we reached LEND
bne a7, a4, 1f
rsr a4, lcount # and LCOUNT != 0
beqz a4, 1f
addi a4, a4, -1 # decrement LCOUNT and set
rsr a7, lbeg # set PC to LBEGIN
wsr a4, lcount
#endif

1: wsr a7, epc1 # skip emulated instruction

movi a4, 0
rsr a3, excsave1
s32i a4, a3, EXC_TABLE_FIXUP
Expand Down

0 comments on commit e9500dd

Please sign in to comment.