aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2011-08-16 15:17:06 +0100
committerJan Beulich <jbeulich@novell.com>2011-08-16 15:17:06 +0100
commitcdfb1853bb2ddfee5ee7306ee48a882946cba2ff (patch)
tree62178ca8ac70a2b16becd11c3ec7127b48c21458
parenta357afd6524b99558cef0617ddacd815fb787b5a (diff)
downloadxen-cdfb1853bb2ddfee5ee7306ee48a882946cba2ff.tar.gz
xen-cdfb1853bb2ddfee5ee7306ee48a882946cba2ff.tar.bz2
xen-cdfb1853bb2ddfee5ee7306ee48a882946cba2ff.zip
VT-d: don't reject valid DMAR/ATSR tables on systems with multiple PCI segments
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
-rw-r--r--xen/drivers/passthrough/vtd/dmar.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/xen/drivers/passthrough/vtd/dmar.c b/xen/drivers/passthrough/vtd/dmar.c
index 0bc10ba047..c9a51e4f7e 100644
--- a/xen/drivers/passthrough/vtd/dmar.c
+++ b/xen/drivers/passthrough/vtd/dmar.c
@@ -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 )