Skip to content

Commit 026948f

Browse files
Ben Luoawilliam
authored andcommitted
vfio/type1: remove hugepage checks in is_invalid_reserved_pfn()
Currently, no hugepage split code can transfer the reserved bit from head to tail during the split, so checking the head can't make a difference in a racing condition with hugepage spliting. The buddy wouldn't allow a driver to allocate an hugepage if any subpage is reserved in the e820 map at boot, if any driver sets the reserved bit of head page before mapping the hugepage in userland, it needs to set the reserved bit in all subpages to be safe. Signed-off-by: Ben Luo <[email protected]> Reviewed-by: Andrea Arcangeli <[email protected]> Signed-off-by: Alex Williamson <[email protected]>
1 parent 4f5cafb commit 026948f

File tree

1 file changed

+4
-22
lines changed

1 file changed

+4
-22
lines changed

drivers/vfio/vfio_iommu_type1.c

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -294,31 +294,13 @@ static int vfio_lock_acct(struct vfio_dma *dma, long npage, bool async)
294294
* Some mappings aren't backed by a struct page, for example an mmap'd
295295
* MMIO range for our own or another device. These use a different
296296
* pfn conversion and shouldn't be tracked as locked pages.
297+
* For compound pages, any driver that sets the reserved bit in head
298+
* page needs to set the reserved bit in all subpages to be safe.
297299
*/
298300
static bool is_invalid_reserved_pfn(unsigned long pfn)
299301
{
300-
if (pfn_valid(pfn)) {
301-
bool reserved;
302-
struct page *tail = pfn_to_page(pfn);
303-
struct page *head = compound_head(tail);
304-
reserved = !!(PageReserved(head));
305-
if (head != tail) {
306-
/*
307-
* "head" is not a dangling pointer
308-
* (compound_head takes care of that)
309-
* but the hugepage may have been split
310-
* from under us (and we may not hold a
311-
* reference count on the head page so it can
312-
* be reused before we run PageReferenced), so
313-
* we've to check PageTail before returning
314-
* what we just read.
315-
*/
316-
smp_rmb();
317-
if (PageTail(tail))
318-
return reserved;
319-
}
320-
return PageReserved(tail);
321-
}
302+
if (pfn_valid(pfn))
303+
return PageReserved(pfn_to_page(pfn));
322304

323305
return true;
324306
}

0 commit comments

Comments
 (0)