]> xenbits.xensource.com Git - people/vhanquez/xen.git/commitdiff
VT-d: don't reject valid DMAR/ATSR tables on systems with multiple PCI segments
authorJan Beulich <jbeulich@novell.com>
Tue, 16 Aug 2011 14:17:06 +0000 (15:17 +0100)
committerJan Beulich <jbeulich@novell.com>
Tue, 16 Aug 2011 14:17:06 +0000 (15:17 +0100)
On multi-PCI-segment systems, each segment has to be expected to have
an include-all DRHD and an all-ports ATSR, so the firmware consistency
check incorrectly rejects valid configurations there (which is
particularly problematic when the firmware also pre-enabled x2apic
mode, as the system will panic in that case due to being unable to
enable interrupt remapping). Thus constrain the check to just segment
0 for now; once full multi-segment support is there (which I'm working
on), it can be revisited whether we'd want to track this per segment,
or whether we trust the firmware of such large systems.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
xen-unstable changeset:   23763:8f647d409196
xen-unstable date:        Sat Aug 13 10:12:49 2011 +0100

xen/drivers/passthrough/vtd/dmar.c

index 0bc10ba0479b7e8ddad6adce0ababb5dcabf83dd..c9a51e4f7e2f7457b8e20689ccb1caf1298ff8c6 100644 (file)
@@ -426,13 +426,14 @@ acpi_parse_one_drhd(struct acpi_dmar_entry_header *header)
         if ( iommu_verbose )
             dprintk(VTDPREFIX, "  flags: INCLUDE_ALL\n");
         /* Only allow one INCLUDE_ALL */
-        if ( include_all )
+        if ( drhd->segment == 0 && include_all )
         {
             dprintk(XENLOG_WARNING VTDPREFIX,
                     "Only one INCLUDE_ALL device scope is allowed\n");
             ret = -EINVAL;
         }
-        include_all = 1;
+        if ( drhd->segment == 0 )
+            include_all = 1;
     }
 
     if ( ret )
@@ -632,13 +633,14 @@ acpi_parse_one_atsr(struct acpi_dmar_entry_header *header)
         if ( iommu_verbose )
             dprintk(VTDPREFIX, "  flags: ALL_PORTS\n");
         /* Only allow one ALL_PORTS */
-        if ( all_ports )
+        if ( atsr->segment == 0 && all_ports )
         {
             dprintk(XENLOG_WARNING VTDPREFIX,
                     "Only one ALL_PORTS device scope is allowed\n");
             ret = -EINVAL;
         }
-        all_ports = 1;
+        if ( atsr->segment == 0 )
+            all_ports = 1;
     }
 
     if ( ret )