[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



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 <teddy.astie@xxxxxxxxxx>
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Signed-off-by: Teddy Astie <teddy.astie@xxxxxxxxxx>
---
 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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.