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)