From: Jan Beulich Date: Fri, 7 Oct 2011 15:50:50 +0000 (+0200) Subject: VT-d: don't reject possibly valid DRHD or RMRR X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=fd1e17183b657505887680d156f83efd82c3df3e;p=xen.git VT-d: don't reject possibly valid DRHD or RMRR If a non-zero PCI segment isn't accessible during Xen boot (because firmware decided to not enter the necessary MMIO space into the E820 table), devices referred to on those segments through DRHD or RMRR structures should not be rejected just because the devices can't be found. This is in line with what is being done in at least one other case already: Systems with more than one PCI segment (usually high end ones) are assumed to have valid firmware provided data, while systems with just segment 0 continue to have their firmware tables validated. Signed-off-by: Jan Beulich Acked-by: "Kay, Allen M" --- diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index fbad1c2258..9fecf80188 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -53,6 +53,11 @@ static inline struct pci_seg *get_pseg(u16 seg) return radix_tree_lookup(&pci_segments, seg); } +bool_t pci_known_segment(u16 seg) +{ + return get_pseg(seg) != NULL; +} + static struct pci_seg *alloc_pseg(u16 seg) { struct pci_seg *pseg = get_pseg(seg); diff --git a/xen/drivers/passthrough/vtd/dmar.c b/xen/drivers/passthrough/vtd/dmar.c index 35c8555c17..99f584ae94 100644 --- a/xen/drivers/passthrough/vtd/dmar.c +++ b/xen/drivers/passthrough/vtd/dmar.c @@ -442,10 +442,14 @@ acpi_parse_one_drhd(struct acpi_dmar_entry_header *header) else { u8 b, d, f; - int i, invalid_cnt = 0; + unsigned int i = 0, invalid_cnt = 0; void *p; - for ( i = 0, p = dev_scope_start; i < dmaru->scope.devices_cnt; + /* Skip checking if segment is not accessible yet. */ + if ( !pci_known_segment(drhd->segment) ) + i = UINT_MAX; + + for ( p = dev_scope_start; i < dmaru->scope.devices_cnt; i++, p += ((struct acpi_dev_scope *)p)->length ) { if ( ((struct acpi_dev_scope *)p)->dev_type == ACPI_DEV_IOAPIC || @@ -546,7 +550,12 @@ acpi_parse_one_rmrr(struct acpi_dmar_entry_header *header) else { u8 b, d, f; - int i, ignore = 0; + bool_t ignore = 0; + unsigned int i = 0; + + /* Skip checking if segment is not accessible yet. */ + if ( !pci_known_segment(rmrr->segment) ) + i = UINT_MAX; for ( i = 0; i < rmrru->scope.devices_cnt; i++ ) { diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h index 10a76f0829..462b4505b1 100644 --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -82,6 +82,7 @@ enum { DEV_TYPE_PCI, }; +bool_t pci_known_segment(u16 seg); int pci_device_detect(u16 seg, u8 bus, u8 dev, u8 func); int scan_pci_devices(void); int pdev_type(u16 seg, u8 bus, u8 devfn);