Skip to content

Commit fa3b3e4

Browse files
ankita-nvgregkh
authored andcommitted
vfio: refactor vfio_pci_mmap_huge_fault function
[ Upstream commit 9b92bc7 ] Refactor vfio_pci_mmap_huge_fault to take out the implementation to map the VMA to the PTE/PMD/PUD as a separate function. Export the new function to be used by nvgrace-gpu module. Move the alignment check code to verify that pfn and VMA VA is aligned to the page order to the header file and make it inline. No functional change is intended. Cc: Shameer Kolothum <skolothumtho@nvidia.com> Cc: Alex Williamson <alex@shazbot.org> Cc: Jason Gunthorpe <jgg@ziepe.ca> Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com> Signed-off-by: Ankit Agrawal <ankita@nvidia.com> Link: https://lore.kernel.org/r/20251127170632.3477-2-ankita@nvidia.com Signed-off-by: Alex Williamson <alex@shazbot.org> Stable-dep-of: 948b71a ("drivers/vfio_pci_core: Change PXD_ORDER check from switch case to if/else block") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 6b96947 commit fa3b3e4

2 files changed

Lines changed: 40 additions & 27 deletions

File tree

drivers/vfio/pci/vfio_pci_core.c

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,49 +1677,49 @@ static unsigned long vma_to_pfn(struct vm_area_struct *vma)
16771677
return (pci_resource_start(vdev->pdev, index) >> PAGE_SHIFT) + pgoff;
16781678
}
16791679

1680-
static vm_fault_t vfio_pci_mmap_huge_fault(struct vm_fault *vmf,
1681-
unsigned int order)
1680+
vm_fault_t vfio_pci_vmf_insert_pfn(struct vfio_pci_core_device *vdev,
1681+
struct vm_fault *vmf,
1682+
unsigned long pfn,
1683+
unsigned int order)
16821684
{
1683-
struct vm_area_struct *vma = vmf->vma;
1684-
struct vfio_pci_core_device *vdev = vma->vm_private_data;
1685-
unsigned long addr = vmf->address & ~((PAGE_SIZE << order) - 1);
1686-
unsigned long pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
1687-
unsigned long pfn = vma_to_pfn(vma) + pgoff;
1688-
vm_fault_t ret = VM_FAULT_SIGBUS;
1689-
1690-
if (order && (addr < vma->vm_start ||
1691-
addr + (PAGE_SIZE << order) > vma->vm_end ||
1692-
pfn & ((1 << order) - 1))) {
1693-
ret = VM_FAULT_FALLBACK;
1694-
goto out;
1695-
}
1696-
1697-
down_read(&vdev->memory_lock);
1685+
lockdep_assert_held_read(&vdev->memory_lock);
16981686

16991687
if (vdev->pm_runtime_engaged || !__vfio_pci_memory_enabled(vdev))
1700-
goto out_unlock;
1688+
return VM_FAULT_SIGBUS;
17011689

17021690
switch (order) {
17031691
case 0:
1704-
ret = vmf_insert_pfn(vma, vmf->address, pfn);
1705-
break;
1692+
return vmf_insert_pfn(vmf->vma, vmf->address, pfn);
17061693
#ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
17071694
case PMD_ORDER:
1708-
ret = vmf_insert_pfn_pmd(vmf, pfn, false);
1709-
break;
1695+
return vmf_insert_pfn_pmd(vmf, pfn, false);
17101696
#endif
17111697
#ifdef CONFIG_ARCH_SUPPORTS_PUD_PFNMAP
17121698
case PUD_ORDER:
1713-
ret = vmf_insert_pfn_pud(vmf, pfn, false);
1699+
return vmf_insert_pfn_pud(vmf, pfn, false);
17141700
break;
17151701
#endif
17161702
default:
1717-
ret = VM_FAULT_FALLBACK;
1703+
return VM_FAULT_FALLBACK;
1704+
}
1705+
}
1706+
EXPORT_SYMBOL_GPL(vfio_pci_vmf_insert_pfn);
1707+
1708+
static vm_fault_t vfio_pci_mmap_huge_fault(struct vm_fault *vmf,
1709+
unsigned int order)
1710+
{
1711+
struct vm_area_struct *vma = vmf->vma;
1712+
struct vfio_pci_core_device *vdev = vma->vm_private_data;
1713+
unsigned long addr = vmf->address & ~((PAGE_SIZE << order) - 1);
1714+
unsigned long pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
1715+
unsigned long pfn = vma_to_pfn(vma) + pgoff;
1716+
vm_fault_t ret = VM_FAULT_FALLBACK;
1717+
1718+
if (is_aligned_for_order(vma, addr, pfn, order)) {
1719+
scoped_guard(rwsem_read, &vdev->memory_lock)
1720+
ret = vfio_pci_vmf_insert_pfn(vdev, vmf, pfn, order);
17181721
}
17191722

1720-
out_unlock:
1721-
up_read(&vdev->memory_lock);
1722-
out:
17231723
dev_dbg_ratelimited(&vdev->pdev->dev,
17241724
"%s(,order = %d) BAR %ld page offset 0x%lx: 0x%x\n",
17251725
__func__, order,

include/linux/vfio_pci_core.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ ssize_t vfio_pci_core_read(struct vfio_device *core_vdev, char __user *buf,
132132
size_t count, loff_t *ppos);
133133
ssize_t vfio_pci_core_write(struct vfio_device *core_vdev, const char __user *buf,
134134
size_t count, loff_t *ppos);
135+
vm_fault_t vfio_pci_vmf_insert_pfn(struct vfio_pci_core_device *vdev,
136+
struct vm_fault *vmf, unsigned long pfn,
137+
unsigned int order);
135138
int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma);
136139
void vfio_pci_core_request(struct vfio_device *core_vdev, unsigned int count);
137140
int vfio_pci_core_match(struct vfio_device *core_vdev, char *buf);
@@ -175,4 +178,14 @@ VFIO_IOREAD_DECLARATION(32)
175178
VFIO_IOREAD_DECLARATION(64)
176179
#endif
177180

181+
static inline bool is_aligned_for_order(struct vm_area_struct *vma,
182+
unsigned long addr,
183+
unsigned long pfn,
184+
unsigned int order)
185+
{
186+
return !(order && (addr < vma->vm_start ||
187+
addr + (PAGE_SIZE << order) > vma->vm_end ||
188+
!IS_ALIGNED(pfn, 1 << order)));
189+
}
190+
178191
#endif /* VFIO_PCI_CORE_H */

0 commit comments

Comments
 (0)