[PATCH 2/5] vtd: Ensure context entry is cleared properly

Teddy Astie <[email protected]> Wed, 29 Jul 2026 11:59:44 +0200
Newsgroups gmane.comp.emulators.xen.devel
Message-ID <1785319341.8631fc262581453bbf619ec5b2062170.19fad533bfc000e099@vates.tech>
When removing a context entry for a device, the present bit needs to
be cleared first, then we can clear the rest of the field. In the current
logic, the compiler is allowed to perform optimizations in a way where high
is cleared before the present bit (which is in low part) is, leading to a
window where the context entry is invalid and would make the IOMMU fault
(as address width would be set to a reserved value).

Fix the logic by ensuring we clear the low part first (which also clears
the present bit) then the high part afterward.

Fixes: cada0c18f8d1 ("vtd: Move dom0 RMRR check to intel_iommu_remove_device()")
Reported-by: Teddy Astie <[email protected]>
Signed-off-by: Andrew Cooper <[email protected]>
Signed-off-by: Teddy Astie <[email protected]>
---
 xen/drivers/passthrough/vtd/iommu.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index c314ce1db8..1005e200c1 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -1889,8 +1889,14 @@ int domain_context_unmap_one(
 
     iommu_domid = context_domain_id(*context);
 
-    context_clear_present(*context);
-    context_clear_entry(*context);
+    /*
+     * Clear the context entry.
+     *
+     * As this is performed with two stores, ensure lo (containing the present
+     * bit) is cleared first.
+     */
+    ACCESS_ONCE(context->lo) = 0;
+    ACCESS_ONCE(context->hi) = 0;
     iommu_sync_cache(context, sizeof(struct context_entry));
 
     rc = iommu_flush_context_device(iommu, iommu_domid,
-- 
2.54.0



-- 
Teddy Astie | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech