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

[RESEND PATCH 1/5] vtd: Ensure root entry is updated consistently



Make sure the root entry is updated consistently such that the compiler
is not allowed to perform optimizations around setting present bit (and
i.e set present bit before setting up the pagetable addresss, which would
cause the IOMMU to use a pagetable at address 0 instead).

This issue can only occurs at boot time where present bit is initially cleared
or when a bus is first introduced in the machine.

Fixes: ccfe4e08455f ("Intel vt-d specific changes in arch/x86/hvm/vmx/vtd.")
Signed-off-by: Teddy Astie <teddy.astie@xxxxxxxxxx>
---
 xen/drivers/passthrough/vtd/iommu.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/xen/drivers/passthrough/vtd/iommu.c 
b/xen/drivers/passthrough/vtd/iommu.c
index 3d6f787b3c..c314ce1db8 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -281,13 +281,13 @@ void free_pgtable_maddr(u64 maddr)
 /* context entry handling */
 static u64 bus_to_context_maddr(struct vtd_iommu *iommu, u8 bus)
 {
-    struct root_entry *root, *root_entries;
+    struct root_entry root, *root_entries;
     u64 maddr;
 
     ASSERT(spin_is_locked(&iommu->lock));
     root_entries = (struct root_entry *)map_vtd_domain_page(iommu->root_maddr);
-    root = &root_entries[bus];
-    if ( !root_present(*root) )
+    root.val = ACCESS_ONCE(root_entries[bus].val);
+    if ( !root_present(root) )
     {
         maddr = alloc_pgtable_maddr(1, iommu->node);
         if ( maddr == 0 )
@@ -295,11 +295,12 @@ static u64 bus_to_context_maddr(struct vtd_iommu *iommu, 
u8 bus)
             unmap_vtd_domain_page(root_entries);
             return 0;
         }
-        set_root_value(*root, maddr);
-        set_root_present(*root);
-        iommu_sync_cache(root, sizeof(struct root_entry));
+        set_root_value(root, maddr);
+        set_root_present(root);
+        ACCESS_ONCE(root_entries[bus].val) = root.val;
+        iommu_sync_cache(&root_entries[bus], sizeof(struct root_entry));
     }
-    maddr = (u64) get_context_addr(*root);
+    maddr = (u64) get_context_addr(root);
     unmap_vtd_domain_page(root_entries);
     return maddr;
 }
-- 
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®.