]> xenbits.xensource.com Git - people/tklengyel/xen.git/commitdiff
gnttab: bypass IOMMU (un)mapping when a domain is (un)mapping its own grant
authorJan Beulich <jbeulich@suse.com>
Thu, 18 Feb 2021 12:16:59 +0000 (13:16 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 18 Feb 2021 12:16:59 +0000 (13:16 +0100)
Mappings for a domain's own pages should already be present in the
IOMMU. While installing the same mapping again is merely redundant (and
inefficient), removing the mapping when the grant mapping gets removed
is outright wrong in this case: The mapping was there before the map, so
should remain in place after unmapping.

This affects
- Arm Dom0 in the direct mapped case,
- x86 PV Dom0 in the "iommu=dom0-strict" / "dom0-iommu=strict" case,
- all x86 PV DomU-s, including driver domains.

See the code comment for why it's the original domain and not the page
owner that gets compared against.

Reported-by: Rahul Singh <Rahul.Singh@arm.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Julien Grall <jgrall@amazon.com>
xen/common/grant_table.c

index 4902598c8fb55cc0ab49fdc32fbb2decbd60e736..f937c1d3503a34ef1452d7a567997e84e9e76496 100644 (file)
@@ -1243,7 +1243,14 @@ map_grant_ref(
         goto undo_out;
     }
 
-    need_iommu = gnttab_need_iommu_mapping(ld);
+    /*
+     * This is deliberately not checking the page's owner: get_paged_frame()
+     * explicitly rejects foreign pages, and all success paths above yield
+     * either owner == rd or owner == dom_io (the dom_cow case is irrelevant
+     * as mem-sharing and IOMMU use are incompatible). The dom_io case would
+     * need checking separately if we compared against owner here.
+     */
+    need_iommu = ld != rd && gnttab_need_iommu_mapping(ld);
     if ( need_iommu )
     {
         unsigned int kind;
@@ -1493,7 +1500,8 @@ unmap_common(
     if ( put_handle )
         put_maptrack_handle(lgt, op->handle);
 
-    if ( rc == GNTST_okay && gnttab_need_iommu_mapping(ld) )
+    /* See the respective comment in map_grant_ref(). */
+    if ( rc == GNTST_okay && ld != rd && gnttab_need_iommu_mapping(ld) )
     {
         unsigned int kind;
         int err = 0;