diff mbox series

[v2] arm64: smccc: Save lr before calling __arm_smccc_sve_check()

Message ID 20210721071834.69130-1-jean-philippe@linaro.org (mailing list archive)
State New, archived
Headers show
Series [v2] arm64: smccc: Save lr before calling __arm_smccc_sve_check() | expand

Commit Message

Jean-Philippe Brucker July 21, 2021, 7:18 a.m. UTC
Commit cfa7ff959a78 ("arm64: smccc: Support SMCCC v1.3 SVE register
saving hint") added a call to __arm_smccc_sve_check() which clobbers the
lr (register x30), causing __arm_smccc_hvc() to return to itself and
crash. Save lr on the stack before calling __arm_smccc_sve_check(). Save
the frame pointer (x29) to complete the frame record, and adjust the
offsets used to access stack parameters.

Acked-by: Ard Biesheuvel <ardb@kernel.org>
Acked-by: Mark Brown <broonie@kernel.org>
Fixes: cfa7ff959a78 ("arm64: smccc: Support SMCCC v1.3 SVE register saving hint")
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---

Under QEMU TCG (-cpu max), PSCI calls now cause a BUG(), since the
clobbered lr causes __arm_smccc_hvc() to return to the hvc instruction
with invalid x0 parameter, which is treated as undefined instruction by
TCG.
---
 arch/arm64/kernel/smccc-call.S | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

Comments

Will Deacon July 21, 2021, 10:47 a.m. UTC | #1
On Wed, 21 Jul 2021 09:18:35 +0200, Jean-Philippe Brucker wrote:
> Commit cfa7ff959a78 ("arm64: smccc: Support SMCCC v1.3 SVE register
> saving hint") added a call to __arm_smccc_sve_check() which clobbers the
> lr (register x30), causing __arm_smccc_hvc() to return to itself and
> crash. Save lr on the stack before calling __arm_smccc_sve_check(). Save
> the frame pointer (x29) to complete the frame record, and adjust the
> offsets used to access stack parameters.

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: smccc: Save lr before calling __arm_smccc_sve_check()
      https://git.kernel.org/arm64/c/a7c3acca5380

Cheers,
diff mbox series

Patch

diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S
index d3d37f932b97..487381164ff6 100644
--- a/arch/arm64/kernel/smccc-call.S
+++ b/arch/arm64/kernel/smccc-call.S
@@ -32,20 +32,23 @@  SYM_FUNC_END(__arm_smccc_sve_check)
 EXPORT_SYMBOL(__arm_smccc_sve_check)
 
 	.macro SMCCC instr
+	stp     x29, x30, [sp, #-16]!
+	mov	x29, sp
 alternative_if ARM64_SVE
 	bl	__arm_smccc_sve_check
 alternative_else_nop_endif
 	\instr	#0
-	ldr	x4, [sp]
+	ldr	x4, [sp, #16]
 	stp	x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS]
 	stp	x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS]
-	ldr	x4, [sp, #8]
+	ldr	x4, [sp, #24]
 	cbz	x4, 1f /* no quirk structure */
 	ldr	x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS]
 	cmp	x9, #ARM_SMCCC_QUIRK_QCOM_A6
 	b.ne	1f
 	str	x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS]
-1:	ret
+1:	ldp     x29, x30, [sp], #16
+	ret
 	.endm
 
 /*