xtensa: fixes for configs without loop option
Build-time fixes: - make lbeg/lend/lcount save/restore conditional on kernel entry; - don't clear lcount in platform_restart functions unconditionally. Run-time fixes: - use correct end of range register in __endla paired with __loopt, not the unused temporary register. This fixes .bss zero-initialization. Update comments in asmmacro.h; - don't clobber a10 in the usercopy that leads to access to unmapped memory. Cc: <stable@vger.kernel.org> Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
Родитель
6a13feb9c8
Коммит
5029615e25
|
@ -35,9 +35,10 @@
|
||||||
* __loop as
|
* __loop as
|
||||||
* restart loop. 'as' register must not have been modified!
|
* restart loop. 'as' register must not have been modified!
|
||||||
*
|
*
|
||||||
* __endla ar, at, incr
|
* __endla ar, as, incr
|
||||||
* ar start address (modified)
|
* ar start address (modified)
|
||||||
* as scratch register used by macro
|
* as scratch register used by __loops/__loopi macros or
|
||||||
|
* end address used by __loopt macro
|
||||||
* inc increment
|
* inc increment
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -97,7 +98,7 @@
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* loop from ar to ax
|
* loop from ar to as
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.macro __loopt ar, as, at, incr_log2
|
.macro __loopt ar, as, at, incr_log2
|
||||||
|
|
|
@ -367,8 +367,10 @@ common_exception:
|
||||||
s32i a2, a1, PT_SYSCALL
|
s32i a2, a1, PT_SYSCALL
|
||||||
movi a2, 0
|
movi a2, 0
|
||||||
s32i a3, a1, PT_EXCVADDR
|
s32i a3, a1, PT_EXCVADDR
|
||||||
|
#if XCHAL_HAVE_LOOPS
|
||||||
xsr a2, lcount
|
xsr a2, lcount
|
||||||
s32i a2, a1, PT_LCOUNT
|
s32i a2, a1, PT_LCOUNT
|
||||||
|
#endif
|
||||||
|
|
||||||
/* It is now save to restore the EXC_TABLE_FIXUP variable. */
|
/* It is now save to restore the EXC_TABLE_FIXUP variable. */
|
||||||
|
|
||||||
|
@ -429,11 +431,12 @@ common_exception:
|
||||||
rsync # PS.WOE => rsync => overflow
|
rsync # PS.WOE => rsync => overflow
|
||||||
|
|
||||||
/* Save lbeg, lend */
|
/* Save lbeg, lend */
|
||||||
|
#if XCHAL_HAVE_LOOPS
|
||||||
rsr a4, lbeg
|
rsr a4, lbeg
|
||||||
rsr a3, lend
|
rsr a3, lend
|
||||||
s32i a4, a1, PT_LBEG
|
s32i a4, a1, PT_LBEG
|
||||||
s32i a3, a1, PT_LEND
|
s32i a3, a1, PT_LEND
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Save SCOMPARE1 */
|
/* Save SCOMPARE1 */
|
||||||
|
|
||||||
|
@ -724,13 +727,14 @@ common_exception_exit:
|
||||||
wsr a3, sar
|
wsr a3, sar
|
||||||
|
|
||||||
/* Restore LBEG, LEND, LCOUNT */
|
/* Restore LBEG, LEND, LCOUNT */
|
||||||
|
#if XCHAL_HAVE_LOOPS
|
||||||
l32i a2, a1, PT_LBEG
|
l32i a2, a1, PT_LBEG
|
||||||
l32i a3, a1, PT_LEND
|
l32i a3, a1, PT_LEND
|
||||||
wsr a2, lbeg
|
wsr a2, lbeg
|
||||||
l32i a2, a1, PT_LCOUNT
|
l32i a2, a1, PT_LCOUNT
|
||||||
wsr a3, lend
|
wsr a3, lend
|
||||||
wsr a2, lcount
|
wsr a2, lcount
|
||||||
|
#endif
|
||||||
|
|
||||||
/* We control single stepping through the ICOUNTLEVEL register. */
|
/* We control single stepping through the ICOUNTLEVEL register. */
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ ENTRY(_startup)
|
||||||
|
|
||||||
__loopt a2, a3, a4, 2
|
__loopt a2, a3, a4, 2
|
||||||
s32i a0, a2, 0
|
s32i a0, a2, 0
|
||||||
__endla a2, a4, 4
|
__endla a2, a3, 4
|
||||||
|
|
||||||
#if XCHAL_DCACHE_IS_WRITEBACK
|
#if XCHAL_DCACHE_IS_WRITEBACK
|
||||||
|
|
||||||
|
|
|
@ -222,8 +222,8 @@ __xtensa_copy_user:
|
||||||
loopnez a7, .Loop2done
|
loopnez a7, .Loop2done
|
||||||
#else /* !XCHAL_HAVE_LOOPS */
|
#else /* !XCHAL_HAVE_LOOPS */
|
||||||
beqz a7, .Loop2done
|
beqz a7, .Loop2done
|
||||||
slli a10, a7, 4
|
slli a12, a7, 4
|
||||||
add a10, a10, a3 # a10 = end of last 16B source chunk
|
add a12, a12, a3 # a12 = end of last 16B source chunk
|
||||||
#endif /* !XCHAL_HAVE_LOOPS */
|
#endif /* !XCHAL_HAVE_LOOPS */
|
||||||
.Loop2:
|
.Loop2:
|
||||||
EX(l32i, a7, a3, 4, l_fixup)
|
EX(l32i, a7, a3, 4, l_fixup)
|
||||||
|
@ -241,7 +241,7 @@ __xtensa_copy_user:
|
||||||
EX(s32i, a9, a5, 12, s_fixup)
|
EX(s32i, a9, a5, 12, s_fixup)
|
||||||
addi a5, a5, 16
|
addi a5, a5, 16
|
||||||
#if !XCHAL_HAVE_LOOPS
|
#if !XCHAL_HAVE_LOOPS
|
||||||
blt a3, a10, .Loop2
|
blt a3, a12, .Loop2
|
||||||
#endif /* !XCHAL_HAVE_LOOPS */
|
#endif /* !XCHAL_HAVE_LOOPS */
|
||||||
.Loop2done:
|
.Loop2done:
|
||||||
bbci.l a4, 3, .L12
|
bbci.l a4, 3, .L12
|
||||||
|
|
|
@ -61,7 +61,9 @@ void platform_restart(void)
|
||||||
#if XCHAL_NUM_IBREAK > 0
|
#if XCHAL_NUM_IBREAK > 0
|
||||||
"wsr a2, ibreakenable\n\t"
|
"wsr a2, ibreakenable\n\t"
|
||||||
#endif
|
#endif
|
||||||
|
#if XCHAL_HAVE_LOOPS
|
||||||
"wsr a2, lcount\n\t"
|
"wsr a2, lcount\n\t"
|
||||||
|
#endif
|
||||||
"movi a2, 0x1f\n\t"
|
"movi a2, 0x1f\n\t"
|
||||||
"wsr a2, ps\n\t"
|
"wsr a2, ps\n\t"
|
||||||
"isync\n\t"
|
"isync\n\t"
|
||||||
|
|
|
@ -72,7 +72,9 @@ void platform_restart(void)
|
||||||
#if XCHAL_NUM_IBREAK > 0
|
#if XCHAL_NUM_IBREAK > 0
|
||||||
"wsr a2, ibreakenable\n\t"
|
"wsr a2, ibreakenable\n\t"
|
||||||
#endif
|
#endif
|
||||||
|
#if XCHAL_HAVE_LOOPS
|
||||||
"wsr a2, lcount\n\t"
|
"wsr a2, lcount\n\t"
|
||||||
|
#endif
|
||||||
"movi a2, 0x1f\n\t"
|
"movi a2, 0x1f\n\t"
|
||||||
"wsr a2, ps\n\t"
|
"wsr a2, ps\n\t"
|
||||||
"isync\n\t"
|
"isync\n\t"
|
||||||
|
|
|
@ -63,7 +63,9 @@ void platform_restart(void)
|
||||||
#if XCHAL_NUM_IBREAK > 0
|
#if XCHAL_NUM_IBREAK > 0
|
||||||
"wsr a2, ibreakenable\n\t"
|
"wsr a2, ibreakenable\n\t"
|
||||||
#endif
|
#endif
|
||||||
|
#if XCHAL_HAVE_LOOPS
|
||||||
"wsr a2, lcount\n\t"
|
"wsr a2, lcount\n\t"
|
||||||
|
#endif
|
||||||
"movi a2, 0x1f\n\t"
|
"movi a2, 0x1f\n\t"
|
||||||
"wsr a2, ps\n\t"
|
"wsr a2, ps\n\t"
|
||||||
"isync\n\t"
|
"isync\n\t"
|
||||||
|
|
Загрузка…
Ссылка в новой задаче