瀏覽代碼

xtensa: make fast_unaligned store restartable

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>
Max Filippov 11 年之前
父節點
當前提交
e9500dd852
共有 1 個文件被更改,包括 19 次插入32 次删除
  1. 19 32
      arch/xtensa/kernel/align.S

+ 19 - 32
arch/xtensa/kernel/align.S

@@ -277,18 +277,6 @@ ENTRY(fast_unaligned)
 	/* Set target register. */
 	/* Set target register. */
 
 
 1:
 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
 	extui	a4, a4, INSN_T, 4	# extract target register
 	movi	a5, .Lload_table
 	movi	a5, .Lload_table
 	addx8	a4, a4, a5
 	addx8	a4, a4, a5
@@ -358,17 +346,6 @@ ENTRY(fast_unaligned)
 	/* Get memory address */
 	/* Get memory address */
 
 
 1:
 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
 	movi	a4, ~3
 	and	a4, a4, a8		# align memory address
 	and	a4, a4, a8		# align memory address
 
 
@@ -380,25 +357,25 @@ ENTRY(fast_unaligned)
 #endif
 #endif
 
 
 	__ssa8r a8
 	__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)
 	__src_b	a6, a6, a5		# hi-mask  0..0F..F (BE) F..F0..0 (LE)
 #ifdef UNALIGNED_USER_EXCEPTION
 #ifdef UNALIGNED_USER_EXCEPTION
 	l32e	a5, a4, -8
 	l32e	a5, a4, -8
 #else
 #else
 	l32i	a5, a4, 0		# load lower address word
 	l32i	a5, a4, 0		# load lower address word
 #endif
 #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
 #ifdef UNALIGNED_USER_EXCEPTION
 	s32e	a5, a4, -8
 	s32e	a5, a4, -8
-	l32e	a7, a4, -4
+	l32e	a8, a4, -4
 #else
 #else
 	s32i	a5, a4, 0		# store
 	s32i	a5, a4, 0		# store
-	l32i	a7, a4, 4		# same for upper address word
+	l32i	a8, a4, 4		# same for upper address word
 #endif
 #endif
 	__sl	a5, a3
 	__sl	a5, a3
-	and	a6, a7, a6
+	and	a6, a8, a6
 	or	a6, a6, a5
 	or	a6, a6, a5
 #ifdef UNALIGNED_USER_EXCEPTION
 #ifdef UNALIGNED_USER_EXCEPTION
 	s32e	a6, a4, -4
 	s32e	a6, a4, -4
@@ -406,9 +383,19 @@ ENTRY(fast_unaligned)
 	s32i	a6, a4, 4
 	s32i	a6, a4, 4
 #endif
 #endif
 
 
-	/* Done. restore stack and return */
-
 .Lexit:
 .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
 	movi	a4, 0
 	rsr	a3, excsave1
 	rsr	a3, excsave1
 	s32i	a4, a3, EXC_TABLE_FIXUP
 	s32i	a4, a3, EXC_TABLE_FIXUP