|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] xen/arm: Introduce arm_smccc_guest_smc()
commit b128b74cf85e3336b8262a0e92f8b6d651e3da5b
Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Mon Aug 31 11:44:40 2026 +0100
Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Mon Sep 7 11:18:11 2026 +0100
xen/arm: Introduce arm_smccc_guest_smc()
Both {get,set}_user_reg() are out-of-line functions, leading to awful code
generation.
Introduce arm_smccc_guest_smc() to operate directly on guest registers.
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Reviewed-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
---
xen/arch/arm/firmware/scmi-smc.c | 16 +---------------
xen/arch/arm/include/asm/smccc.h | 29 +++++++++++++++++++++++++++++
xen/arch/arm/platforms/imx8m.c | 16 +---------------
xen/arch/arm/platforms/imx8qm.c | 16 +---------------
xen/arch/arm/platforms/xilinx-zynqmp-eemi.c | 17 ++---------------
5 files changed, 34 insertions(+), 60 deletions(-)
diff --git a/xen/arch/arm/firmware/scmi-smc.c b/xen/arch/arm/firmware/scmi-smc.c
index 0835ddeeec..a0cc6c6192 100644
--- a/xen/arch/arm/firmware/scmi-smc.c
+++ b/xen/arch/arm/firmware/scmi-smc.c
@@ -50,7 +50,6 @@ static bool scmi_is_valid_smc_id(uint32_t fid)
static bool scmi_handle_smc(struct cpu_user_regs *regs)
{
uint32_t fid = (uint32_t)get_user_reg(regs, 0);
- struct arm_smccc_res res;
if ( !scmi_is_valid_smc_id(fid) )
return false;
@@ -63,20 +62,7 @@ static bool scmi_handle_smc(struct cpu_user_regs *regs)
}
/* For the moment, forward the SCMI Request to FW running at EL3 */
- arm_smccc_1_1_smc(fid,
- get_user_reg(regs, 1),
- get_user_reg(regs, 2),
- get_user_reg(regs, 3),
- get_user_reg(regs, 4),
- get_user_reg(regs, 5),
- get_user_reg(regs, 6),
- get_user_reg(regs, 7),
- &res);
-
- set_user_reg(regs, 0, res.a0);
- set_user_reg(regs, 1, res.a1);
- set_user_reg(regs, 2, res.a2);
- set_user_reg(regs, 3, res.a3);
+ arm_smccc_guest_smc(regs);
return true;
}
diff --git a/xen/arch/arm/include/asm/smccc.h b/xen/arch/arm/include/asm/smccc.h
index 53cdddb690..832157f437 100644
--- a/xen/arch/arm/include/asm/smccc.h
+++ b/xen/arch/arm/include/asm/smccc.h
@@ -202,6 +202,21 @@ struct arm_smccc_res {
#ifdef CONFIG_ARM_32
#define arm_smccc_1_0_smc(...) arm_smccc_1_1_smc(__VA_ARGS__)
#define arm_smccc_smc(...) arm_smccc_1_1_smc(__VA_ARGS__)
+
+/* Make an SMCCC v1.1 compliant SMC call with guest register state. */
+static inline void arm_smccc_guest_smc(struct cpu_user_regs *regs)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_1_1_smc(regs->r0, regs->r1, regs->r2, regs->r3,
+ regs->r4, regs->r5, regs->r6, regs->r7, &res);
+
+ regs->r0 = res.a0;
+ regs->r1 = res.a1;
+ regs->r2 = res.a2;
+ regs->r3 = res.a3;
+}
+
#else
void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
@@ -251,6 +266,20 @@ void __arm_smccc_1_0_smc(register_t a0, register_t a1,
register_t a2,
arm_smccc_1_0_smc(__VA_ARGS__); \
} while ( 0 )
+/* Make an SMCCC v1.1 compliant SMC call with guest register state. */
+static inline void arm_smccc_guest_smc(struct cpu_user_regs *regs)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_1_1_smc(regs->x0, regs->x1, regs->x2, regs->x3,
+ regs->x4, regs->x5, regs->x6, regs->x7, &res);
+
+ regs->x0 = res.a0;
+ regs->x1 = res.a1;
+ regs->x2 = res.a2;
+ regs->x3 = res.a3;
+}
+
/*
* struct arm_smccc_1_2_regs - Arguments for or Results from SMC call
* @a0-a17 argument values from registers 0 to 17
diff --git a/xen/arch/arm/platforms/imx8m.c b/xen/arch/arm/platforms/imx8m.c
index 669dd517e0..efb0ad20d6 100644
--- a/xen/arch/arm/platforms/imx8m.c
+++ b/xen/arch/arm/platforms/imx8m.c
@@ -50,7 +50,6 @@ static bool imx8m_smc(struct cpu_user_regs *regs)
{
uint32_t function_id = get_user_reg(regs, 0);
uint32_t subfunction_id = get_user_reg(regs, 1);
- struct arm_smccc_res res;
if ( !cpus_have_const_cap(ARM_SMCCC_1_1) )
{
@@ -122,20 +121,7 @@ static bool imx8m_smc(struct cpu_user_regs *regs)
return false;
}
- arm_smccc_1_1_smc(function_id,
- subfunction_id,
- get_user_reg(regs, 2),
- get_user_reg(regs, 3),
- get_user_reg(regs, 4),
- get_user_reg(regs, 5),
- get_user_reg(regs, 6),
- get_user_reg(regs, 7),
- &res);
-
- set_user_reg(regs, 0, res.a0);
- set_user_reg(regs, 1, res.a1);
- set_user_reg(regs, 2, res.a2);
- set_user_reg(regs, 3, res.a3);
+ arm_smccc_guest_smc(regs);
return true;
}
diff --git a/xen/arch/arm/platforms/imx8qm.c b/xen/arch/arm/platforms/imx8qm.c
index 3600a073e8..7249e14ab6 100644
--- a/xen/arch/arm/platforms/imx8qm.c
+++ b/xen/arch/arm/platforms/imx8qm.c
@@ -67,7 +67,6 @@ static bool imx8qm_smc(struct cpu_user_regs *regs)
{
uint32_t function_id = get_user_reg(regs, 0);
uint32_t subfunction_id = get_user_reg(regs, 1);
- struct arm_smccc_res res;
if ( !cpus_have_const_cap(ARM_SMCCC_1_1) )
{
@@ -106,20 +105,7 @@ static bool imx8qm_smc(struct cpu_user_regs *regs)
}
allow_call:
- arm_smccc_1_1_smc(function_id,
- subfunction_id,
- get_user_reg(regs, 2),
- get_user_reg(regs, 3),
- get_user_reg(regs, 4),
- get_user_reg(regs, 5),
- get_user_reg(regs, 6),
- get_user_reg(regs, 7),
- &res);
-
- set_user_reg(regs, 0, res.a0);
- set_user_reg(regs, 1, res.a1);
- set_user_reg(regs, 2, res.a2);
- set_user_reg(regs, 3, res.a3);
+ arm_smccc_guest_smc(regs);
return true;
}
diff --git a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
index 2053ed7ac5..326c8a1ba6 100644
--- a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
+++ b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
@@ -51,7 +51,6 @@ static inline bool domain_has_reset_access(struct domain *d,
uint32_t rst)
bool zynqmp_eemi(struct cpu_user_regs *regs)
{
- struct arm_smccc_res res;
uint32_t fid = get_user_reg(regs, 0);
uint32_t nodeid = get_user_reg(regs, 1);
unsigned int pm_fn = fid & 0xFFFF;
@@ -187,20 +186,8 @@ forward_to_fw:
* can forward the whole command to firmware without additional
* parameters checks.
*/
- arm_smccc_1_1_smc(get_user_reg(regs, 0),
- get_user_reg(regs, 1),
- get_user_reg(regs, 2),
- get_user_reg(regs, 3),
- get_user_reg(regs, 4),
- get_user_reg(regs, 5),
- get_user_reg(regs, 6),
- get_user_reg(regs, 7),
- &res);
-
- set_user_reg(regs, 0, res.a0);
- set_user_reg(regs, 1, res.a1);
- set_user_reg(regs, 2, res.a2);
- set_user_reg(regs, 3, res.a3);
+ arm_smccc_guest_smc(regs);
+
return true;
done:
--
generated by git-patchbot for /home/xen/git/xen.git#staging
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |