lkml.org 
[lkml]   [2020]   [Sep]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 49/88] iommu/vt-d: Serialize IOMMU GCMD register modifications
    Date
    From: Lu Baolu <baolu.lu@linux.intel.com>

    [ 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: af8d102f999a4 ("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>
    ---
    drivers/iommu/intel_irq_remapping.c | 10 ++++++++--
    1 file changed, 8 insertions(+), 2 deletions(-)

    diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
    index 15a4ad31c510a..9d2d03545bb07 100644
    --- a/drivers/iommu/intel_irq_remapping.c
    +++ b/drivers/iommu/intel_irq_remapping.c
    @@ -479,12 +479,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
    --
    2.25.1


    \
     
     \ /
      Last update: 2020-09-08 18:22    [W:4.278 / U:0.148 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site