IOMMU/x86: fix type ref-counting race upon IOMMU page table construction

When arch_iommu_populate_page_table() gets invoked for an already
running guest, simply looking at page types once isn't enough, as they
may change at any time. Add logic to re-check the type after having
mapped the page, unmapping it again if needed.

This is XSA-285.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tentatively-Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
Jan Beulich committed 2019-03-05 13:47:36 +01:00
1 parent 6d4f36c3fe
commit 1f0b0bb777
1 file changed
+21
+21
View File
@@ -70,6 +70,27 @@ int arch_iommu_populate_page_table(struct domain *d)
rc = iommu_map(d, _dfn(gfn), _mfn(mfn), PAGE_ORDER_4K,
IOMMUF_readable | IOMMUF_writable,
&flush_flags);
/*
* We may be working behind the back of a running guest, which
* may change the type of a page at any time. We can't prevent
* this (for instance, by bumping the type count while mapping
* the page) without causing legitimate guest type-change
* operations to fail. So after adding the page to the IOMMU,
* check again to make sure this is still valid. NB that the
* writable entry in the iommu is harmless until later, when
* the actual device gets assigned.
*/
if ( !rc && !is_hvm_domain(d) &&
((page->u.inuse.type_info & PGT_type_mask) !=
PGT_writable_page) )
{
rc = iommu_unmap(d, _dfn(gfn), PAGE_ORDER_4K, &flush_flags);
/* If the type changed yet again, simply force a retry. */
if ( !rc && ((page->u.inuse.type_info & PGT_type_mask) ==
PGT_writable_page) )
rc = -ERESTART;
}
}
if ( rc )
{
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.