From 7af261fc12472fbbe8c8f5b178abd22f2bc97dd6 Mon Sep 17 00:00:00 2001 From: Sebastian Ene Date: Thu, 15 May 2025 15:35:54 +0000 Subject: [PATCH] ANDROID: KVM: arm64: Use smccc 1.2 for direct FF-A calls Make use of all the registers x4-x17 for direct FF-A request/responses and keep compatibility with smccc 1.1. Bug: 416377721 Change-Id: I9ee946969a25660296c39d1bbdc857a3fd451791 Signed-off-by: Sebastian Ene --- arch/arm64/kvm/hyp/nvhe/Makefile | 3 ++- arch/arm64/kvm/hyp/nvhe/ffa.c | 44 ++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile index 81e0c8057048..d3157145c685 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -10,7 +10,8 @@ hyp-obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o cache.o setup.o mm.o mem_protect.o sys_regs.o pkvm.o stacktrace.o ffa.o \ serial.o alloc_mgt.o iommu/iommu.o power/hvc.o power/scmi.o device/device.o hyp-obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \ - ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o iommu/pviommu-host.o iommu/pviommu.o + ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o iommu/pviommu-host.o iommu/pviommu.o \ + ../../../kernel/smccc-call.o hyp-obj-$(CONFIG_LIST_HARDENED) += list_debug.o hyp-obj-$(CONFIG_TRACING) += clock.o events.o trace.o hyp-obj-$(CONFIG_PROTECTED_NVHE_FTRACE) += ftrace.o diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c index c26c4ffaff67..7995f63b8f58 100644 --- a/arch/arm64/kvm/hyp/nvhe/ffa.c +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c @@ -27,6 +27,7 @@ */ #include +#include #include #include @@ -1107,8 +1108,7 @@ out_unlock: hyp_spin_unlock(&kvm_ffa_hyp_lock); } -static void do_ffa_direct_msg(struct arm_smccc_res *res, - struct kvm_cpu_context *ctxt, +static void do_ffa_direct_msg(struct kvm_cpu_context *ctxt, u64 vm_handle) { DECLARE_REG(u32, func_id, ctxt, 0); @@ -1120,14 +1120,38 @@ static void do_ffa_direct_msg(struct arm_smccc_res *res, DECLARE_REG(u32, w6, ctxt, 6); DECLARE_REG(u32, w7, ctxt, 7); + struct arm_smccc_1_2_regs req, resp; + if (FIELD_GET(FFA_SRC_ENDPOINT_MASK, endp) != vm_handle) { - ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS); + resp = (struct arm_smccc_1_2_regs) { + .a0 = FFA_ERROR, + .a2 = FFA_RET_INVALID_PARAMETERS, + }; return; } - arm_smccc_1_1_smc(func_id, endp, msg_flags, w3, - w4, w5, w6, w7, - res); + req = (struct arm_smccc_1_2_regs) { + .a0 = func_id, + .a1 = endp, + .a2 = msg_flags, + .a3 = w3, + .a4 = w4, + .a5 = w5, + .a6 = w6, + .a7 = w7, + }; + + /* + * In case SMCCC 1.2 is not supported we should preserve the + * host registers. + */ + memcpy(&resp, &ctxt->regs.regs[0], sizeof(resp)); + + __hyp_exit(); + arm_smccc_1_2_smc(&req, &resp); + __hyp_enter(); + + memcpy(&ctxt->regs.regs[0], &resp, sizeof(resp)); } bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id) @@ -1198,8 +1222,8 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id) goto out_handled; case FFA_MSG_SEND_DIRECT_REQ: case FFA_FN64_MSG_SEND_DIRECT_REQ: - do_ffa_direct_msg(&res, host_ctxt, HOST_FFA_ID); - goto out_handled; + do_ffa_direct_msg(host_ctxt, HOST_FFA_ID); + return true; } if (ffa_call_supported(func_id)) @@ -1273,8 +1297,8 @@ bool kvm_guest_ffa_handler(struct pkvm_hyp_vcpu *hyp_vcpu, u64 *exit_code) goto out_guest; case FFA_MSG_SEND_DIRECT_REQ: case FFA_FN64_MSG_SEND_DIRECT_REQ: - do_ffa_direct_msg(&res, ctxt, hyp_vcpu_to_ffa_handle(hyp_vcpu)); - goto out_guest; + do_ffa_direct_msg(ctxt, hyp_vcpu_to_ffa_handle(hyp_vcpu)); + return true; default: ret = -EOPNOTSUPP; break;