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 <[email protected]> --- CC: Stefano Stabellini <[email protected]> CC: Julien Grall <[email protected]> CC: Volodymyr Babchuk <[email protected]> CC: Bertrand Marquis <[email protected]> CC: Michal Orzel <[email protected]> CC: Jan Setje-Eilers <[email protected]> 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
