Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Revert mmiocfg heuristics and blacklist changes

This reverts commits 11012d419cfc0e0f78ca356aca03674217910124 and
40dd2d20f220eda1cd0da8ea3f0f9db8971ba237, which allowed us to use the
MMIO accesses for PCI config cycles even without the area being marked
reserved in the e820 memory tables.

Those changes were needed for EFI-environment Intel macs, but broke some
newer Intel 965 boards, so for now it's better to revert to our old
2.6.17 behaviour and at least avoid introducing any new breakage.

Andi Kleen has a set of patches that work with both EFI and the broken
Intel 965 boards, which will be applied once they get wider testing.

Cc: Arjan van de Ven <arjan@infradead.org>
Cc: Edgar Hucek <hostmaster@ed-soft.at>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

+82 -57
-2
Documentation/kernel-parameters.txt
··· 1189 1189 Mechanism 2. 1190 1190 nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI 1191 1191 Configuration 1192 - mmconf [IA-32,X86_64] Force MMCONFIG. This is useful 1193 - to override the builtin blacklist. 1194 1192 nomsi [MSI] If the PCI_MSI kernel config parameter is 1195 1193 enabled, this kernel boot option can be used to 1196 1194 disable the use of MSI interrupts system-wide.
+32
arch/i386/kernel/setup.c
··· 956 956 return 0; 957 957 } 958 958 959 + /* 960 + * This function checks if the entire range <start,end> is mapped with type. 961 + * 962 + * Note: this function only works correct if the e820 table is sorted and 963 + * not-overlapping, which is the case 964 + */ 965 + int __init 966 + e820_all_mapped(unsigned long s, unsigned long e, unsigned type) 967 + { 968 + u64 start = s; 969 + u64 end = e; 970 + int i; 971 + for (i = 0; i < e820.nr_map; i++) { 972 + struct e820entry *ei = &e820.map[i]; 973 + if (type && ei->type != type) 974 + continue; 975 + /* is the region (part) in overlap with the current region ?*/ 976 + if (ei->addr >= end || ei->addr + ei->size <= start) 977 + continue; 978 + /* if the region is at the beginning of <start,end> we move 979 + * start to the end of the region since it's ok until there 980 + */ 981 + if (ei->addr <= start) 982 + start = ei->addr + ei->size; 983 + /* if start is now at or beyond end, we're done, full 984 + * coverage */ 985 + if (start >= end) 986 + return 1; /* we're done */ 987 + } 988 + return 0; 989 + } 990 + 959 991 /* 960 992 * Find the highest page frame number we have available 961 993 */
-5
arch/i386/pci/common.c
··· 237 237 pci_probe &= ~PCI_PROBE_MMCONF; 238 238 return NULL; 239 239 } 240 - /* override DMI blacklist */ 241 - else if (!strcmp(str, "mmconf")) { 242 - pci_probe |= PCI_PROBE_MMCONF_FORCE; 243 - return NULL; 244 - } 245 240 #endif 246 241 else if (!strcmp(str, "noacpi")) { 247 242 acpi_noirq_set();
+10 -24
arch/i386/pci/mmconfig.c
··· 12 12 #include <linux/pci.h> 13 13 #include <linux/init.h> 14 14 #include <linux/acpi.h> 15 - #include <linux/dmi.h> 16 15 #include <asm/e820.h> 17 16 #include "pci.h" 18 17 ··· 187 188 } 188 189 } 189 190 190 - static int disable_mcfg(struct dmi_system_id *d) 191 - { 192 - printk("PCI: %s detected. Disabling MCFG.\n", d->ident); 193 - pci_probe &= ~PCI_PROBE_MMCONF; 194 - return 0; 195 - } 196 - 197 - static struct dmi_system_id __initdata dmi_bad_mcfg[] = { 198 - /* Has broken MCFG table that makes the system hang when used */ 199 - { 200 - .callback = disable_mcfg, 201 - .ident = "Intel D3C5105 SDV", 202 - .matches = { 203 - DMI_MATCH(DMI_BIOS_VENDOR, "Intel"), 204 - DMI_MATCH(DMI_BOARD_NAME, "D26928"), 205 - }, 206 - }, 207 - {} 208 - }; 209 - 210 191 void __init pci_mmcfg_init(void) 211 192 { 212 - dmi_check_system(dmi_bad_mcfg); 213 - 214 - if ((pci_probe & (PCI_PROBE_MMCONF_FORCE|PCI_PROBE_MMCONF)) == 0) 193 + if ((pci_probe & PCI_PROBE_MMCONF) == 0) 215 194 return; 216 195 217 196 acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); ··· 197 220 (pci_mmcfg_config == NULL) || 198 221 (pci_mmcfg_config[0].base_address == 0)) 199 222 return; 223 + 224 + if (!e820_all_mapped(pci_mmcfg_config[0].base_address, 225 + pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, 226 + E820_RESERVED)) { 227 + printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", 228 + pci_mmcfg_config[0].base_address); 229 + printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); 230 + return; 231 + } 200 232 201 233 printk(KERN_INFO "PCI: Using MMCONFIG\n"); 202 234 raw_pci_ops = &pci_mmcfg;
+1 -2
arch/i386/pci/pci.h
··· 16 16 #define PCI_PROBE_CONF1 0x0002 17 17 #define PCI_PROBE_CONF2 0x0004 18 18 #define PCI_PROBE_MMCONF 0x0008 19 - #define PCI_PROBE_MMCONF_FORCE 0x0010 20 - #define PCI_PROBE_MASK 0x00ff 19 + #define PCI_PROBE_MASK 0x000f 21 20 22 21 #define PCI_NO_SORT 0x0100 23 22 #define PCI_BIOS_SORT 0x0200
+29
arch/x86_64/kernel/e820.c
··· 108 108 return 0; 109 109 } 110 110 111 + /* 112 + * This function checks if the entire range <start,end> is mapped with type. 113 + * 114 + * Note: this function only works correct if the e820 table is sorted and 115 + * not-overlapping, which is the case 116 + */ 117 + int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type) 118 + { 119 + int i; 120 + for (i = 0; i < e820.nr_map; i++) { 121 + struct e820entry *ei = &e820.map[i]; 122 + if (type && ei->type != type) 123 + continue; 124 + /* is the region (part) in overlap with the current region ?*/ 125 + if (ei->addr >= end || ei->addr + ei->size <= start) 126 + continue; 127 + 128 + /* if the region is at the beginning of <start,end> we move 129 + * start to the end of the region since it's ok until there 130 + */ 131 + if (ei->addr <= start) 132 + start = ei->addr + ei->size; 133 + /* if start is now at or beyond end, we're done, full coverage */ 134 + if (start >= end) 135 + return 1; /* we're done */ 136 + } 137 + return 0; 138 + } 139 + 111 140 /* 112 141 * Find a free area in a specific range. 113 142 */
+10 -24
arch/x86_64/pci/mmconfig.c
··· 9 9 #include <linux/init.h> 10 10 #include <linux/acpi.h> 11 11 #include <linux/bitmap.h> 12 - #include <linux/dmi.h> 13 12 #include <asm/e820.h> 14 13 15 14 #include "pci.h" ··· 164 165 } 165 166 } 166 167 167 - static int disable_mcfg(struct dmi_system_id *d) 168 - { 169 - printk("PCI: %s detected. Disabling MCFG.\n", d->ident); 170 - pci_probe &= ~PCI_PROBE_MMCONF; 171 - return 0; 172 - } 173 - 174 - static struct dmi_system_id __initdata dmi_bad_mcfg[] = { 175 - /* Has broken MCFG table that makes the system hang when used */ 176 - { 177 - .callback = disable_mcfg, 178 - .ident = "Intel D3C5105 SDV", 179 - .matches = { 180 - DMI_MATCH(DMI_BIOS_VENDOR, "Intel"), 181 - DMI_MATCH(DMI_BOARD_NAME, "D26928"), 182 - }, 183 - }, 184 - {} 185 - }; 186 - 187 168 void __init pci_mmcfg_init(void) 188 169 { 189 170 int i; 190 171 191 - dmi_check_system(dmi_bad_mcfg); 192 - 193 - if ((pci_probe & (PCI_PROBE_MMCONF|PCI_PROBE_MMCONF_FORCE)) == 0) 172 + if ((pci_probe & PCI_PROBE_MMCONF) == 0) 194 173 return; 195 174 196 175 acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); ··· 176 199 (pci_mmcfg_config == NULL) || 177 200 (pci_mmcfg_config[0].base_address == 0)) 178 201 return; 202 + 203 + if (!e820_all_mapped(pci_mmcfg_config[0].base_address, 204 + pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, 205 + E820_RESERVED)) { 206 + printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", 207 + pci_mmcfg_config[0].base_address); 208 + printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); 209 + return; 210 + } 179 211 180 212 /* RED-PEN i386 doesn't do _nocache right now */ 181 213 pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);