]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: s390: get rid of gmap_fault()
authorClaudio Imbrenda <imbrenda@linux.ibm.com>
Thu, 23 Jan 2025 14:46:19 +0000 (15:46 +0100)
committerClaudio Imbrenda <imbrenda@linux.ibm.com>
Fri, 31 Jan 2025 11:03:52 +0000 (12:03 +0100)
All gmap page faults are already handled in kvm by the function
kvm_s390_handle_dat_fault(); only few users of gmap_fault remained, all
within kvm.

Convert those calls to use kvm_s390_handle_dat_fault() instead.

Remove gmap_fault() entirely since it has no more users.

Acked-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Link: https://lore.kernel.org/r/20250123144627.312456-8-imbrenda@linux.ibm.com
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Message-ID: <20250123144627.312456-8-imbrenda@linux.ibm.com>

arch/s390/include/asm/gmap.h
arch/s390/kvm/intercept.c
arch/s390/mm/gmap.c

index 3e66f53fe3cccff6fabce1778564bad77cd7b527..d4572729269f4fcc363a023e8449b36e277b469e 100644 (file)
@@ -113,7 +113,6 @@ int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len);
 unsigned long __gmap_translate(struct gmap *, unsigned long gaddr);
 unsigned long gmap_translate(struct gmap *, unsigned long gaddr);
 int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr);
-int gmap_fault(struct gmap *, unsigned long gaddr, unsigned int fault_flags);
 void gmap_discard(struct gmap *, unsigned long from, unsigned long to);
 void __gmap_zap(struct gmap *, unsigned long gaddr);
 void gmap_unlink(struct mm_struct *, unsigned long *table, unsigned long vmaddr);
index acf10aefd08f08e7cbdac07b1be5771be4d4ad69..610dd44a948b22945b0a35b760ded64bd44ef7cb 100644 (file)
@@ -368,7 +368,7 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
                                              reg2, &srcaddr, GACC_FETCH, 0);
        if (rc)
                return kvm_s390_inject_prog_cond(vcpu, rc);
-       rc = gmap_fault(vcpu->arch.gmap, srcaddr, 0);
+       rc = kvm_s390_handle_dat_fault(vcpu, srcaddr, 0);
        if (rc != 0)
                return rc;
 
@@ -377,7 +377,7 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
                                              reg1, &dstaddr, GACC_STORE, 0);
        if (rc)
                return kvm_s390_inject_prog_cond(vcpu, rc);
-       rc = gmap_fault(vcpu->arch.gmap, dstaddr, FAULT_FLAG_WRITE);
+       rc = kvm_s390_handle_dat_fault(vcpu, dstaddr, FOLL_WRITE);
        if (rc != 0)
                return rc;
 
index bfaba773330675f319b81af2ccdc2ff05eda9d70..e124fca1473777fbf3193089156e51addfc2de41 100644 (file)
@@ -607,130 +607,6 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr)
 }
 EXPORT_SYMBOL(__gmap_link);
 
