[RFC PATCH 1/3] arm64: KVM: defer kvm_init() to finalise_pkvm() when pKVM is enabled

Yeoreum Yun <[email protected]>
Newsgroups org.kernel.vger.linux-integrity,dev.linux.lists.kvmarm,org.infradead.lists.linux-arm-kernel,org.kernel.vger.keyrings,org.kernel.vger.linux-kernel,org.kernel.vger.linux-security-module
Message-ID <[email protected]>
This patch is a preparatory change to address dependency issues
between the FF-A driver and pKVM.

kvm_init() should be invoked from finalise_pkvm(),
as this is the point where pKVM initialisation is finalised and
the system transitions into the protected mode.

Deferring kvm_init() ensures that KVM is initialised only after pKVM has
fully established its protected environment.

Signed-off-by: Yeoreum Yun <[email protected]>
---
 arch/arm64/kvm/arm.c  |  8 +++++---
 arch/arm64/kvm/pkvm.c | 15 ++++++++++++++-
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 8bb2c7422cc8..663b1d447a9b 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -3025,9 +3025,11 @@ static __init int kvm_arm_init(void)
 	 * FIXME: Do something reasonable if kvm_init() fails after pKVM
 	 * hypervisor protection is finalized.
 	 */
-	err = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
-	if (err)
-		goto out_subs;
+	if (!is_protected_kvm_enabled()) {
+		err = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
+		if (err)
+			goto out_subs;
+	}
 
 	/*
 	 * This should be called after initialization is done and failure isn't
diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
index 053e4f733e4b..48b06d384570 100644
--- a/arch/arm64/kvm/pkvm.c
+++ b/arch/arm64/kvm/pkvm.c
@@ -17,6 +17,7 @@
 #include "hyp_constants.h"
 
 DEFINE_STATIC_KEY_FALSE(kvm_protected_mode_initialized);
+EXPORT_SYMBOL_GPL(kvm_protected_mode_initialized);
 
 static struct memblock_region *hyp_memory = kvm_nvhe_sym(hyp_memory);
 static unsigned int *hyp_memblock_nr_ptr = &kvm_nvhe_sym(hyp_memblock_nr);
@@ -289,10 +290,22 @@ static int __init finalize_pkvm(void)
 	kmemleak_free_part(__hyp_rodata_start, __hyp_rodata_end - __hyp_rodata_start);
 	kmemleak_free_part_phys(hyp_mem_base, hyp_mem_size);
 
-	ret = pkvm_drop_host_privileges();
+	ret = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
 	if (ret)
+		goto out_err;
+
+	ret = pkvm_drop_host_privileges();
+	if (ret) {
 		pr_err("Failed to finalize Hyp protection: %d\n", ret);
+		kvm_exit();
+		goto out_err;
+	}
+
+	return 0;
 
+out_err:
+	kvm_unregister_perf_callbacks();
+	kvm_arm_vmid_alloc_free();
 	return ret;
 }
 device_initcall_sync(finalize_pkvm);
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.