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

[xen master] VT-d: re-order register restoring in vtd_resume()



commit 95e07f8c0e64889ee56015c7f99bdf5309e9e8ef
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Tue Mar 30 14:39:54 2021 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Mar 30 14:39:54 2021 +0200

    VT-d: re-order register restoring in vtd_resume()
    
    For one FECTL must be written last - the interrupt shouldn't be unmasked
    without first having written the data and address needed to actually
    deliver it. In the common case (when dma_msi_set_affinity() doesn't end
    up bailing early) this happens from init_vtd_hw(), but for this to
    actually have the intended effect we shouldn't subsequently overwrite
    what was written there - this is only benign when old and new settings
    match. Instead we should restore the registers ahead of calling
    init_vtd_hw(), just for the unlikely case of dma_msi_set_affinity()
    bailing early.
    
    In the moved code drop some stray casts as well.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx>
---
 xen/drivers/passthrough/vtd/iommu.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/xen/drivers/passthrough/vtd/iommu.c 
b/xen/drivers/passthrough/vtd/iommu.c
index 058f55f9a0..114f9512e9 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -2594,6 +2594,21 @@ static void vtd_resume(void)
     if ( !iommu_enabled )
         return;
 
+    for_each_drhd_unit ( drhd )
+    {
+        iommu = drhd->iommu;
+        i = iommu->index;
+
+        spin_lock_irqsave(&iommu->register_lock, flags);
+        dmar_writel(iommu->reg, DMAR_FEDATA_REG,
+                    iommu_state[i][DMAR_FEDATA_REG]);
+        dmar_writel(iommu->reg, DMAR_FEADDR_REG,
+                    iommu_state[i][DMAR_FEADDR_REG]);
+        dmar_writel(iommu->reg, DMAR_FEUADDR_REG,
+                    iommu_state[i][DMAR_FEUADDR_REG]);
+        spin_unlock_irqrestore(&iommu->register_lock, flags);
+    }
+
     if ( init_vtd_hw(true) != 0 && force_iommu )
          panic("IOMMU setup failed, crash Xen for security purpose\n");
 
@@ -2605,12 +2620,6 @@ static void vtd_resume(void)
         spin_lock_irqsave(&iommu->register_lock, flags);
         dmar_writel(iommu->reg, DMAR_FECTL_REG,
                     (u32) iommu_state[i][DMAR_FECTL_REG]);
-        dmar_writel(iommu->reg, DMAR_FEDATA_REG,
-                    (u32) iommu_state[i][DMAR_FEDATA_REG]);
-        dmar_writel(iommu->reg, DMAR_FEADDR_REG,
-                    (u32) iommu_state[i][DMAR_FEADDR_REG]);
-        dmar_writel(iommu->reg, DMAR_FEUADDR_REG,
-                    (u32) iommu_state[i][DMAR_FEUADDR_REG]);
         spin_unlock_irqrestore(&iommu->register_lock, flags);
 
         iommu_enable_translation(drhd);
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

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