Commit 44de0203fab205417b24322272c53ee0883c36e7
Committed by
Andi Kleen
1 parent
faed197b7b
Exists in
master
and in
4 other branches
[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 | { |