From e3c771734c2f9136afc06210cba9a18f6529068b Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 7 Jul 2022 15:51:28 +0100 Subject: [PATCH] Revert "ANDROID: KVM: arm64: Refcount shadow structs on vcpu_{load/put}()" This reverts commit 6f93dc7bb931a035aec8e9ed697f47990f7c5caf. Bug: 233587962 Signed-off-by: Will Deacon Change-Id: I5d6f272349a30363081dd10962a04600c6191030 --- arch/arm64/kvm/hyp/include/nvhe/pkvm.h | 3 +- arch/arm64/kvm/hyp/nvhe/hyp-main.c | 6 +-- arch/arm64/kvm/hyp/nvhe/pkvm.c | 53 +++++++++----------------- 3 files changed, 20 insertions(+), 42 deletions(-) diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h index 30922f99e2f8..c1c0d79cbac5 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h +++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h @@ -53,8 +53,7 @@ extern struct kvm_shadow_vm **shadow_table; int __pkvm_init_shadow(struct kvm *kvm, void *shadow_va, size_t size, void *pgd); int __pkvm_teardown_shadow(struct kvm *kvm); -struct kvm_vcpu *get_shadow_vcpu(int shadow_handle, int vcpu_idx); -void put_shadow_vcpu(struct kvm_vcpu *vcpu); +struct kvm_vcpu *hyp_get_shadow_vcpu(const struct kvm_vcpu *host_vcpu); u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id); bool kvm_handle_pvm_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code); diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index 59f289f708f4..8e43c96470de 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -501,7 +501,6 @@ static void handle___pkvm_vcpu_load(struct kvm_cpu_context *host_ctxt) { DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1); struct pkvm_loaded_state *state; - int handle; /* Why did you bother? */ if (!is_protected_kvm_enabled()) @@ -515,8 +514,7 @@ static void handle___pkvm_vcpu_load(struct kvm_cpu_context *host_ctxt) vcpu = kern_hyp_va(vcpu); - handle = vcpu->arch.pkvm.shadow_handle; - state->vcpu = get_shadow_vcpu(handle, vcpu->vcpu_idx) ?: vcpu; + state->vcpu = hyp_get_shadow_vcpu(vcpu) ?: vcpu; state->is_shadow = state->vcpu != vcpu; if (state->is_shadow) { @@ -542,8 +540,6 @@ static void handle___pkvm_vcpu_put(struct kvm_cpu_context *host_ctxt) if (state->vcpu->arch.flags & KVM_ARM64_FP_ENABLED) fpsimd_host_restore(); - put_shadow_vcpu(state->vcpu); - /* "It's over and done with..." */ state->vcpu = NULL; } diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index c77baf1c8347..465283b9e29a 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -254,30 +254,27 @@ static struct kvm_shadow_vm *find_shadow_by_handle(int shadow_handle) return shadow_table[shadow_index]; } -struct kvm_vcpu *get_shadow_vcpu(int shadow_handle, int vcpu_idx) +/* + * Returns the hyp shadow vcpu for the corresponding host vcpu, + * or NULL if it fails. + */ +struct kvm_vcpu *hyp_get_shadow_vcpu(const struct kvm_vcpu *vcpu) { - struct kvm_vcpu *vcpu = NULL; + struct shadow_vcpu_state *shadow_vcpu_state; struct kvm_shadow_vm *vm; + int vcpu_idx; + int shadow_handle; - hyp_spin_lock(&shadow_lock); + shadow_handle = vcpu->arch.pkvm.shadow_handle; vm = find_shadow_by_handle(shadow_handle); - if (!vm || vcpu_idx < 0 || vm->created_vcpus <= vcpu_idx) - goto unlock; - vcpu = &vm->shadow_vcpus[vcpu_idx].vcpu; - hyp_page_ref_inc(hyp_virt_to_page(vm)); -unlock: - hyp_spin_unlock(&shadow_lock); + vcpu_idx = vcpu->vcpu_idx; - return vcpu; -} + if (unlikely(!vm || vcpu_idx < 0 || vcpu_idx >= vm->created_vcpus)) + return NULL; -void put_shadow_vcpu(struct kvm_vcpu *vcpu) -{ - struct kvm_shadow_vm *vm = vcpu->arch.pkvm.shadow_vm; + shadow_vcpu_state = &vm->shadow_vcpus[vcpu_idx]; - hyp_spin_lock(&shadow_lock); - hyp_page_ref_dec(hyp_virt_to_page(vm)); - hyp_spin_unlock(&shadow_lock); + return &shadow_vcpu_state->vcpu; } /* Check and copy the supported features for the vcpu from the host. */ @@ -595,7 +592,7 @@ int __pkvm_teardown_shadow(struct kvm *kvm) struct kvm_shadow_vm *vm; struct kvm *host_kvm; size_t shadow_size; - int err, shadow_handle; + int shadow_handle; u64 pfn; u64 nr_pages; void *addr; @@ -605,20 +602,11 @@ int __pkvm_teardown_shadow(struct kvm *kvm) shadow_handle = kvm->arch.pkvm.shadow_handle; /* Lookup then remove entry from the shadow table. */ - hyp_spin_lock(&shadow_lock); vm = find_shadow_by_handle(shadow_handle); - if (!vm) { - err = -ENOENT; - goto err_unlock; - } + if (!vm) + return -ENOENT; - if (WARN_ON(hyp_page_count(vm))) { - err = -EBUSY; - goto err_unlock; - } - - __remove_shadow_table(shadow_handle); - hyp_spin_unlock(&shadow_lock); + shadow_size = vm->shadow_area_size; /* Reclaim guest pages, and page-table pages */ mc = &vm->host_kvm->arch.pkvm.teardown_mc; @@ -627,7 +615,6 @@ int __pkvm_teardown_shadow(struct kvm *kvm) unpin_host_vcpus(vm); /* Push the metadata pages to the teardown memcache */ - shadow_size = vm->shadow_area_size; host_kvm = vm->host_kvm; memset(vm, 0, shadow_size); for (addr = vm; addr < ((void *)vm + shadow_size); addr += PAGE_SIZE) @@ -638,10 +625,6 @@ int __pkvm_teardown_shadow(struct kvm *kvm) nr_pages = shadow_size >> PAGE_SHIFT; WARN_ON(__pkvm_hyp_donate_host(pfn, nr_pages)); return 0; - -err_unlock: - hyp_spin_unlock(&shadow_lock); - return err; } /*