Commit 44de0203fab205417b24322272c53ee0883c36e7

Authored by OGAWA Hirofumi
Committed by Andi Kleen
1 parent faed197b7b

[PATCH] mmconfig: Reject a broken MCFG tables on Asus etc

This rejects broken MCFG tables on Asus. When the table
looks bogus just disable mmconfig

Arjan and Andi suggested this.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: Andi Kleen <ak@suse.de>

Showing 3 changed files with 37 additions and 46 deletions Side-by-side Diff

arch/i386/pci/mmconfig-shared.c
... ... @@ -197,6 +197,26 @@
197 197 }
198 198 }
199 199  
  200 +static void __init pci_mmcfg_reject_broken(void)
  201 +{
  202 + typeof(pci_mmcfg_config[0]) *cfg = &pci_mmcfg_config[0];
  203 +
  204 + /*
  205 + * Handle more broken MCFG tables on Asus etc.
  206 + * They only contain a single entry for bus 0-0.
  207 + */
  208 + if (pci_mmcfg_config_num == 1 &&
  209 + cfg->pci_segment == 0 &&
  210 + (cfg->start_bus_number | cfg->end_bus_number) == 0) {
  211 + kfree(pci_mmcfg_config);
  212 + pci_mmcfg_config = NULL;
  213 + pci_mmcfg_config_num = 0;
  214 +
  215 + printk(KERN_ERR "PCI: start and end of bus number is 0. "
  216 + "Rejected as broken MCFG.");
  217 + }
  218 +}
  219 +
200 220 void __init pci_mmcfg_init(int type)
201 221 {
202 222 int known_bridge = 0;
203 223  
... ... @@ -207,8 +227,10 @@
207 227 if (type == 1 && pci_mmcfg_check_hostbridge())
208 228 known_bridge = 1;
209 229  
210   - if (!known_bridge)
  230 + if (!known_bridge) {
211 231 acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
  232 + pci_mmcfg_reject_broken();
  233 + }
212 234  
213 235 if ((pci_mmcfg_config_num == 0) ||
214 236 (pci_mmcfg_config == NULL) ||
arch/i386/pci/mmconfig.c
... ... @@ -47,15 +47,6 @@
47 47 return cfg->address;
48 48 }
49 49  
50   - /* Handle more broken MCFG tables on Asus etc.
51   - They only contain a single entry for bus 0-0. Assume
52   - this applies to all busses. */
53   - cfg = &pci_mmcfg_config[0];
54   - if (pci_mmcfg_config_num == 1 &&
55   - cfg->pci_segment == 0 &&
56   - (cfg->start_bus_number | cfg->end_bus_number) == 0)
57   - return cfg->address;
58   -
59 50 /* Fall back to type 0 */
60 51 return 0;
61 52 }
arch/x86_64/pci/mmconfig.c
... ... @@ -28,39 +28,6 @@
28 28 };
29 29 static struct mmcfg_virt *pci_mmcfg_virt;
30 30  
31   -static inline int mcfg_broken(void)
32   -{
33   - struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[0];
34   -
35   - /* Handle more broken MCFG tables on Asus etc.
36   - They only contain a single entry for bus 0-0. Assume
37   - this applies to all busses. */
38   - if (pci_mmcfg_config_num == 1 &&
39   - cfg->pci_segment_group_number == 0 &&
40   - (cfg->start_bus_number | cfg->end_bus_number) == 0)
41   - return 1;
42   - return 0;
43   -}
44   -
45   -static void __iomem *mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
46   -{
47   - void __iomem *addr;
48   - u32 size;
49   -
50   - if (mcfg_broken())
51   - size = 256 << 20;
52   - else
53   - size = (cfg->end_bus_number + 1) << 20;
54   -
55   - addr = ioremap_nocache(cfg->base_address, size);
56   - if (addr) {
57   - printk(KERN_INFO "PCI: Using MMCONFIG at %x - %x\n",
58   - cfg->base_address,
59   - cfg->base_address + size - 1);
60   - }
61   - return addr;
62   -}
63   -
64 31 static char __iomem *get_virt(unsigned int seg, unsigned bus)
65 32 {
66 33 int cfg_num = -1;
... ... @@ -78,9 +45,6 @@
78 45 return pci_mmcfg_virt[cfg_num].virt;
79 46 }
80 47  
81   - if (mcfg_broken())
82   - return pci_mmcfg_virt[0].virt;
83   -
84 48 /* Fall back to type 0 */
85 49 return NULL;
86 50 }
... ... @@ -159,6 +123,20 @@
159 123 .read = pci_mmcfg_read,
160 124 .write = pci_mmcfg_write,
161 125 };
  126 +
  127 +static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
  128 +{
  129 + void __iomem *addr;
  130 + u32 size;
  131 +
  132 + size = (cfg->end_bus_number + 1) << 20;
  133 + addr = ioremap_nocache(cfg->address, size);
  134 + if (addr) {
  135 + printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n",
  136 + cfg->address, cfg->address + size - 1);
  137 + }
  138 + return addr;
  139 +}
162 140  
163 141 int __init pci_mmcfg_arch_init(void)
164 142 {