Skip to content

Commit

Permalink
iommu/vt-d: Serialize IOMMU GCMD register modifications
Browse files Browse the repository at this point in the history
[ Upstream commit 6e4e9ec65078093165463c13d4eb92b3e8d7b2e8 ]

The VT-d spec requires (10.4.4 Global Command Register, GCMD_REG General
Description) that:

If multiple control fields in this register need to be modified, software
must serialize the modifications through multiple writes to this register.

However, in irq_remapping.c, modifications of IRE and CFI are done in one
write. We need to do two separate writes with STS checking after each. It
also checks the status register before writing command register to avoid
unnecessary register write.

Fixes: af8d102 ("x86/intel/irq_remapping: Clean up x2apic opt-out security warning mess")
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Ashok Raj <ashok.raj@intel.com>
Link: https://lore.kernel.org/r/20200828000615.8281-1-baolu.lu@linux.intel.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
LuBaolu authored and gregkh committed Sep 9, 2020
1 parent 920d9ff commit 0c21f1b
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions drivers/iommu/intel_irq_remapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,12 +507,18 @@ static void iommu_enable_irq_remapping(struct intel_iommu *iommu)

/* Enable interrupt-remapping */
iommu->gcmd |= DMA_GCMD_IRE;
iommu->gcmd &= ~DMA_GCMD_CFI; /* Block compatibility-format MSIs */
writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);

IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
readl, (sts & DMA_GSTS_IRES), sts);

/* Block compatibility-format MSIs */
if (sts & DMA_GSTS_CFIS) {
iommu->gcmd &= ~DMA_GCMD_CFI;
writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
readl, !(sts & DMA_GSTS_CFIS), sts);
}

/*
* With CFI clear in the Global Command register, we should be
* protected from dangerous (i.e. compatibility) interrupts
Expand Down

0 comments on commit 0c21f1b

Please sign in to comment.