Description: AMD,IOMMU: Disable IOMMU if SATA Combined mode is on
 AMD's SP5100 chipset can be placed into SATA Combined mode
 that may cause prevent dom0 from booting when IOMMU is
 enabled and per-device interrupt remapping table is used.
 While SP5100 erratum 28 requires BIOSes to disable this mode,
 some may still use it.
 .
 This patch checks whether this mode is on and, if per-device
 table is in use, disables IOMMU.
From: Jan Beulich <jbeulich@suse.com>
From: Boris Ostrovsky <boris.ostrovsky@amd.com>
Origin: upstream, commit:23450:5c0fe82d6060
Id: CVE-2013-0153
---
--- a/xen/drivers/passthrough/amd/iommu_init.c	Tue Feb 05 15:35:44 2013 +0100
+++ b/xen/drivers/passthrough/amd/iommu_init.c	Tue Feb 05 15:36:11 2013 +0100
@@ -897,12 +897,45 @@
     return 0;
 }
 
+/* Check whether SP5100 SATA Combined mode is on */
+static bool_t __init amd_sp5100_erratum28(void)
+{
+    u32 bus, id;
+    u16 vendor_id, dev_id;
+    u8 byte;
+
+    for (bus = 0; bus < 256; bus++)
+    {
+        id = pci_conf_read32(bus, 0x14, 0, PCI_VENDOR_ID);
+
+        vendor_id = id & 0xffff;
+        dev_id = (id >> 16) & 0xffff;
+
+        /* SP5100 SMBus module sets Combined mode on */
+        if (vendor_id != 0x1002 || dev_id != 0x4385)
+            continue;
+
+        byte = pci_conf_read8(bus, 0x14, 0, 0xad);
+        if ( (byte >> 3) & 1 )
+        {
+            printk(XENLOG_WARNING "AMD-Vi: SP5100 erratum 28 detected, disabling IOMMU.\n"
+                   "If possible, disable SATA Combined mode in BIOS or contact your vendor for BIOS update.\n");
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
 int __init amd_iommu_init(void)
 {
     struct amd_iommu *iommu;
 
     BUG_ON( !iommu_found() );
 
+    if ( amd_iommu_perdev_intremap && amd_sp5100_erratum28() )
+        goto error_out;
+
     irq_to_iommu = xmalloc_array(struct amd_iommu *, nr_irqs);
     if ( irq_to_iommu == NULL )
         goto error_out;
