forked from mirrors/linux
		
	[PATCH] i386/x86-64: Check that MCFG points to an e820 reserved area
This patch introduces a user for the e820_all_mapped function: There have been several machines that don't have a working MMCONFIG, often because of a buggy MCFG table in the ACPI bios. This patch adds a simple sanity check that detects a whole bunch of these cases, and when it detects it, linux now boots rather than crash-and-burns. The accuracy of this detection can in principle be improved if there was a "is this entire range in e820 with THIS attribute", but no such function exist and the complexity needed for this is not really worth it; this simple check already catches most cases anyway. Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
		
							parent
							
								
									952223683e
								
							
						
					
					
						commit
						946f2ee5c7
					
				
					 2 changed files with 21 additions and 0 deletions
				
			
		|  | @ -12,8 +12,11 @@ | |||
| #include <linux/pci.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/acpi.h> | ||||
| #include <asm/e820.h> | ||||
| #include "pci.h" | ||||
| 
 | ||||
| #define MMCONFIG_APER_SIZE (256*1024*1024) | ||||
| 
 | ||||
| #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) | ||||
| 
 | ||||
| /* The base address of the last MMCONFIG device accessed */ | ||||
|  | @ -183,6 +186,14 @@ void __init pci_mmcfg_init(void) | |||
| 	    (pci_mmcfg_config[0].base_address == 0)) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | ||||
| 			pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, | ||||
| 			E820_RESERVED)) { | ||||
| 		printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); | ||||
| 		printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	printk(KERN_INFO "PCI: Using MMCONFIG\n"); | ||||
| 	raw_pci_ops = &pci_mmcfg; | ||||
| 	pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; | ||||
|  |  | |||
|  | @ -9,6 +9,8 @@ | |||
| #include <linux/init.h> | ||||
| #include <linux/acpi.h> | ||||
| #include <linux/bitmap.h> | ||||
| #include <asm/e820.h> | ||||
| 
 | ||||
| #include "pci.h" | ||||
| 
 | ||||
| #define MMCONFIG_APER_SIZE (256*1024*1024) | ||||
|  | @ -161,6 +163,14 @@ void __init pci_mmcfg_init(void) | |||
| 	    (pci_mmcfg_config[0].base_address == 0)) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | ||||
| 			pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, | ||||
| 			E820_RESERVED)) { | ||||
| 		printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); | ||||
| 		printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	/* RED-PEN i386 doesn't do _nocache right now */ | ||||
| 	pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); | ||||
| 	if (pci_mmcfg_virt == NULL) { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Arjan van de Ven
						Arjan van de Ven