On Fri, Aug 09, 2024 at 12:09:09PM -0400, Peter Xu wrote: > @@ -1672,30 +1679,49 @@ static vm_fault_t vfio_pci_mmap_fault(struct vm_fault *vmf) > if (vdev->pm_runtime_engaged || !__vfio_pci_memory_enabled(vdev)) > goto out_unlock; > > - ret = vmf_insert_pfn(vma, vmf->address, pfn + pgoff); > - if (ret & VM_FAULT_ERROR) > - goto out_unlock; > - > - /* > - * Pre-fault the remainder of the vma, abort further insertions and > - * supress error if fault is encountered during pre-fault. > - */ > - for (; addr < vma->vm_end; addr += PAGE_SIZE, pfn++) { > - if (addr == vmf->address) > - continue; > - > - if (vmf_insert_pfn(vma, addr, pfn) & VM_FAULT_ERROR) > - break; > + switch (order) { > + case 0: > + ret = vmf_insert_pfn(vma, vmf->address, pfn + pgoff); > + break; > +#ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP > + case PMD_ORDER: > + ret = vmf_insert_pfn_pmd(vmf, __pfn_to_pfn_t(pfn + pgoff, > + PFN_DEV), false); > + break; > +#endif > +#ifdef CONFIG_ARCH_SUPPORTS_PUD_PFNMAP > + case PUD_ORDER: > + ret = vmf_insert_pfn_pud(vmf, __pfn_to_pfn_t(pfn + pgoff, > + PFN_DEV), false); > + break; > +#endif I feel like this switch should be in some general function? vmf_insert_pfn_order(vmf, order, __pfn_to_pfn_t(pfn + pgoff, PFN_DEV), false); No reason to expose every driver to this when you've already got a nice contract to have the driver work on the passed in order. What happens if the driver can't get a PFN that matches the requested order? Jason