[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <878qlkexr2.wl-maz@kernel.org>
Date: Sun, 22 Jun 2025 14:01:21 +0100
From: Marc Zyngier <maz@...nel.org>
To: perlarsen@...gle.com
Cc: Oliver Upton <oliver.upton@...ux.dev>,
Joey Gouly <joey.gouly@....com>,
Suzuki K Poulose <suzuki.poulose@....com>,
Zenghui Yu <yuzenghui@...wei.com>,
Catalin Marinas <catalin.marinas@....com>,
Will Deacon <will@...nel.org>,
Sudeep Holla <sudeep.holla@....com>,
linux-arm-kernel@...ts.infradead.org,
kvmarm@...ts.linux.dev,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH v5 3/6] KVM: arm64: Use SMCCC 1.2 in host FF-A handler
On Thu, 19 Jun 2025 10:02:56 +0100,
Per Larsen via B4 Relay <devnull+perlarsen.google.com@...nel.org> wrote:
>
> From: Per Larsen <perlarsen@...gle.com>
>
> SMCCC 1.1 and prior allows four registers to be sent back as a result
> of an FF-A interface. SMCCC 1.2 increases the number of results that can
> (and often must) be sent back to 8 and 16 for 32-bit and 64-bit SMC/HVCs
> respectively.
>
> FF-A 1.0 references SMCCC 1.2 (reference [4] on page xi) and FF-A 1.2
> explicitly requires SMCCC 1.2 so it should be safe to use this version
> unconditionally. Moreover, it is simpler to implement FF-A features
> without having to worry about compatibility with SMCCC 1.1 and older.
>
> Add SMCCC 1.2 helper routines and use this version unconditionally.
Well, the previous patch already mandates that, so I wonder why you
have two patches tackling the same thing.
>
> Signed-off-by: Per Larsen <perlarsen@...gle.com>
> ---
> arch/arm64/kvm/hyp/nvhe/ffa.c | 297 ++++++++++++++++++++++++------------------
> 1 file changed, 173 insertions(+), 124 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> index 51bbe8f9c94584e9001ee769cbfd608d930ff723..23b75b9f0bcc62724f0d0d185ac2ed2526375da4 100644
> --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> @@ -71,36 +71,55 @@ static u32 hyp_ffa_version;
> static bool has_version_negotiated;
> static hyp_spinlock_t version_lock;
>
> -static void ffa_to_smccc_error(struct arm_smccc_res *res, u64 ffa_errno)
> +static void ffa_to_smccc_1_2_error(struct arm_smccc_1_2_regs *regs, u64 ffa_errno)
> {
> - *res = (struct arm_smccc_res) {
> + *regs = (struct arm_smccc_1_2_regs) {
> .a0 = FFA_ERROR,
> .a2 = ffa_errno,
> };
> }
>
> -static void ffa_to_smccc_res_prop(struct arm_smccc_res *res, int ret, u64 prop)
> +static void ffa_to_smccc_regs_prop(struct arm_smccc_1_2_regs *regs, int ret,
> + u64 prop)
> {
> if (ret == FFA_RET_SUCCESS) {
> - *res = (struct arm_smccc_res) { .a0 = FFA_SUCCESS,
> - .a2 = prop };
> + *regs = (struct arm_smccc_1_2_regs) { .a0 = FFA_SUCCESS,
> + .a2 = prop };
> } else {
> - ffa_to_smccc_error(res, ret);
> + ffa_to_smccc_1_2_error(regs, ret);
> }
> }
>
> -static void ffa_to_smccc_res(struct arm_smccc_res *res, int ret)
> +static void ffa_to_smccc_regs(struct arm_smccc_1_2_regs *regs, int ret)
> {
> - ffa_to_smccc_res_prop(res, ret, 0);
> + ffa_to_smccc_regs_prop(regs, ret, 0);
> }
>
> static void ffa_set_retval(struct kvm_cpu_context *ctxt,
> - struct arm_smccc_res *res)
> + struct arm_smccc_1_2_regs *regs)
> {
> - cpu_reg(ctxt, 0) = res->a0;
> - cpu_reg(ctxt, 1) = res->a1;
> - cpu_reg(ctxt, 2) = res->a2;
> - cpu_reg(ctxt, 3) = res->a3;
> + cpu_reg(ctxt, 0) = regs->a0;
> + cpu_reg(ctxt, 1) = regs->a1;
> + cpu_reg(ctxt, 2) = regs->a2;
> + cpu_reg(ctxt, 3) = regs->a3;
> + cpu_reg(ctxt, 4) = regs->a4;
> + cpu_reg(ctxt, 5) = regs->a5;
> + cpu_reg(ctxt, 6) = regs->a6;
> + cpu_reg(ctxt, 7) = regs->a7;
> +
But my main problem with this patch is this sort of pointless
churn. Changing "res" to "regs" just for the sake of it is completely
pointless, and makes everything harder to read.
Please do yourself (and everybody else) a favour by keeping the
variable name the same.
> + /* DEN0028C 2.6: SMC32/HVC32 call from aarch64 must preserve x8-x30 */
> + if (ARM_SMCCC_IS_64(regs->a0)) {
This is the *return value*, right? Not the function number. How can
you tell about the 64-bitness of the function number based on that?
> + cpu_reg(ctxt, 8) = regs->a8;
> + cpu_reg(ctxt, 9) = regs->a9;
> + cpu_reg(ctxt, 10) = regs->a10;
> + cpu_reg(ctxt, 11) = regs->a11;
> + cpu_reg(ctxt, 12) = regs->a12;
> + cpu_reg(ctxt, 13) = regs->a13;
> + cpu_reg(ctxt, 14) = regs->a14;
> + cpu_reg(ctxt, 15) = regs->a15;
> + cpu_reg(ctxt, 16) = regs->a16;
> + cpu_reg(ctxt, 17) = regs->a17;
> + }
> }
>
> static bool is_ffa_call(u64 func_id)
> @@ -113,82 +132,104 @@ static bool is_ffa_call(u64 func_id)
>
> static int ffa_map_hyp_buffers(u64 ffa_page_count)
> {
> - struct arm_smccc_res res;
> + struct arm_smccc_1_2_regs regs;
>
> - arm_smccc_1_1_smc(FFA_FN64_RXTX_MAP,
> - hyp_virt_to_phys(hyp_buffers.tx),
> - hyp_virt_to_phys(hyp_buffers.rx),
> - ffa_page_count,
> - 0, 0, 0, 0,
> - &res);
> + regs = (struct arm_smccc_1_2_regs) {
> + .a0 = FFA_FN64_RXTX_MAP,
> + .a1 = hyp_virt_to_phys(hyp_buffers.tx),
> + .a2 = hyp_virt_to_phys(hyp_buffers.rx),
> + .a3 = ffa_page_count,
> + };
> + arm_smccc_1_2_smc(®s, ®s);
To expand on my previous comment about this res/regs repainting, I'd
rather see something like:
struct arm_smccc_1_2_regs res;
arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs){
.a0 = FFA_FN64_RXTX_MAP,
.a1 = hyp_virt_to_phys(hyp_buffers.tx),
.a2 = hyp_virt_to_phys(hyp_buffers.rx),
.a3 = ffa_page_count,
}, &res);
> + if (regs.a0 != FFA_SUCCESS)
> + return regs.a2;
>
> - return res.a0 == FFA_SUCCESS ? FFA_RET_SUCCESS : res.a2;
> + return regs.a0 == FFA_SUCCESS ? FFA_RET_SUCCESS : regs.a2;
Why are you writing the same thing twice?
I stopped reading here.
M.
--
Jazz isn't dead. It just smells funny.
Powered by blists - more mailing lists