intel-iommu: set compatibility format interrupt
authorHan, Weidong <weidong.han@intel.com>
Fri, 3 Apr 2009 09:15:47 +0000 (17:15 +0800)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Fri, 3 Apr 2009 20:46:01 +0000 (21:46 +0100)
When extended interrupt mode (x2apic mode) is not supported in a
system, it must set compatibility format interrupt to bypass
interrupt remapping, otherwise compatibility format interrupts
will be blocked.

This will be used when interrupt remapping is enabled while x2apic
is not supported.

Signed-off-by: Weidong Han <weidong.han@intel.com>
Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
drivers/pci/intr_remapping.c
include/linux/intel-iommu.h

index c26633d7e7da75adbe48e63e4ef54bb18a26e9d7..ef25caade54b743b9559fe6c11075d26841b16d9 100644 (file)
@@ -415,12 +415,27 @@ static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
 
        /* Set interrupt-remapping table pointer */
        cmd = iommu->gcmd | DMA_GCMD_SIRTP;
+       iommu->gcmd |= DMA_GCMD_SIRTP;
        writel(cmd, iommu->reg + DMAR_GCMD_REG);
 
        IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
                      readl, (sts & DMA_GSTS_IRTPS), sts);
        spin_unlock_irqrestore(&iommu->register_lock, flags);
 
+       if (mode == 0) {
+               spin_lock_irqsave(&iommu->register_lock, flags);
+
+               /* enable comaptiblity format interrupt pass through */
+               cmd = iommu->gcmd | DMA_GCMD_CFI;
+               iommu->gcmd |= DMA_GCMD_CFI;
+               writel(cmd, iommu->reg + DMAR_GCMD_REG);
+
+               IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+                             readl, (sts & DMA_GSTS_CFIS), sts);
+
+               spin_unlock_irqrestore(&iommu->register_lock, flags);
+       }
+
        /*
         * global invalidation of interrupt entry cache before enabling
         * interrupt-remapping.
index 3771cd1f876eac2d2090bbf06e2d2aaf0fadafcb..aa8c531712330cb2f5d845dab291c15fc299a0e3 100644 (file)
@@ -164,6 +164,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
 #define DMA_GCMD_QIE (((u32)1) << 26)
 #define DMA_GCMD_SIRTP (((u32)1) << 24)
 #define DMA_GCMD_IRE (((u32) 1) << 25)
+#define DMA_GCMD_CFI (((u32) 1) << 23)
 
 /* GSTS_REG */
 #define DMA_GSTS_TES (((u32)1) << 31)
@@ -174,6 +175,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
 #define DMA_GSTS_QIES (((u32)1) << 26)
 #define DMA_GSTS_IRTPS (((u32)1) << 24)
 #define DMA_GSTS_IRES (((u32)1) << 25)
+#define DMA_GSTS_CFIS (((u32)1) << 23)
 
 /* CCMD_REG */
 #define DMA_CCMD_ICC (((u64)1) << 63)