From a8ec2d328aed7925482d98011e8f1fdd816899b9 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Sat, 7 May 2016 19:02:28 +0200 Subject: [PATCH] x86: Block DMA from unlisted devices in AMD IOMMU Invalid device table entries in the AMD IOMMU mean that those devices are actually allowed to perform DMA requests and issue interrupts. We have to avoid this case because only devices listed in a config are permitted to do so. We already achieve this effect when removing an existing device from the table, but we have to ensure it also for any unlisted device. Devices with IDs not covered by any table are blocked by the IOMMU, see AMD I/O Virtualization Technology spec, 2.2.2. Signed-off-by: Jan Kiszka --- hypervisor/arch/x86/amd_iommu.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hypervisor/arch/x86/amd_iommu.c b/hypervisor/arch/x86/amd_iommu.c index 65662a2..31e78f4 100644 --- a/hypervisor/arch/x86/amd_iommu.c +++ b/hypervisor/arch/x86/amd_iommu.c @@ -446,6 +446,7 @@ static struct dev_table_entry *get_dev_table_entry(struct amd_iommu *iommu, struct dev_table_entry *devtable_seg; u8 seg_idx, seg_shift; u64 reg_base, reg_val; + unsigned int n; u16 seg_mask; u32 seg_size; @@ -481,6 +482,14 @@ static struct dev_table_entry *get_dev_table_entry(struct amd_iommu *iommu, return NULL; iommu->devtable_segments[seg_idx] = devtable_seg; + /* + * Initialize all entries to paging mode 0, IR & IW cleared so + * that DMA requests are blocked. + */ + for (n = 0; n < seg_size / sizeof(struct dev_table_entry); n++) + devtable_seg[n].raw64[0] = + DTE_VALID | DTE_TRANSLATION_VALID; + if (!seg_idx) reg_base = AMD_DEV_TABLE_BASE_REG; else -- 2.39.2