VT-d: don't reject possibly valid DRHD or RMRR
authorJan Beulich <jbeulich@suse.com>
Fri, 7 Oct 2011 15:50:50 +0000 (17:50 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 7 Oct 2011 15:50:50 +0000 (17:50 +0200)
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 <jbeulich@suse.com>
Acked-by: "Kay, Allen M" <allen.m.kay@intel.com>
xen/drivers/passthrough/pci.c
xen/drivers/passthrough/vtd/dmar.c
xen/include/xen/pci.h

index fbad1c225869ba9a881eae9ea11efe3008b42f0a..9fecf801886bf8163885914c46d5d11f429ab866 100644 (file)
@@ -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);
index 35c8555c17984e388d09978ea615c60e21530fcc..99f584ae947de530dae122987e30b63a8ad82fba 100644 (file)
@@ -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++ )
         {
index 10a76f0829fa3109f8913a151a09152fb8762b6e..462b4505b197295ff77f0f1b0d417fb3309694e3 100644 (file)
@@ -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);