aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2012-06-15 12:03:31 -0400
committerJoerg Roedel <joerg.roedel@amd.com>2012-09-28 11:31:41 -0400
commit33f28c59e18d83fd2aeef258d211be66b9b80eb3 (patch)
tree37076d60ce5e1b7830edad4ece164361d3185ecb /drivers/iommu
parenteb1eb7ae65a9d32f6c16a90419caf01221f94734 (diff)
iommu/amd: Split device table initialization into irq and dma part
When the IOMMU is enabled very early (as with irq-remapping) some devices are still in BIOS hand. When dma is blocked early this can cause lots of IO_PAGE_FAULTs. So delay the DMA initialization and do it right before the dma_ops are initialized. To be secure, block all interrupts by default when irq-remapping is enabled in the system. They will be reenabled on demand later. Without blocking interrupts by default devices can issue arbitrary interrupts by sending special DMA packets to the CPU that look like MSI messages. This is especially dangerous when a device is assigned to a KVM guest because the guest can then DoS the host. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/amd_iommu_init.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index f8a222b0ac3f..8a7f1971d633 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -1381,7 +1381,7 @@ static int __init init_memory_definitions(struct acpi_table_header *table)
1381 * Init the device table to not allow DMA access for devices and 1381 * Init the device table to not allow DMA access for devices and
1382 * suppress all page faults 1382 * suppress all page faults
1383 */ 1383 */
1384static void init_device_table(void) 1384static void init_device_table_dma(void)
1385{ 1385{
1386 u32 devid; 1386 u32 devid;
1387 1387
@@ -1391,6 +1391,17 @@ static void init_device_table(void)
1391 } 1391 }
1392} 1392}
1393 1393
1394static void init_device_table(void)
1395{
1396 u32 devid;
1397
1398 if (!amd_iommu_irq_remap)
1399 return;
1400
1401 for (devid = 0; devid <= amd_iommu_last_bdf; ++devid)
1402 set_dev_entry_bit(devid, DEV_ENTRY_IRQ_TBL_EN);
1403}
1404
1394static void iommu_init_flags(struct amd_iommu *iommu) 1405static void iommu_init_flags(struct amd_iommu *iommu)
1395{ 1406{
1396 iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ? 1407 iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ?
@@ -1781,8 +1792,14 @@ static bool detect_ivrs(void)
1781 1792
1782static int amd_iommu_init_dma(void) 1793static int amd_iommu_init_dma(void)
1783{ 1794{
1795 struct amd_iommu *iommu;
1784 int ret; 1796 int ret;
1785 1797
1798 init_device_table_dma();
1799
1800 for_each_iommu(iommu)
1801 iommu_flush_all_caches(iommu);
1802
1786 if (iommu_pass_through) 1803 if (iommu_pass_through)
1787 ret = amd_iommu_init_passthrough(); 1804 ret = amd_iommu_init_passthrough();
1788 else 1805 else