mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
KVM: arm64: Decouple hyp VM creation state from its handle
Currently, the presence of a pKVM handle (pkvm.handle != 0) is used to determine if the corresponding hypervisor (EL2) VM has been created and initialized. This couples the handle's lifecycle with the VM's creation state. This coupling will become problematic with upcoming changes that will allocate the pKVM handle earlier in the VM's life, before the VM is instantiated at the hypervisor. To prepare for this and make the state tracking explicit, decouple the two concepts. Introduce a new boolean flag, 'pkvm.is_created', to track whether the hypervisor-side VM has been created and initialized. A new helper, pkvm_hyp_vm_is_created(), is added to check this flag. All call sites that previously checked for the handle's existence are converted to use the new, explicit check. The 'is_created' flag is set to true upon successful creation in the hypervisor (EL2) and cleared upon destruction. Signed-off-by: Fuad Tabba <tabba@google.com> Tested-by: Mark Brown <broonie@kernel.org> Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
parent
070362648f
commit
3c45b67625
|
|
@ -253,6 +253,7 @@ struct kvm_protected_vm {
|
|||
struct kvm_hyp_memcache teardown_mc;
|
||||
struct kvm_hyp_memcache stage2_teardown_mc;
|
||||
bool is_protected;
|
||||
bool is_created;
|
||||
};
|
||||
|
||||
struct kvm_mpidr_data {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
int pkvm_init_host_vm(struct kvm *kvm);
|
||||
int pkvm_create_hyp_vm(struct kvm *kvm);
|
||||
bool pkvm_hyp_vm_is_created(struct kvm *kvm);
|
||||
void pkvm_destroy_hyp_vm(struct kvm *kvm);
|
||||
int pkvm_create_hyp_vcpu(struct kvm_vcpu *vcpu);
|
||||
|
||||
|
|
|
|||
|
|
@ -407,6 +407,7 @@ static void init_pkvm_hyp_vm(struct kvm *host_kvm, struct pkvm_hyp_vm *hyp_vm,
|
|||
hyp_vm->kvm.created_vcpus = nr_vcpus;
|
||||
hyp_vm->kvm.arch.mmu.vtcr = host_mmu.arch.mmu.vtcr;
|
||||
hyp_vm->kvm.arch.pkvm.is_protected = READ_ONCE(host_kvm->arch.pkvm.is_protected);
|
||||
hyp_vm->kvm.arch.pkvm.is_created = true;
|
||||
hyp_vm->kvm.arch.flags = 0;
|
||||
pkvm_init_features_from_host(hyp_vm, host_kvm);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,12 +87,13 @@ void __init kvm_hyp_reserve(void)
|
|||
|
||||
static void __pkvm_destroy_hyp_vm(struct kvm *kvm)
|
||||
{
|
||||
if (kvm->arch.pkvm.handle) {
|
||||
if (pkvm_hyp_vm_is_created(kvm)) {
|
||||
WARN_ON(kvm_call_hyp_nvhe(__pkvm_teardown_vm,
|
||||
kvm->arch.pkvm.handle));
|
||||
}
|
||||
|
||||
kvm->arch.pkvm.handle = 0;
|
||||
kvm->arch.pkvm.is_created = false;
|
||||
free_hyp_memcache(&kvm->arch.pkvm.teardown_mc);
|
||||
free_hyp_memcache(&kvm->arch.pkvm.stage2_teardown_mc);
|
||||
}
|
||||
|
|
@ -165,6 +166,7 @@ static int __pkvm_create_hyp_vm(struct kvm *kvm)
|
|||
goto free_vm;
|
||||
|
||||
kvm->arch.pkvm.handle = ret;
|
||||
kvm->arch.pkvm.is_created = true;
|
||||
kvm->arch.pkvm.stage2_teardown_mc.flags |= HYP_MEMCACHE_ACCOUNT_STAGE2;
|
||||
kvm_account_pgtable_pages(pgd, pgd_sz / PAGE_SIZE);
|
||||
|
||||
|
|
@ -176,12 +178,17 @@ static int __pkvm_create_hyp_vm(struct kvm *kvm)
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool pkvm_hyp_vm_is_created(struct kvm *kvm)
|
||||
{
|
||||
return READ_ONCE(kvm->arch.pkvm.is_created);
|
||||
}
|
||||
|
||||
int pkvm_create_hyp_vm(struct kvm *kvm)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&kvm->arch.config_lock);
|
||||
if (!kvm->arch.pkvm.handle)
|
||||
if (!pkvm_hyp_vm_is_created(kvm))
|
||||
ret = __pkvm_create_hyp_vm(kvm);
|
||||
mutex_unlock(&kvm->arch.config_lock);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user