|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 2/6] xen/arm: Introduce arm_smccc_guest_smc()
Hi Andrew,
> On 31 Aug 2026, at 14:19, Andrew Cooper <andrew.cooper3@xxxxxxxxxx> wrote:
>
> 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>
Looks good to me.
Reviewed-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
Cheers
Bertrand
> ---
> 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 |