]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
x86: Block DMA from unlisted devices in AMD IOMMU
authorJan Kiszka <jan.kiszka@siemens.com>
Sat, 7 May 2016 17:02:28 +0000 (19:02 +0200)
committerJan Kiszka <jan.kiszka@siemens.com>
Mon, 9 May 2016 18:03:06 +0000 (20:03 +0200)
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 <jan.kiszka@siemens.com>
hypervisor/arch/x86/amd_iommu.c

index 65662a2d5a6afe6137d748d0a539a2660a396fe6..31e78f4b6d7317be5a071013f1e56d73315a4a43 100644 (file)
@@ -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