kvm_handle_guest_abort currently just returns 1 if user_mem_abort returns 0. Since 1 is the "resume the guest" code, user_mem_abort is essentially incapable of triggering a "normal" exit: it can only trigger exits by returning a negative value, which indicates an error. Remove the "if (ret == 0) ret = 1;" statement from kvm_handle_guest_abort and refactor user_mem_abort slightly to allow it to trigger 'normal' exits by returning 0. Signed-off-by: Anish Moorthy <amoorthy@xxxxxxxxxx> --- arch/arm64/kvm/mmu.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 7113587222ffe..735044859eb25 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1190,7 +1190,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, struct kvm_memory_slot *memslot, unsigned long hva, unsigned long fault_status) { - int ret = 0; + int ret = 1; bool write_fault, writable, force_pte = false; bool exec_fault; bool device = false; @@ -1281,8 +1281,10 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, (logging_active && write_fault)) { ret = kvm_mmu_topup_memory_cache(memcache, kvm_mmu_cache_min_pages(kvm)); - if (ret) + if (ret < 0) return ret; + else + ret = 1; } mmu_seq = vcpu->kvm->mmu_invalidate_seq; @@ -1305,7 +1307,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, write_fault, &writable, NULL); if (pfn == KVM_PFN_ERR_HWPOISON) { kvm_send_hwpoison_signal(hva, vma_shift); - return 0; + return 1; } if (is_error_noslot_pfn(pfn)) return -EFAULT; @@ -1387,6 +1389,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, KVM_PGTABLE_WALK_HANDLE_FAULT | KVM_PGTABLE_WALK_SHARED); + if (ret == 0) + ret = 1; + /* Mark the page dirty only if the fault is handled successfully */ if (writable && !ret) { kvm_set_pfn_dirty(pfn); @@ -1397,7 +1402,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, read_unlock(&kvm->mmu_lock); kvm_set_pfn_accessed(pfn); kvm_release_pfn_clean(pfn); - return ret != -EAGAIN ? ret : 0; + return ret != -EAGAIN ? ret : 1; } /* Resolve the access fault by making the page young again. */ @@ -1549,8 +1554,6 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) } ret = user_mem_abort(vcpu, fault_ipa, memslot, hva, fault_status); - if (ret == 0) - ret = 1; out: if (ret == -ENOEXEC) { kvm_inject_pabt(vcpu, kvm_vcpu_get_hfar(vcpu)); -- 2.40.0.rc1.284.g88254d51c5-goog