KVM: arm64: Probe FF-A version and host/hyp partition ID during init
authorWill Deacon <will@kernel.org>
Tue, 23 May 2023 10:18:19 +0000 (11:18 +0100)
committerOliver Upton <oliver.upton@linux.dev>
Thu, 1 Jun 2023 21:34:50 +0000 (21:34 +0000)
Probe FF-A during pKVM initialisation so that we can detect any
inconsistencies in the version or partition ID early on.

Signed-off-by: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20230523101828.7328-3-will@kernel.org
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
arch/arm64/include/asm/kvm_host.h
arch/arm64/kvm/arm.c
arch/arm64/kvm/hyp/include/nvhe/ffa.h
arch/arm64/kvm/hyp/nvhe/ffa.c
arch/arm64/kvm/hyp/nvhe/setup.c

index 7e7e19e..396e68c 100644 (file)
@@ -405,6 +405,7 @@ struct kvm_host_data {
 struct kvm_host_psci_config {
        /* PSCI version used by host. */
        u32 version;
+       u32 smccc_version;
 
        /* Function IDs used by host if version is v0.1. */
        struct psci_0_1_function_ids function_ids_0_1;
index 1439182..4139569 100644 (file)
@@ -1910,6 +1910,7 @@ static bool __init init_psci_relay(void)
        }
 
        kvm_host_psci_config.version = psci_ops.get_version();
+       kvm_host_psci_config.smccc_version = arm_smccc_get_version();
 
        if (kvm_host_psci_config.version == PSCI_VERSION(0, 1)) {
                kvm_host_psci_config.function_ids_0_1 = get_psci_0_1_function_ids();
index fc09ec6..5c9b924 100644 (file)
@@ -11,6 +11,7 @@
 #define FFA_MIN_FUNC_NUM 0x60
 #define FFA_MAX_FUNC_NUM 0x7F
 
+int hyp_ffa_init(void);
 bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt);
 
 #endif /* __KVM_HYP_FFA_H */
index 3028069..abdcaf9 100644 (file)
 #include <nvhe/ffa.h>
 #include <nvhe/trap_handler.h>
 
+/*
+ * "ID value 0 must be returned at the Non-secure physical FF-A instance"
+ * We share this ID with the host.
+ */
+#define HOST_FFA_ID    0
+
 static void ffa_to_smccc_error(struct arm_smccc_res *res, u64 ffa_errno)
 {
        *res = (struct arm_smccc_res) {
@@ -117,3 +123,27 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt)
        ffa_set_retval(host_ctxt, &res);
        return true;
 }
+
+int hyp_ffa_init(void)
+{
+       struct arm_smccc_res res;
+
+       if (kvm_host_psci_config.smccc_version < ARM_SMCCC_VERSION_1_2)
+               return 0;
+
+       arm_smccc_1_1_smc(FFA_VERSION, FFA_VERSION_1_0, 0, 0, 0, 0, 0, 0, &res);
+       if (res.a0 == FFA_RET_NOT_SUPPORTED)
+               return 0;
+
+       if (res.a0 != FFA_VERSION_1_0)
+               return -EOPNOTSUPP;
+
+       arm_smccc_1_1_smc(FFA_ID_GET, 0, 0, 0, 0, 0, 0, 0, &res);
+       if (res.a0 != FFA_SUCCESS)
+               return -EOPNOTSUPP;
+
+       if (res.a2 != HOST_FFA_ID)
+               return -EINVAL;
+
+       return 0;
+}
index 110f046..c4ca174 100644 (file)
@@ -11,6 +11,7 @@
 #include <asm/kvm_pkvm.h>
 
 #include <nvhe/early_alloc.h>
+#include <nvhe/ffa.h>
 #include <nvhe/fixed_config.h>
 #include <nvhe/gfp.h>
 #include <nvhe/memory.h>
@@ -314,6 +315,10 @@ void __noreturn __pkvm_init_finalise(void)
        if (ret)
                goto out;
 
+       ret = hyp_ffa_init();
+       if (ret)
+               goto out;
+
        pkvm_hyp_vm_table_init(vm_table_base);
 out:
        /*