mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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@suse.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
This commit is contained in:
1 parent
0d597e7bd1
commit
95e07f8c0e
1 file changed
+15
-6
@@ -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);
|
||||
|
||||