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

[xen stable-4.12] AMD/IOMMU: update live PTEs atomically



commit 97f9defe9610adc44dd65a2e21d788e053641183
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Tue Oct 20 15:03:04 2020 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Oct 20 15:03:04 2020 +0200

    AMD/IOMMU: update live PTEs atomically
    
    Updating a live PTE word by word allows the IOMMU to see a partially
    updated entry. Construct the new entry fully in a local variable and
    then write the new entry by a single insn.
    
    This is part of XSA-347.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Paul Durrant <paul@xxxxxxx>
    master commit: 3b055121c5410e2c3105d6d06aa24ca0d58868cd
    master date: 2020-10-20 14:22:52 +0200
---
 xen/drivers/passthrough/amd/iommu_map.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/xen/drivers/passthrough/amd/iommu_map.c 
b/xen/drivers/passthrough/amd/iommu_map.c
index 8f0ec3dc8e..98993aa0ce 100644
--- a/xen/drivers/passthrough/amd/iommu_map.c
+++ b/xen/drivers/passthrough/amd/iommu_map.c
@@ -49,7 +49,7 @@ static unsigned int clear_iommu_pte_present(unsigned long 
l1_mfn,
                                          IOMMU_PTE_PRESENT_SHIFT) ?
                                          IOMMU_FLUSHF_modified : 0;
 
-    *pte = 0;
+    write_atomic(pte, 0);
     unmap_domain_page(table);
 
     return flush_flags;
@@ -60,7 +60,7 @@ static unsigned int set_iommu_pde_present(uint32_t *pde,
                                           unsigned int next_level, bool iw,
                                           bool ir)
 {
-    uint64_t maddr_next;
+    uint64_t maddr_next, full;
     uint32_t addr_lo, addr_hi, entry;
     bool old_present;
     unsigned int flush_flags = IOMMU_FLUSHF_added;
@@ -119,7 +119,7 @@ static unsigned int set_iommu_pde_present(uint32_t *pde,
     if ( next_level == 0 )
         set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,
                              IOMMU_PTE_FC_MASK, IOMMU_PTE_FC_SHIFT, &entry);
-    pde[1] = entry;
+    full = (uint64_t)entry << 32;
 
     /* mark next level as 'present' */
     set_field_in_reg_u32(addr_lo >> PAGE_SHIFT, 0,
@@ -131,7 +131,9 @@ static unsigned int set_iommu_pde_present(uint32_t *pde,
     set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,
                          IOMMU_PDE_PRESENT_MASK,
                          IOMMU_PDE_PRESENT_SHIFT, &entry);
-    pde[0] = entry;
+    full |= entry;
+
+    write_atomic((uint64_t *)pde, full);
 
     return flush_flags;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12



 


Rackspace

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