aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vfio/vfio_iommu_type1.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-12-07 14:51:04 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2019-12-07 14:51:04 -0800
commit94e89b40235476a83a53a47b9ffb0cb91a4c335e (patch)
tree3411f7cbbf0f50a1719bda94ea4484fb4982794f /drivers/vfio/vfio_iommu_type1.c
parentMerge tag 'for-linus-5.5b-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip (diff)
parentMerge branch 'v5.5/vfio/jiang-yi-irq-bypass-unregister-v1' into v5.5/vfio/next (diff)
downloadlinux-dev-94e89b40235476a83a53a47b9ffb0cb91a4c335e.tar.xz
linux-dev-94e89b40235476a83a53a47b9ffb0cb91a4c335e.zip
Merge tag 'vfio-v5.5-rc1' of git://github.com/awilliam/linux-vfio
Pull VFIO updates from Alex Williamson: - Remove hugepage checks for reserved pfns (Ben Luo) - Fix irq-bypass unregister ordering (Jiang Yi) * tag 'vfio-v5.5-rc1' of git://github.com/awilliam/linux-vfio: vfio/pci: call irq_bypass_unregister_producer() before freeing irq vfio/type1: remove hugepage checks in is_invalid_reserved_pfn()
Diffstat (limited to 'drivers/vfio/vfio_iommu_type1.c')
-rw-r--r--drivers/vfio/vfio_iommu_type1.c26
1 files changed, 4 insertions, 22 deletions
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index d864277ea16f..2ada8e6cdb88 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -294,31 +294,13 @@ static int vfio_lock_acct(struct vfio_dma *dma, long npage, bool async)
* Some mappings aren't backed by a struct page, for example an mmap'd
* MMIO range for our own or another device. These use a different
* pfn conversion and shouldn't be tracked as locked pages.
+ * For compound pages, any driver that sets the reserved bit in head
+ * page needs to set the reserved bit in all subpages to be safe.
*/
static bool is_invalid_reserved_pfn(unsigned long pfn)
{
- if (pfn_valid(pfn)) {
- bool reserved;
- struct page *tail = pfn_to_page(pfn);
- struct page *head = compound_head(tail);
- reserved = !!(PageReserved(head));
- if (head != tail) {
- /*
- * "head" is not a dangling pointer
- * (compound_head takes care of that)
- * but the hugepage may have been split
- * from under us (and we may not hold a
- * reference count on the head page so it can
- * be reused before we run PageReferenced), so
- * we've to check PageTail before returning
- * what we just read.
- */
- smp_rmb();
- if (PageTail(tail))
- return reserved;
- }
- return PageReserved(tail);
- }
+ if (pfn_valid(pfn))
+ return PageReserved(pfn_to_page(pfn));
return true;
}