-/**
- * fixup_user_fault_nowait - manually resolve a user page fault without waiting
- * @mm:                mm_struct of target mm
- * @address:   user address
- * @fault_flags:flags to pass down to handle_mm_fault()
- * @unlocked:  did we unlock the mmap_lock while retrying
- *
- * This function behaves similarly to fixup_user_fault(), but it guarantees
- * that the fault will be resolved without waiting. The function might drop
- * and re-acquire the mm lock, in which case @unlocked will be set to true.
- *
- * The guarantee is that the fault is handled without waiting, but the
- * function itself might sleep, due to the lock.
- *
- * Context: Needs to be called with mm->mmap_lock held in read mode, and will
- * return with the lock held in read mode; @unlocked will indicate whether
- * the lock has been dropped and re-acquired. This is the same behaviour as
- * fixup_user_fault().
- *
- * Return: 0 on success, -EAGAIN if the fault cannot be resolved without
- * waiting, -EFAULT if the fault cannot be resolved, -ENOMEM if out of
- * memory.
- */
-static int fixup_user_fault_nowait(struct mm_struct *mm, unsigned long address,
-                                  unsigned int fault_flags, bool *unlocked)
-{
-       struct vm_area_struct *vma;
-       unsigned int test_flags;
-       vm_fault_t fault;
-       int rc;
-
-       fault_flags |= FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_RETRY_NOWAIT;
-       test_flags = fault_flags & FAULT_FLAG_WRITE ? VM_WRITE : VM_READ;
-
-       vma = find_vma(mm, address);
-       if (unlikely(!vma || address < vma->vm_start))
-               return -EFAULT;
-       if (unlikely(!(vma->vm_flags & test_flags)))
-               return -EFAULT;
-
-       fault = handle_mm_fault(vma, address, fault_flags, NULL);
-       /* the mm lock has been dropped, take it again */
-       if (fault & VM_FAULT_COMPLETED) {
-               *unlocked = true;
-               mmap_read_lock(mm);
-               return 0;
-       }
-       /* the mm lock has not been dropped */
-       if (fault & VM_FAULT_ERROR) {
-               rc = vm_fault_to_errno(fault, 0);
-               BUG_ON(!rc);
-               return rc;
-       }
-       /* the mm lock has not been dropped because of FAULT_FLAG_RETRY_NOWAIT */
-       if (fault & VM_FAULT_RETRY)
-               return -EAGAIN;
-       /* nothing needed to be done and the mm lock has not been dropped */
-       return 0;
-}
-
-/**
- * __gmap_fault - resolve a fault on a guest address
- * @gmap: pointer to guest mapping meta data structure
- * @gaddr: guest address
- * @fault_flags: flags to pass down to handle_mm_fault()
- *
- * Context: Needs to be called with mm->mmap_lock held in read mode. Might
- * drop and re-acquire the lock. Will always return with the lock held.
- */
-static int __gmap_fault(struct gmap *gmap, unsigned long gaddr, unsigned int fault_flags)
-{
-       unsigned long vmaddr;
-       bool unlocked;
-       int rc = 0;
-
-retry:
-       unlocked = false;
-
-       vmaddr = __gmap_translate(gmap, gaddr);
-       if (IS_ERR_VALUE(vmaddr))
-               return vmaddr;
-
-       if (fault_flags & FAULT_FLAG_RETRY_NOWAIT)
-               rc = fixup_user_fault_nowait(gmap->mm, vmaddr, fault_flags, &unlocked);
-       else
-               rc = fixup_user_fault(gmap->mm, vmaddr, fault_flags, &unlocked);
-       if (rc)
-               return rc;
-       /*
-        * In the case that fixup_user_fault unlocked the mmap_lock during
-        * fault-in, redo __gmap_translate() to avoid racing with a
-        * map/unmap_segment.
-        * In particular, __gmap_translate(), fixup_user_fault{,_nowait}(),
-        * and __gmap_link() must all be called atomically in one go; if the
-        * lock had been dropped in between, a retry is needed.
-        */
-       if (unlocked)
-               goto retry;
-
-       return __gmap_link(gmap, gaddr, vmaddr);
-}
-
-/**
- * gmap_fault - resolve a fault on a guest address
- * @gmap: pointer to guest mapping meta data structure
- * @gaddr: guest address
- * @fault_flags: flags to pass down to handle_mm_fault()
- *
- * Returns 0 on success, -ENOMEM for out of memory conditions, -EFAULT if the
- * vm address is already mapped to a different guest segment, and -EAGAIN if
- * FAULT_FLAG_RETRY_NOWAIT was specified and the fault could not be processed
- * immediately.
- */
-int gmap_fault(struct gmap *gmap, unsigned long gaddr, unsigned int fault_flags)
-{
-       int rc;
-
-       mmap_read_lock(gmap->mm);
-       rc = __gmap_fault(gmap, gaddr, fault_flags);
-       mmap_read_unlock(gmap->mm);
-       return rc;
-}
-EXPORT_SYMBOL_GPL(gmap_fault);
-
 /*
  * this function is assumed to be called with mmap_lock held
  */