Skip to content

Commit a19d26d

Browse files
committed
vfio/pci: Fallback huge faults for unaligned pfn
jira LE-3557 Rebuild_History Non-Buildable kernel-5.14.0-570.26.1.el9_6 commit-author Alex Williamson <[email protected]> commit 09dfc8a Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-5.14.0-570.26.1.el9_6/09dfc8a5.failed The PFN must also be aligned to the fault order to insert a huge pfnmap. Test the alignment and fallback when unaligned. Fixes: f9e54c3 ("vfio/pci: implement huge_fault support") Link: https://bugzilla.kernel.org/show_bug.cgi?id=219619 Reported-by: Athul Krishna <[email protected]> Reported-by: Precific <[email protected]> Reviewed-by: Peter Xu <[email protected]> Tested-by: Precific <[email protected]> Link: https://lore.kernel.org/r/[email protected] Cc: [email protected] Signed-off-by: Alex Williamson <[email protected]> (cherry picked from commit 09dfc8a) Signed-off-by: Jonathan Maple <[email protected]> # Conflicts: # drivers/vfio/pci/vfio_pci_core.c
1 parent 43c17b5 commit a19d26d

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
vfio/pci: Fallback huge faults for unaligned pfn
2+
3+
jira LE-3557
4+
Rebuild_History Non-Buildable kernel-5.14.0-570.26.1.el9_6
5+
commit-author Alex Williamson <[email protected]>
6+
commit 09dfc8a5f2ce897005a94bf66cca4f91e4e03700
7+
Empty-Commit: Cherry-Pick Conflicts during history rebuild.
8+
Will be included in final tarball splat. Ref for failed cherry-pick at:
9+
ciq/ciq_backports/kernel-5.14.0-570.26.1.el9_6/09dfc8a5.failed
10+
11+
The PFN must also be aligned to the fault order to insert a huge
12+
pfnmap. Test the alignment and fallback when unaligned.
13+
14+
Fixes: f9e54c3a2f5b ("vfio/pci: implement huge_fault support")
15+
Link: https://bugzilla.kernel.org/show_bug.cgi?id=219619
16+
Reported-by: Athul Krishna <[email protected]>
17+
Reported-by: Precific <[email protected]>
18+
Reviewed-by: Peter Xu <[email protected]>
19+
Tested-by: Precific <[email protected]>
20+
Link: https://lore.kernel.org/r/[email protected]
21+
22+
Signed-off-by: Alex Williamson <[email protected]>
23+
(cherry picked from commit 09dfc8a5f2ce897005a94bf66cca4f91e4e03700)
24+
Signed-off-by: Jonathan Maple <[email protected]>
25+
26+
# Conflicts:
27+
# drivers/vfio/pci/vfio_pci_core.c
28+
diff --cc drivers/vfio/pci/vfio_pci_core.c
29+
index ffda816e0119,1a4ed5a357d3..000000000000
30+
--- a/drivers/vfio/pci/vfio_pci_core.c
31+
+++ b/drivers/vfio/pci/vfio_pci_core.c
32+
@@@ -1770,49 -1658,59 +1770,87 @@@ static vm_fault_t vfio_pci_mmap_fault(s
33+
{
34+
struct vm_area_struct *vma = vmf->vma;
35+
struct vfio_pci_core_device *vdev = vma->vm_private_data;
36+
++<<<<<<< HEAD
37+
+ struct vfio_pci_mmap_vma *mmap_vma;
38+
+ vm_fault_t ret = VM_FAULT_NOPAGE;
39+
+
40+
+ mutex_lock(&vdev->vma_lock);
41+
+ down_read(&vdev->memory_lock);
42+
+
43+
+ /*
44+
+ * Memory region cannot be accessed if the low power feature is engaged
45+
+ * or memory access is disabled.
46+
+ */
47+
+ if (vdev->pm_runtime_engaged || !__vfio_pci_memory_enabled(vdev)) {
48+
+ ret = VM_FAULT_SIGBUS;
49+
+ goto up_out;
50+
++=======
51+
+ unsigned long pfn, pgoff = vmf->pgoff - vma->vm_pgoff;
52+
+ vm_fault_t ret = VM_FAULT_SIGBUS;
53+
+
54+
+ pfn = vma_to_pfn(vma) + pgoff;
55+
+
56+
+ if (order && (pfn & ((1 << order) - 1) ||
57+
+ vmf->address & ((PAGE_SIZE << order) - 1) ||
58+
+ vmf->address + (PAGE_SIZE << order) > vma->vm_end)) {
59+
+ ret = VM_FAULT_FALLBACK;
60+
+ goto out;
61+
+ }
62+
+
63+
+ down_read(&vdev->memory_lock);
64+
+
65+
+ if (vdev->pm_runtime_engaged || !__vfio_pci_memory_enabled(vdev))
66+
+ goto out_unlock;
67+
+
68+
+ switch (order) {
69+
+ case 0:
70+
+ ret = vmf_insert_pfn(vma, vmf->address, pfn);
71+
+ break;
72+
+ #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
73+
+ case PMD_ORDER:
74+
+ ret = vmf_insert_pfn_pmd(vmf,
75+
+ __pfn_to_pfn_t(pfn, PFN_DEV), false);
76+
+ break;
77+
+ #endif
78+
+ #ifdef CONFIG_ARCH_SUPPORTS_PUD_PFNMAP
79+
+ case PUD_ORDER:
80+
+ ret = vmf_insert_pfn_pud(vmf,
81+
+ __pfn_to_pfn_t(pfn, PFN_DEV), false);
82+
+ break;
83+
+ #endif
84+
+ default:
85+
+ ret = VM_FAULT_FALLBACK;
86+
++>>>>>>> 09dfc8a5f2ce (vfio/pci: Fallback huge faults for unaligned pfn)
87+
}
88+
89+
-out_unlock:
90+
- up_read(&vdev->memory_lock);
91+
-out:
92+
- dev_dbg_ratelimited(&vdev->pdev->dev,
93+
- "%s(,order = %d) BAR %ld page offset 0x%lx: 0x%x\n",
94+
- __func__, order,
95+
- vma->vm_pgoff >>
96+
- (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT),
97+
- pgoff, (unsigned int)ret);
98+
+ /*
99+
+ * We populate the whole vma on fault, so we need to test whether
100+
+ * the vma has already been mapped, such as for concurrent faults
101+
+ * to the same vma. io_remap_pfn_range() will trigger a BUG_ON if
102+
+ * we ask it to fill the same range again.
103+
+ */
104+
+ list_for_each_entry(mmap_vma, &vdev->vma_list, vma_next) {
105+
+ if (mmap_vma->vma == vma)
106+
+ goto up_out;
107+
+ }
108+
109+
- return ret;
110+
-}
111+
+ if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
112+
+ vma->vm_end - vma->vm_start,
113+
+ vma->vm_page_prot)) {
114+
+ ret = VM_FAULT_SIGBUS;
115+
+ zap_vma_ptes(vma, vma->vm_start, vma->vm_end - vma->vm_start);
116+
+ goto up_out;
117+
+ }
118+
119+
-static vm_fault_t vfio_pci_mmap_page_fault(struct vm_fault *vmf)
120+
-{
121+
- return vfio_pci_mmap_huge_fault(vmf, 0);
122+
+ if (__vfio_pci_add_vma(vdev, vma)) {
123+
+ ret = VM_FAULT_OOM;
124+
+ zap_vma_ptes(vma, vma->vm_start, vma->vm_end - vma->vm_start);
125+
+ }
126+
+
127+
+up_out:
128+
+ up_read(&vdev->memory_lock);
129+
+ mutex_unlock(&vdev->vma_lock);
130+
+ return ret;
131+
}
132+
133+
static const struct vm_operations_struct vfio_pci_mmap_ops = {
134+
* Unmerged path drivers/vfio/pci/vfio_pci_core.c

0 commit comments

Comments
 (0)