ANDROID: KVM: arm64: Add FF-A trace event
Define a hypervisor trace event for FF-A smc calls. Log the function
number and the associated arguments when the hypervisor traps the FF-A smc
request coming from the host. Refactor the handling of the FF-A host smc
calls without chaning the intended behaviour.
Bug: 325404073
Change-Id: I2d448a69e4250debfeeba07beae59682bc958e02
Signed-off-by: Sebastian Ene <sebastianene@google.com>
diff --git a/arch/arm64/include/asm/kvm_hypevents.h b/arch/arm64/include/asm/kvm_hypevents.h
index 2f2b34f..30a7e86 100644
--- a/arch/arm64/include/asm/kvm_hypevents.h
+++ b/arch/arm64/include/asm/kvm_hypevents.h
@@ -92,6 +92,31 @@ HYP_EVENT(__hyp_printk,
__entry->a, __entry->b, __entry->c, __entry->d)
);
+HYP_EVENT(host_ffa_call,
+ HE_PROTO(u64 func_id, u64 res_a1, u64 res_a2, u64 res_a3, u64 res_a4, int handled, int err),
+ HE_STRUCT(
+ he_field(u64, func_id)
+ he_field(u64, res_a1)
+ he_field(u64, res_a2)
+ he_field(u64, res_a3)
+ he_field(u64, res_a4)
+ he_field(int, handled)
+ he_field(int, err)
+ ),
+ HE_ASSIGN(
+ __entry->func_id = func_id;
+ __entry->res_a1 = res_a1;
+ __entry->res_a2 = res_a2;
+ __entry->res_a3 = res_a3;
+ __entry->res_a4 = res_a4;
+ __entry->handled = handled;
+ __entry->err = err;
+ ),
+ HE_PRINTK("ffa_func=0x%llx a1=0x%llx a2=0x%llx a3=0x%llx a4=%llx handled=%d err=%d",
+ __entry->func_id, __entry->res_a1, __entry->res_a2,
+ __entry->res_a3, __entry->res_a4, __entry->handled, __entry->err)
+);
+
#ifdef CONFIG_PROTECTED_NVHE_TESTING
HYP_EVENT(selftest,
HE_PROTO(void),
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index adc35c4..7bf13f1 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -792,6 +792,13 @@ static void do_ffa_part_get(struct arm_smccc_res *res,
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_res res;
+ bool handled = true;
+ int err = 0;
+
+ DECLARE_REG(u64, arg1, host_ctxt, 1);
+ DECLARE_REG(u64, arg2, host_ctxt, 2);
+ DECLARE_REG(u64, arg3, host_ctxt, 3);
+ DECLARE_REG(u64, arg4, host_ctxt, 4);
/*
* There's no way we can tell what a non-standard SMC call might
@@ -811,50 +818,57 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
if (!has_version_negotiated && func_id != FFA_VERSION) {
ffa_to_smccc_error(&res, FFA_RET_INVALID_PARAMETERS);
- goto out_handled;
+ goto unhandled;
}
switch (func_id) {
case FFA_FEATURES:
- if (!do_ffa_features(&res, host_ctxt))
- return false;
- goto out_handled;
+ if (!do_ffa_features(&res, host_ctxt)) {
+ handled = false;
+ goto unhandled;
+ }
+ break;
/* Memory management */
case FFA_FN64_RXTX_MAP:
do_ffa_rxtx_map(&res, host_ctxt);
- goto out_handled;
+ break;
case FFA_RXTX_UNMAP:
do_ffa_rxtx_unmap(&res, host_ctxt);
- goto out_handled;
+ break;
case FFA_MEM_SHARE:
case FFA_FN64_MEM_SHARE:
do_ffa_mem_xfer(FFA_FN64_MEM_SHARE, &res, host_ctxt);
- goto out_handled;
+ break;
case FFA_MEM_RECLAIM:
do_ffa_mem_reclaim(&res, host_ctxt);
- goto out_handled;
+ break;
case FFA_MEM_LEND:
case FFA_FN64_MEM_LEND:
do_ffa_mem_xfer(FFA_FN64_MEM_LEND, &res, host_ctxt);
- goto out_handled;
+ break;
case FFA_MEM_FRAG_TX:
do_ffa_mem_frag_tx(&res, host_ctxt);
- goto out_handled;
+ break;
case FFA_VERSION:
do_ffa_version(&res, host_ctxt);
- goto out_handled;
+ break;
case FFA_PARTITION_INFO_GET:
do_ffa_part_get(&res, host_ctxt);
- goto out_handled;
+ break;
+ default:
+ if (ffa_call_supported(func_id)) {
+ handled = false;
+ goto unhandled;
+ }
+
+ ffa_to_smccc_error(&res, FFA_RET_NOT_SUPPORTED);
}
- if (ffa_call_supported(func_id))
- return false; /* Pass through */
-
- ffa_to_smccc_error(&res, FFA_RET_NOT_SUPPORTED);
-out_handled:
ffa_set_retval(host_ctxt, &res);
- return true;
+ err = res.a0 == FFA_SUCCESS ? 0 : res.a2;
+unhandled:
+ trace_host_ffa_call(func_id, arg1, arg2, arg3, arg4, handled, err);
+ return handled;
}
int hyp_ffa_init(void *pages)