|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC PATCH 1/1] xen/arm: smccc: preserve arguments before register setup
Some callers of arm_smccc_1_1_smc() pass get_user_reg() calls as
arguments. These include the SCMI, ZynqMP EEMI, and i.MX forwarding
paths.
The argument macros currently put each value into its SMC register as
the expression is evaluated. A later function call can overwrite a
register prepared for an earlier argument. Firmware then receives the
wrong values.
Restore temporary variables for a1-a7. Because the macros are nested,
this lets every function call finish before x0-x7 are prepared for the
SMC instruction. It also keeps the inferred type of each argument.
Fixes: 67bcf5eae709 ("xen/arm: Simplify type handling for SMCCC declarations")
Backport: 4.22+
Assisted-by: Codex:GPT-5
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@xxxxxxxxxx>
---
xen/arch/arm/include/asm/smccc.h | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/xen/arch/arm/include/asm/smccc.h b/xen/arch/arm/include/asm/smccc.h
index 62c6985e73..a153042cc5 100644
--- a/xen/arch/arm/include/asm/smccc.h
+++ b/xen/arch/arm/include/asm/smccc.h
@@ -108,37 +108,49 @@ struct arm_smccc_res {
#define __constraint_read_6 __constraint_read_5, "r" (arg6)
#define __constraint_read_7 __constraint_read_6, "r" (arg7)
+/*
+ * Save a1-a7 in temporary variables before assigning the SMC argument
+ * registers. A later argument may call a function and overwrite a register
+ * assigned earlier.
+ */
#define __declare_arg_0(a0, res) \
struct arm_smccc_res *___res = (res); \
register unsigned long arg0 ASM_REG(0) = (uint32_t)(a0)
#define __declare_arg_1(a0, a1, res) \
+ auto __a1 = (a1); \
__declare_arg_0(a0, res); \
- register auto arg1 ASM_REG(1) = (a1)
+ register auto arg1 ASM_REG(1) = __a1
#define __declare_arg_2(a0, a1, a2, res) \
+ auto __a2 = (a2); \
__declare_arg_1(a0, a1, res); \
- register auto arg2 ASM_REG(2) = (a2)
+ register auto arg2 ASM_REG(2) = __a2
#define __declare_arg_3(a0, a1, a2, a3, res) \
+ auto __a3 = (a3); \
__declare_arg_2(a0, a1, a2, res); \
- register auto arg3 ASM_REG(3) = (a3)
+ register auto arg3 ASM_REG(3) = __a3
#define __declare_arg_4(a0, a1, a2, a3, a4, res) \
+ auto __a4 = (a4); \
__declare_arg_3(a0, a1, a2, a3, res); \
- register auto arg4 ASM_REG(4) = (a4)
+ register auto arg4 ASM_REG(4) = __a4
#define __declare_arg_5(a0, a1, a2, a3, a4, a5, res) \
+ auto __a5 = (a5); \
__declare_arg_4(a0, a1, a2, a3, a4, res); \
- register auto arg5 ASM_REG(5) = (a5)
+ register auto arg5 ASM_REG(5) = __a5
#define __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res) \
+ auto __a6 = (a6); \
__declare_arg_5(a0, a1, a2, a3, a4, a5, res); \
- register auto arg6 ASM_REG(6) = (a6)
+ register auto arg6 ASM_REG(6) = __a6
#define __declare_arg_7(a0, a1, a2, a3, a4, a5, a6, a7, res) \
+ auto __a7 = (a7); \
__declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res); \
- register auto arg7 ASM_REG(7) = (a7)
+ register auto arg7 ASM_REG(7) = __a7
#define ___declare_args(count, ...) __declare_arg_ ## count(__VA_ARGS__)
#define __declare_args(count, ...) ___declare_args(count, __VA_ARGS__)
--
2.47.3
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |