Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
xen.10697
5c7e6fe8-IOMMU-x86-fix-type-ref-counting-race.p...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5c7e6fe8-IOMMU-x86-fix-type-ref-counting-race.patch of Package xen.10697
# Commit 1f0b0bb7773d537bcf169e021495d0986d9809fc # Date 2019-03-05 13:47:36 +0100 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> 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> --- a/xen/drivers/passthrough/iommu.c +++ b/xen/drivers/passthrough/iommu.c @@ -366,10 +366,31 @@ static int iommu_populate_page_table(str if ( is_hvm_domain(d) || (page->u.inuse.type_info & PGT_type_mask) == PGT_writable_page ) { - BUG_ON(SHARED_M2P(mfn_to_gmfn(d, page_to_mfn(page)))); - rc = hd->platform_ops->map_page( - d, mfn_to_gmfn(d, page_to_mfn(page)), page_to_mfn(page), - IOMMUF_readable|IOMMUF_writable); + unsigned long gfn = mfn_to_gmfn(d, page_to_mfn(page)); + + BUG_ON(SHARED_M2P(gfn)); + rc = hd->platform_ops->map_page(d, gfn, page_to_mfn(page), + IOMMUF_readable|IOMMUF_writable); + + /* + * 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 = hd->platform_ops->unmap_page(d, gfn); + /* 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 ) { page_list_add(page, &d->page_list);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor