Commit 77d6273e authored by Max Filippov's avatar Max Filippov
Browse files

xtensa: fix kernel register spilling



call12 can't be safely used as the first call in the inline function,
because the compiler does not extend the stack frame of the bounding
function accordingly, which may result in corruption of local variables.

If a call needs to be done, do call8 first followed by call12.

For pure assembly code in _switch_to increase stack frame size of the
bounding function.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarMax Filippov <jcmvbkbc@gmail.com>
parent 7d5f6a9a
Loading
Loading
Loading
Loading
+19 −10
Original line number Diff line number Diff line
@@ -25,30 +25,39 @@ static inline void spill_registers(void)
{
#if XCHAL_NUM_AREGS > 16
	__asm__ __volatile__ (
		"	call12	1f\n"
		"	call8	1f\n"
		"	_j	2f\n"
		"	retw\n"
		"	.align	4\n"
		"1:\n"
#if XCHAL_NUM_AREGS == 32
		"	_entry	a1, 32\n"
		"	addi	a8, a0, 3\n"
		"	_entry	a1, 16\n"
		"	mov	a12, a12\n"
		"	retw\n"
#else
		"	_entry	a1, 48\n"
		"	addi	a12, a0, 3\n"
#if XCHAL_NUM_AREGS > 32
		"	.rept	(" __stringify(XCHAL_NUM_AREGS) " - 32) / 12\n"
		"	call12	1f\n"
		"	retw\n"
		"	.align	4\n"
		"1:\n"
		"	.rept	(" __stringify(XCHAL_NUM_AREGS) " - 16) / 12\n"
		"	_entry	a1, 48\n"
		"	mov	a12, a0\n"
		"	.endr\n"
#endif
		"	_entry	a1, 48\n"
		"	_entry	a1, 16\n"
#if XCHAL_NUM_AREGS % 12 == 0
		"	mov	a8, a8\n"
#elif XCHAL_NUM_AREGS % 12 == 4
		"	mov	a12, a12\n"
#elif XCHAL_NUM_AREGS % 12 == 8
#elif XCHAL_NUM_AREGS % 12 == 4
		"	mov	a4, a4\n"
#elif XCHAL_NUM_AREGS % 12 == 8
		"	mov	a8, a8\n"
#endif
		"	retw\n"
#endif
		"2:\n"
		: : : "a12", "a13", "memory");
		: : : "a8", "a9", "memory");
#else
	__asm__ __volatile__ (
		"	mov	a12, a12\n"
+2 −2
Original line number Diff line number Diff line
@@ -1823,7 +1823,7 @@ ENDPROC(system_call)
	mov	a12, a0
	.endr
#endif
	_entry	a1, 48
	_entry	a1, 16
#if XCHAL_NUM_AREGS % 12 == 0
	mov	a8, a8
#elif XCHAL_NUM_AREGS % 12 == 4
@@ -1847,7 +1847,7 @@ ENDPROC(system_call)

ENTRY(_switch_to)

	entry	a1, 16
	entry	a1, 48

	mov	a11, a3			# and 'next' (a3)