aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/vfio/vfio_iommu_type1.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index e30e29ae4819..45657e2b1ff7 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -338,11 +338,12 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr,
338{ 338{
339 struct page *page[1]; 339 struct page *page[1];
340 struct vm_area_struct *vma; 340 struct vm_area_struct *vma;
341 struct vm_area_struct *vmas[1];
341 int ret; 342 int ret;
342 343
343 if (mm == current->mm) { 344 if (mm == current->mm) {
344 ret = get_user_pages_fast(vaddr, 1, !!(prot & IOMMU_WRITE), 345 ret = get_user_pages_longterm(vaddr, 1, !!(prot & IOMMU_WRITE),
345 page); 346 page, vmas);
346 } else { 347 } else {
347 unsigned int flags = 0; 348 unsigned int flags = 0;
348 349
@@ -351,7 +352,18 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr,
351 352
352 down_read(&mm->mmap_sem); 353 down_read(&mm->mmap_sem);
353 ret = get_user_pages_remote(NULL, mm, vaddr, 1, flags, page, 354 ret = get_user_pages_remote(NULL, mm, vaddr, 1, flags, page,
354 NULL, NULL); 355 vmas, NULL);
356 /*
357 * The lifetime of a vaddr_get_pfn() page pin is
358 * userspace-controlled. In the fs-dax case this could
359 * lead to indefinite stalls in filesystem operations.
360 * Disallow attempts to pin fs-dax pages via this
361 * interface.
362 */
363 if (ret > 0 && vma_is_fsdax(vmas[0])) {
364 ret = -EOPNOTSUPP;
365 put_page(page[0]);
366 }
355 up_read(&mm->mmap_sem); 367 up_read(&mm->mmap_sem);
356 } 368 }
357 369