|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 2/6] 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>
---
CC: Stefano Stabellini <sstabellini@xxxxxxxxxx>
CC: Julien Grall <julien@xxxxxxx>
CC: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
CC: Bertrand Marquis <bertrand.marquis@xxxxxxx>
CC: Michal Orzel <michal.orzel@xxxxxxx>
CC: Jan Setje-Eilers <Jan.SetjeEilers@xxxxxxxxxx>
For arm64:
add/remove: 0/0 grow/shrink: 2/4 up/down: 27/-864 (-837)
Function old new delta
symbols_addresses 35096 35120 +24
symbols_names 42958 42961 +3
imx8qm_smc 544 348 -196
scmi_handle_smc 372 152 -220
imx8m_smc 576 356 -220
zynqmp_eemi 864 636 -228
For arm32:
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-160 (-160)
Function old new delta
scmi_handle_smc 392 232 -160
---
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 0835ddeeeccc..a0cc6c6192f8 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 53cdddb690b7..832157f43734 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 669dd517e057..efb0ad20d6e8 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 3600a073e8ba..7249e14ab640 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 2053ed7ac5f6..326c8a1ba6e5 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 @@ bool zynqmp_eemi(struct cpu_user_regs *regs)
* 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:
--
2.39.5
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |