KVM: arm64: relay entropy requests from protected guests directly to secure

As pKVM does not trust the host, it should not be involved in the
handling of, or be able to observe the response to entropy requests
issues by protected guests.

Let's just assume that support for the SMC flavor of the ARM SMCCC TRNG
interface is a prerequisite for pKVM support, and pass the request on
directly to the secure firmware.

Signed-off-by: Ard Biesheuvel <ardb@google.com>
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index ff8e173..1caa441 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -16,6 +16,7 @@
 #include <linux/jump_label.h>
 #include <uapi/linux/psci.h>
 
+#include <kvm/arm_hypercalls.h>
 #include <kvm/arm_psci.h>
 
 #include <asm/barrier.h>
@@ -403,7 +404,36 @@
 
 static bool kvm_hyp_handle_hvc64(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
-	return false;
+	u32 func_id;
+	unsigned long arg1 = 0;
+
+	if (!is_protected_kvm_enabled())
+		return false;
+
+	func_id = smccc_get_function(vcpu);
+	switch (func_id) {
+		struct arm_smccc_res res;
+
+	default:
+		return false;
+
+	/*
+	 * pKVM does not trust the host, and so it should not be
+	 * involved in serving entropy requests from protected guests.
+	 * Let's just patch the call through to the secure world directly.
+	 */
+	case ARM_SMCCC_TRNG_FEATURES:
+	case ARM_SMCCC_TRNG_RND32:
+	case ARM_SMCCC_TRNG_RND64:
+		arg1 = smccc_get_arg1(vcpu);
+		fallthrough;
+	case ARM_SMCCC_TRNG_VERSION:
+	case ARM_SMCCC_TRNG_GET_UUID:
+		arm_smccc_1_1_smc(func_id, arg1, &res);
+		smccc_set_retval(vcpu, res.a0, res.a1, res.a2, res.a3);
+		break;
+	}
+	return true;
 }
 
 typedef bool (*exit_handler_fn)(struct kvm_vcpu *, u64 *);