VT-d: fix caching mode IOTLB flushing
authorJan Beulich <jbeulich@suse.com>
Fri, 27 Aug 2021 08:52:15 +0000 (10:52 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 27 Aug 2021 08:52:15 +0000 (10:52 +0200)
While for context cache entry flushing use of did 0 is indeed correct
(after all upon reading the context entry the IOMMU wouldn't know any
domain ID if the entry is not present, and hence a surrogate one needs
to be used), for IOTLB entries the normal domain ID (from the [present]
context entry) gets used. See sub-section "IOTLB" of section "Address
Translation Caches" in the VT-d spec.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Paul Durrant <paul@xen.org>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
xen/drivers/passthrough/vtd/iommu.c
xen/drivers/passthrough/vtd/qinval.c

index 23921dfb7bae61f95ec9c75e9889cc378682f21f..2034a95a873cb9efb69320e6913d273252ac0eff 100644 (file)
@@ -468,17 +468,10 @@ int vtd_flush_iotlb_reg(struct vtd_iommu *iommu, uint16_t did, uint64_t addr,
 
     /*
      * In the non-present entry flush case, if hardware doesn't cache
-     * non-present entry we do nothing and if hardware cache non-present
-     * entry, we flush entries of domain 0 (the domain id is used to cache
-     * any non-present entries)
+     * non-present entries we do nothing.
      */
-    if ( flush_non_present_entry )
-    {
-        if ( !cap_caching_mode(iommu->cap) )
-            return 1;
-        else
-            did = 0;
-    }
+    if ( flush_non_present_entry && !cap_caching_mode(iommu->cap) )
+        return 1;
 
     /* use register invalidation */
     switch ( type )
index b0e3672231ae5214264c5ce279d7cfbdec12655e..b16153e298128cbc448b18833806d38a03c870ba 100644 (file)
@@ -362,17 +362,10 @@ static int __must_check flush_iotlb_qi(struct vtd_iommu *iommu, u16 did,
 
     /*
      * In the non-present entry flush case, if hardware doesn't cache
-     * non-present entry we do nothing and if hardware cache non-present
-     * entry, we flush entries of domain 0 (the domain id is used to cache
-     * any non-present entries)
+     * non-present entries we do nothing.
      */
-    if ( flush_non_present_entry )
-    {
-        if ( !cap_caching_mode(iommu->cap) )
-            return 1;
-        else
-            did = 0;
-    }
+    if ( flush_non_present_entry && !cap_caching_mode(iommu->cap) )
+        return 1;
 
     /* use queued invalidation */
     if (cap_write_drain(iommu->cap))