]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm: pass VMA instead of MM to follow_pte()
authorDavid Hildenbrand <david@redhat.com>
Wed, 10 Apr 2024 15:55:26 +0000 (17:55 +0200)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 6 May 2024 00:53:27 +0000 (17:53 -0700)
... and centralize the VM_IO/VM_PFNMAP sanity check in there. We'll
now also perform these sanity checks for direct follow_pte()
invocations.

For generic_access_phys(), we might now check multiple times: nothing to
worry about, really.

Link: https://lkml.kernel.org/r/20240410155527.474777-3-david@redhat.com
Signed-off-by: David Hildenbrand <david@redhat.com>
Acked-by: Sean Christopherson <seanjc@google.com> [KVM]
Cc: Alex Williamson <alex.williamson@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Fei Li <fei1.li@intel.com>
Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Yonghua Huang <yonghua.huang@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
arch/s390/pci/pci_mmio.c
arch/x86/mm/pat/memtype.c
drivers/vfio/vfio_iommu_type1.c
drivers/virt/acrn/mm.c
include/linux/mm.h
mm/memory.c
virt/kvm/kvm_main.c

index a90499c087f0c5e917c1f36072f56c0979951d1a..5398729bfe1b77ac1db2d742b5b4d4955b5e1aaf 100644 (file)
@@ -169,7 +169,7 @@ SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr,
        if (!(vma->vm_flags & VM_WRITE))
                goto out_unlock_mmap;
 
-       ret = follow_pte(vma->vm_mm, mmio_addr, &ptep, &ptl);
+       ret = follow_pte(vma, mmio_addr, &ptep, &ptl);
        if (ret)
                goto out_unlock_mmap;
 
@@ -308,7 +308,7 @@ SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr,
        if (!(vma->vm_flags & VM_WRITE))
                goto out_unlock_mmap;
 
-       ret = follow_pte(vma->vm_mm, mmio_addr, &ptep, &ptl);
+       ret = follow_pte(vma, mmio_addr, &ptep, &ptl);
        if (ret)
                goto out_unlock_mmap;
 
index d01c3b0bd6eb1cf2f33dc60d6e0e5ec5127ee863..bdc2a240c2aae67e253565636fe279fdea93e907 100644 (file)
@@ -954,10 +954,7 @@ static int follow_phys(struct vm_area_struct *vma, unsigned long *prot,
        pte_t *ptep, pte;
        spinlock_t *ptl;
 
-       if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
-               return -EINVAL;
-
-       if (follow_pte(vma->vm_mm, vma->vm_start, &ptep, &ptl))
+       if (follow_pte(vma, vma->vm_start, &ptep, &ptl))
                return -EINVAL;
 
        pte = ptep_get(ptep);
index b5c15fe8f9fcf91911dcb391031713e517588297..3a0218171cfaa059e8e55b9f108536b30fb934e8 100644 (file)
@@ -518,7 +518,7 @@ static int follow_fault_pfn(struct vm_area_struct *vma, struct mm_struct *mm,
        spinlock_t *ptl;
        int ret;
 
-       ret = follow_pte(vma->vm_mm, vaddr, &ptep, &ptl);
+       ret = follow_pte(vma, vaddr, &ptep, &ptl);
        if (ret) {
                bool unlocked = false;
 
@@ -532,7 +532,7 @@ static int follow_fault_pfn(struct vm_area_struct *vma, struct mm_struct *mm,
                if (ret)
                        return ret;
 
-               ret = follow_pte(vma->vm_mm, vaddr, &ptep, &ptl);
+               ret = follow_pte(vma, vaddr, &ptep, &ptl);
                if (ret)
                        return ret;
        }
index 2d98e1e185c4773cbe030ea7c9d933d9e77f9097..db8ff1d0ac23ce7630ac0623eb70be0f6dff19e4 100644 (file)
@@ -187,8 +187,7 @@ int acrn_vm_ram_map(struct acrn_vm *vm, struct acrn_vm_memmap *memmap)
                }
 
                for (i = 0; i < nr_pages; i++) {
-                       ret = follow_pte(vma->vm_mm,
-                                        memmap->vma_base + i * PAGE_SIZE,
+                       ret = follow_pte(vma, memmap->vma_base + i * PAGE_SIZE,
                                         &ptep, &ptl);
                        if (ret)
                                break;
index 0b933f9f486438db87600ebfb84be9b953131e51..c25ce69929513227648afc5d12215740aadc5a4c 100644 (file)
@@ -2420,7 +2420,7 @@ void free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
                unsigned long end, unsigned long floor, unsigned long ceiling);
 int
 copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma);
-int follow_pte(struct mm_struct *mm, unsigned long address,
+int follow_pte(struct vm_area_struct *vma, unsigned long address,
               pte_t **ptepp, spinlock_t **ptlp);
 int generic_access_phys(struct vm_area_struct *vma, unsigned long addr,
                        void *buf, int len, int write);
index 59c05dc8b18a7ad488c925873d17cb956e084e93..1d45d25c1bba182d82900434823d7817538c510f 100644 (file)
@@ -5926,7 +5926,7 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
 
 /**
  * follow_pte - look up PTE at a user virtual address
- * @mm: the mm_struct of the target address space
+ * @vma: the memory mapping
  * @address: user virtual address
  * @ptepp: location to store found PTE
  * @ptlp: location to store the lock for the PTE
@@ -5945,15 +5945,19 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
  *
  * Return: zero on success, -ve otherwise.
  */
-int follow_pte(struct mm_struct *mm, unsigned long address,
+int follow_pte(struct vm_area_struct *vma, unsigned long address,
               pte_t **ptepp, spinlock_t **ptlp)
 {
+       struct mm_struct *mm = vma->vm_mm;
        pgd_t *pgd;
        p4d_t *p4d;
        pud_t *pud;
        pmd_t *pmd;
        pte_t *ptep;
 
+       if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
+               goto out;
+
        pgd = pgd_offset(mm, address);
        if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
                goto out;
@@ -6007,11 +6011,8 @@ int generic_access_phys(struct vm_area_struct *vma, unsigned long addr,
        int offset = offset_in_page(addr);
        int ret = -EINVAL;
 
-       if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
-               return -EINVAL;
-
 retry:
-       if (follow_pte(vma->vm_mm, addr, &ptep, &ptl))
+       if (follow_pte(vma, addr, &ptep, &ptl))
                return -EINVAL;
        pte = ptep_get(ptep);
        pte_unmap_unlock(ptep, ptl);
@@ -6026,7 +6027,7 @@ retry:
        if (!maddr)
                return -ENOMEM;
 
-       if (follow_pte(vma->vm_mm, addr, &ptep, &ptl))
+       if (follow_pte(vma, addr, &ptep, &ptl))
                goto out_unmap;
 
        if (!pte_same(pte, ptep_get(ptep))) {
index fb49c2a602002ed30a5f426203fa0e30be2436b0..f57dbacb8689c930e39c8ae265cffecee3d8e163 100644 (file)
@@ -2902,7 +2902,7 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma,
        spinlock_t *ptl;
        int r;
 
-       r = follow_pte(vma->vm_mm, addr, &ptep, &ptl);
+       r = follow_pte(vma, addr, &ptep, &ptl);
        if (r) {
                /*
                 * get_user_pages fails for VM_IO and VM_PFNMAP vmas and does
@@ -2917,7 +2917,7 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma,
                if (r)
                        return r;
 
-               r = follow_pte(vma->vm_mm, addr, &ptep, &ptl);
+               r = follow_pte(vma, addr, &ptep, &ptl);
                if (r)
                        return r;
        }