Commit 026948f0 authored by Ben Luo's avatar Ben Luo Committed by Alex Williamson

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: default avatarBen Luo <luoben@linux.alibaba.com>
Reviewed-by: default avatarAndrea Arcangeli <aarcange@redhat.com>
Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent 4f5cafb5
...@@ -294,31 +294,13 @@ static int vfio_lock_acct(struct vfio_dma *dma, long npage, bool async) ...@@ -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 * 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 * MMIO range for our own or another device. These use a different
* pfn conversion and shouldn't be tracked as locked pages. * 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) static bool is_invalid_reserved_pfn(unsigned long pfn)
{ {
if (pfn_valid(pfn)) { if (pfn_valid(pfn))
bool reserved; return PageReserved(pfn_to_page(pfn));
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);
}
return true; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment