1*e907ae53SClaudio Imbrenda // SPDX-License-Identifier: GPL-2.0 2*e907ae53SClaudio Imbrenda /* 3*e907ae53SClaudio Imbrenda * KVM guest fault handling. 4*e907ae53SClaudio Imbrenda * 5*e907ae53SClaudio Imbrenda * Copyright IBM Corp. 2025 6*e907ae53SClaudio Imbrenda * Author(s): Claudio Imbrenda <imbrenda@linux.ibm.com> 7*e907ae53SClaudio Imbrenda */ 8*e907ae53SClaudio Imbrenda #include <linux/kvm_types.h> 9*e907ae53SClaudio Imbrenda #include <linux/kvm_host.h> 10*e907ae53SClaudio Imbrenda 11*e907ae53SClaudio Imbrenda #include "gmap.h" 12*e907ae53SClaudio Imbrenda #include "trace.h" 13*e907ae53SClaudio Imbrenda #include "faultin.h" 14*e907ae53SClaudio Imbrenda 15*e907ae53SClaudio Imbrenda bool kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu); 16*e907ae53SClaudio Imbrenda 17*e907ae53SClaudio Imbrenda /* 18*e907ae53SClaudio Imbrenda * kvm_s390_faultin_gfn() - handle a dat fault. 19*e907ae53SClaudio Imbrenda * @vcpu: The vCPU whose gmap is to be fixed up, or NULL if operating on the VM. 20*e907ae53SClaudio Imbrenda * @kvm: The VM whose gmap is to be fixed up, or NULL if operating on a vCPU. 21*e907ae53SClaudio Imbrenda * @f: The guest fault that needs to be resolved. 22*e907ae53SClaudio Imbrenda * 23*e907ae53SClaudio Imbrenda * Return: 24*e907ae53SClaudio Imbrenda * * 0 on success 25*e907ae53SClaudio Imbrenda * * < 0 in case of error 26*e907ae53SClaudio Imbrenda * * > 0 in case of guest exceptions 27*e907ae53SClaudio Imbrenda * 28*e907ae53SClaudio Imbrenda * Context: 29*e907ae53SClaudio Imbrenda * * The mm lock must not be held before calling 30*e907ae53SClaudio Imbrenda * * kvm->srcu must be held 31*e907ae53SClaudio Imbrenda * * may sleep 32*e907ae53SClaudio Imbrenda */ 33*e907ae53SClaudio Imbrenda int kvm_s390_faultin_gfn(struct kvm_vcpu *vcpu, struct kvm *kvm, struct guest_fault *f) 34*e907ae53SClaudio Imbrenda { 35*e907ae53SClaudio Imbrenda struct kvm_s390_mmu_cache *local_mc __free(kvm_s390_mmu_cache) = NULL; 36*e907ae53SClaudio Imbrenda struct kvm_s390_mmu_cache *mc = NULL; 37*e907ae53SClaudio Imbrenda struct kvm_memory_slot *slot; 38*e907ae53SClaudio Imbrenda unsigned long inv_seq; 39*e907ae53SClaudio Imbrenda int foll, rc = 0; 40*e907ae53SClaudio Imbrenda 41*e907ae53SClaudio Imbrenda foll = f->write_attempt ? FOLL_WRITE : 0; 42*e907ae53SClaudio Imbrenda foll |= f->attempt_pfault ? FOLL_NOWAIT : 0; 43*e907ae53SClaudio Imbrenda 44*e907ae53SClaudio Imbrenda if (vcpu) { 45*e907ae53SClaudio Imbrenda kvm = vcpu->kvm; 46*e907ae53SClaudio Imbrenda mc = vcpu->arch.mc; 47*e907ae53SClaudio Imbrenda } 48*e907ae53SClaudio Imbrenda 49*e907ae53SClaudio Imbrenda lockdep_assert_held(&kvm->srcu); 50*e907ae53SClaudio Imbrenda 51*e907ae53SClaudio Imbrenda scoped_guard(read_lock, &kvm->mmu_lock) { 52*e907ae53SClaudio Imbrenda if (gmap_try_fixup_minor(kvm->arch.gmap, f) == 0) 53*e907ae53SClaudio Imbrenda return 0; 54*e907ae53SClaudio Imbrenda } 55*e907ae53SClaudio Imbrenda 56*e907ae53SClaudio Imbrenda while (1) { 57*e907ae53SClaudio Imbrenda f->valid = false; 58*e907ae53SClaudio Imbrenda inv_seq = kvm->mmu_invalidate_seq; 59*e907ae53SClaudio Imbrenda /* Pairs with the smp_wmb() in kvm_mmu_invalidate_end(). */ 60*e907ae53SClaudio Imbrenda smp_rmb(); 61*e907ae53SClaudio Imbrenda 62*e907ae53SClaudio Imbrenda if (vcpu) 63*e907ae53SClaudio Imbrenda slot = kvm_vcpu_gfn_to_memslot(vcpu, f->gfn); 64*e907ae53SClaudio Imbrenda else 65*e907ae53SClaudio Imbrenda slot = gfn_to_memslot(kvm, f->gfn); 66*e907ae53SClaudio Imbrenda f->pfn = __kvm_faultin_pfn(slot, f->gfn, foll, &f->writable, &f->page); 67*e907ae53SClaudio Imbrenda 68*e907ae53SClaudio Imbrenda /* Needs I/O, try to setup async pfault (only possible with FOLL_NOWAIT). */ 69*e907ae53SClaudio Imbrenda if (f->pfn == KVM_PFN_ERR_NEEDS_IO) { 70*e907ae53SClaudio Imbrenda if (unlikely(!f->attempt_pfault)) 71*e907ae53SClaudio Imbrenda return -EAGAIN; 72*e907ae53SClaudio Imbrenda if (unlikely(!vcpu)) 73*e907ae53SClaudio Imbrenda return -EINVAL; 74*e907ae53SClaudio Imbrenda trace_kvm_s390_major_guest_pfault(vcpu); 75*e907ae53SClaudio Imbrenda if (kvm_arch_setup_async_pf(vcpu)) 76*e907ae53SClaudio Imbrenda return 0; 77*e907ae53SClaudio Imbrenda vcpu->stat.pfault_sync++; 78*e907ae53SClaudio Imbrenda /* Could not setup async pfault, try again synchronously. */ 79*e907ae53SClaudio Imbrenda foll &= ~FOLL_NOWAIT; 80*e907ae53SClaudio Imbrenda f->pfn = __kvm_faultin_pfn(slot, f->gfn, foll, &f->writable, &f->page); 81*e907ae53SClaudio Imbrenda } 82*e907ae53SClaudio Imbrenda 83*e907ae53SClaudio Imbrenda /* Access outside memory, addressing exception. */ 84*e907ae53SClaudio Imbrenda if (is_noslot_pfn(f->pfn)) 85*e907ae53SClaudio Imbrenda return PGM_ADDRESSING; 86*e907ae53SClaudio Imbrenda /* Signal pending: try again. */ 87*e907ae53SClaudio Imbrenda if (f->pfn == KVM_PFN_ERR_SIGPENDING) 88*e907ae53SClaudio Imbrenda return -EAGAIN; 89*e907ae53SClaudio Imbrenda /* Check if it's read-only memory; don't try to actually handle that case. */ 90*e907ae53SClaudio Imbrenda if (f->pfn == KVM_PFN_ERR_RO_FAULT) 91*e907ae53SClaudio Imbrenda return -EOPNOTSUPP; 92*e907ae53SClaudio Imbrenda /* Any other error. */ 93*e907ae53SClaudio Imbrenda if (is_error_pfn(f->pfn)) 94*e907ae53SClaudio Imbrenda return -EFAULT; 95*e907ae53SClaudio Imbrenda 96*e907ae53SClaudio Imbrenda if (!mc) { 97*e907ae53SClaudio Imbrenda local_mc = kvm_s390_new_mmu_cache(); 98*e907ae53SClaudio Imbrenda if (!local_mc) 99*e907ae53SClaudio Imbrenda return -ENOMEM; 100*e907ae53SClaudio Imbrenda mc = local_mc; 101*e907ae53SClaudio Imbrenda } 102*e907ae53SClaudio Imbrenda 103*e907ae53SClaudio Imbrenda /* Loop, will automatically release the faulted page. */ 104*e907ae53SClaudio Imbrenda if (mmu_invalidate_retry_gfn_unsafe(kvm, inv_seq, f->gfn)) { 105*e907ae53SClaudio Imbrenda kvm_release_faultin_page(kvm, f->page, true, false); 106*e907ae53SClaudio Imbrenda continue; 107*e907ae53SClaudio Imbrenda } 108*e907ae53SClaudio Imbrenda 109*e907ae53SClaudio Imbrenda scoped_guard(read_lock, &kvm->mmu_lock) { 110*e907ae53SClaudio Imbrenda if (!mmu_invalidate_retry_gfn(kvm, inv_seq, f->gfn)) { 111*e907ae53SClaudio Imbrenda f->valid = true; 112*e907ae53SClaudio Imbrenda rc = gmap_link(mc, kvm->arch.gmap, f); 113*e907ae53SClaudio Imbrenda kvm_release_faultin_page(kvm, f->page, !!rc, f->write_attempt); 114*e907ae53SClaudio Imbrenda f->page = NULL; 115*e907ae53SClaudio Imbrenda } 116*e907ae53SClaudio Imbrenda } 117*e907ae53SClaudio Imbrenda kvm_release_faultin_page(kvm, f->page, true, false); 118*e907ae53SClaudio Imbrenda 119*e907ae53SClaudio Imbrenda if (rc == -ENOMEM) { 120*e907ae53SClaudio Imbrenda rc = kvm_s390_mmu_cache_topup(mc); 121*e907ae53SClaudio Imbrenda if (rc) 122*e907ae53SClaudio Imbrenda return rc; 123*e907ae53SClaudio Imbrenda } else if (rc != -EAGAIN) { 124*e907ae53SClaudio Imbrenda return rc; 125*e907ae53SClaudio Imbrenda } 126*e907ae53SClaudio Imbrenda } 127*e907ae53SClaudio Imbrenda } 128*e907ae53SClaudio Imbrenda 129*e907ae53SClaudio Imbrenda int kvm_s390_get_guest_page(struct kvm *kvm, struct guest_fault *f, gfn_t gfn, bool w) 130*e907ae53SClaudio Imbrenda { 131*e907ae53SClaudio Imbrenda struct kvm_memory_slot *slot = gfn_to_memslot(kvm, gfn); 132*e907ae53SClaudio Imbrenda int foll = w ? FOLL_WRITE : 0; 133*e907ae53SClaudio Imbrenda 134*e907ae53SClaudio Imbrenda f->write_attempt = w; 135*e907ae53SClaudio Imbrenda f->gfn = gfn; 136*e907ae53SClaudio Imbrenda f->pfn = __kvm_faultin_pfn(slot, gfn, foll, &f->writable, &f->page); 137*e907ae53SClaudio Imbrenda if (is_noslot_pfn(f->pfn)) 138*e907ae53SClaudio Imbrenda return PGM_ADDRESSING; 139*e907ae53SClaudio Imbrenda if (is_sigpending_pfn(f->pfn)) 140*e907ae53SClaudio Imbrenda return -EINTR; 141*e907ae53SClaudio Imbrenda if (f->pfn == KVM_PFN_ERR_NEEDS_IO) 142*e907ae53SClaudio Imbrenda return -EAGAIN; 143*e907ae53SClaudio Imbrenda if (is_error_pfn(f->pfn)) 144*e907ae53SClaudio Imbrenda return -EFAULT; 145*e907ae53SClaudio Imbrenda 146*e907ae53SClaudio Imbrenda f->valid = true; 147*e907ae53SClaudio Imbrenda return 0; 148*e907ae53SClaudio Imbrenda } 149