/*
  * Functions for accessing PCI configuration space with MMCONFIG accesses
  */
+static u32 get_base_addr(unsigned int seg, int bus)
+{
+       int cfg_num = -1;
+       struct acpi_table_mcfg_config *cfg;
+
+       while (1) {
+               ++cfg_num;
+               if (cfg_num >= pci_mmcfg_config_num) {
+                       /* something bad is going on, no cfg table is found. */
+                       /* so we fall back to the old way we used to do this */
+                       /* and just rely on the first entry to be correct. */
+                       return pci_mmcfg_config[0].base_address;
+               }
+               cfg = &pci_mmcfg_config[cfg_num];
+               if (cfg->pci_segment_group_number != seg)
+                       continue;
+               if ((cfg->start_bus_number <= bus) &&
+                   (cfg->end_bus_number >= bus))
+                       return cfg->base_address;
+       }
+}
 
-static inline void pci_exp_set_dev_base(int bus, int devfn)
+static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn)
 {
-       u32 dev_base = pci_mmcfg_config[0].base_address | (bus << 20) | (devfn << 12);
+       u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12);
        if (dev_base != mmcfg_last_accessed_device) {
                mmcfg_last_accessed_device = dev_base;
                set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);
 
        spin_lock_irqsave(&pci_config_lock, flags);
 
-       pci_exp_set_dev_base(bus, devfn);
+       pci_exp_set_dev_base(seg, bus, devfn);
 
        switch (len) {
        case 1:
 
        spin_lock_irqsave(&pci_config_lock, flags);
 
-       pci_exp_set_dev_base(bus, devfn);
+       pci_exp_set_dev_base(seg, bus, devfn);
 
        switch (len) {
        case 1: