iommu/vt-d: Don't copy translation tables if RTT bit needs to be changed
authorJoerg Roedel <jroedel@suse.de>
Fri, 12 Jun 2015 10:39:25 +0000 (12:39 +0200)
committerJoerg Roedel <jroedel@suse.de>
Tue, 16 Jun 2015 08:59:35 +0000 (10:59 +0200)
We can't change the RTT bit when translation is enabled, so
don't copy translation tables when we would change the bit
with our new root entry.

Tested-by: ZhenHua Li <zhen-hual@hp.com>
Tested-by: Baoquan He <bhe@redhat.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/intel-iommu.c

index 3b32aa55f27c2b742e1449b4481d486adbcc0466..ca7d37c3981fbbdae69b13a107f33d40a2c269e1 100644 (file)
@@ -2934,10 +2934,20 @@ static int copy_translation_tables(struct intel_iommu *iommu)
        unsigned long flags;
        u64 rtaddr_reg;
        int bus, ret;
-       bool ext;
+       bool new_ext, ext;
 
        rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
        ext        = !!(rtaddr_reg & DMA_RTADDR_RTT);
+       new_ext    = !!ecap_ecs(iommu->ecap);
+
+       /*
+        * The RTT bit can only be changed when translation is disabled,
+        * but disabling translation means to open a window for data
+        * corruption. So bail out and don't copy anything if we would
+        * have to change the bit.
+        */
+       if (new_ext != ext)
+               return -EINVAL;
 
        old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
        if (!old_rt_phys)