public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [patch] Ignore MCFG if the mmconfig area isn't reserved in the e820 table
@ 2006-03-23 18:22 Arjan van de Ven
  2006-03-23 17:56 ` Andi Kleen
  0 siblings, 1 reply; 21+ messages in thread
From: Arjan van de Ven @ 2006-03-23 18:22 UTC (permalink / raw)
  To: linux-kernel; +Cc: akpm, ak

Hi,

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. 

Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>

diff -purN linux-2.6.16/arch/i386/kernel/setup.c linux-2.6.16-mmconfig/arch/i386/kernel/setup.c
--- linux-2.6.16/arch/i386/kernel/setup.c	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-mmconfig/arch/i386/kernel/setup.c	2006-03-23 17:26:13.000000000 +0100
@@ -1377,6 +1377,31 @@ static void __init register_memory(void)
 		pci_mem_start, gapstart, gapsize);
 }
 
+
+
+/*
+ * Check if an address is reserved in the e820 map
+ */
+int is_e820_reserved(u64 address)
+{
+	int	      i;
+	i = e820.nr_map;
+	while (--i >= 0) {
+		unsigned long long start = e820.map[i].addr;
+		unsigned long long end = start + e820.map[i].size;
+
+		if (address <=end && address >= start) {
+			if (e820.map[i].type == E820_RESERVED)
+				return 1;
+			else
+				return 0;
+		}
+	}
+	return 0;
+}
+
+
+
 /* Use inline assembly to define this because the nops are defined 
    as inline assembly strings in the include files and we cannot 
    get them easily into strings. */
diff -purN linux-2.6.16/arch/i386/pci/mmconfig.c linux-2.6.16-mmconfig/arch/i386/pci/mmconfig.c
--- linux-2.6.16/arch/i386/pci/mmconfig.c	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-mmconfig/arch/i386/pci/mmconfig.c	2006-03-23 17:26:13.000000000 +0100
@@ -12,6 +12,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/acpi.h>
+#include <asm/e820.h>
 #include "pci.h"
 
 #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
@@ -183,6 +184,17 @@ static int __init pci_mmcfg_init(void)
 	    (pci_mmcfg_config[0].base_address == 0))
 		goto out;
 
+	/*
+	 * several bioses have a buggy MCFG table. While this is hard
+	 * to test for conclusively, we know the value is defective
+	 * if the memory isn't marked reserved in the e820 table
+	 */
+	if (!is_e820_reserved(pci_mmcfg_config[0].base_address)) {
+		printk(KERN_INFO "PCI: BIOS Bug: MCFG area is not reserved\n");
+		printk(KERN_INFO "PCI: Not using MMCONFIG.\n");
+		goto out;
+	}
+
 	printk(KERN_INFO "PCI: Using MMCONFIG\n");
 	raw_pci_ops = &pci_mmcfg;
 	pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
diff -purN linux-2.6.16/arch/x86_64/kernel/e820.c linux-2.6.16-mmconfig/arch/x86_64/kernel/e820.c
--- linux-2.6.16/arch/x86_64/kernel/e820.c	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-mmconfig/arch/x86_64/kernel/e820.c	2006-03-23 17:27:04.000000000 +0100
@@ -639,3 +639,25 @@ __init void e820_setup_gap(void)
 	printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
 		pci_mem_start, gapstart, gapsize);
 }
+
+/*
+ * Check if an address is reserved in the e820 map
+ */
+int is_e820_reserved(u64 address)
+{
+	int	      i;
+	i = e820.nr_map;
+	while (--i >= 0) {
+		unsigned long long start = e820.map[i].addr;
+		unsigned long long end = start + e820.map[i].size;
+
+		if (address <=end && address >= start) {
+			if (e820.map[i].type == E820_RESERVED)
+				return 1;
+			else
+				return 0;
+		}
+	}
+	return 0;
+}
+
diff -purN linux-2.6.16/arch/x86_64/pci/mmconfig.c linux-2.6.16-mmconfig/arch/x86_64/pci/mmconfig.c
--- linux-2.6.16/arch/x86_64/pci/mmconfig.c	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-mmconfig/arch/x86_64/pci/mmconfig.c	2006-03-23 17:34:06.000000000 +0100
@@ -9,6 +9,7 @@
 #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 +162,19 @@ static int __init pci_mmcfg_init(void)
 	    (pci_mmcfg_config[0].base_address == 0))
 		return 0;
 
+
+	/*
+	 * several bioses have a buggy MCFG table. While this is hard
+	 * to test for conclusively, we know the value is defective
+	 * if the memory isn't marked reserved in the e820 table
+	 */
+	if (!is_e820_reserved(pci_mmcfg_config[0].base_address)) {
+		printk(KERN_INFO "PCI: BIOS Bug: MCFG area is not reserved\n");
+		printk(KERN_INFO "PCI: Not using MMCONFIG.\n");
+		return 0;
+	}
+
+
 	/* 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) {
diff -purN linux-2.6.16/include/asm-i386/e820.h linux-2.6.16-mmconfig/include/asm-i386/e820.h
--- linux-2.6.16/include/asm-i386/e820.h	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-mmconfig/include/asm-i386/e820.h	2006-03-23 17:26:13.000000000 +0100
@@ -35,6 +35,9 @@ struct e820map {
 };
 
 extern struct e820map e820;
+
+extern int is_e820_reserved(u64 address);
+
 #endif/*!__ASSEMBLY__*/
 
 #endif/*__E820_HEADER*/
diff -purN linux-2.6.16/include/asm-x86_64/e820.h linux-2.6.16-mmconfig/include/asm-x86_64/e820.h
--- linux-2.6.16/include/asm-x86_64/e820.h	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-mmconfig/include/asm-x86_64/e820.h	2006-03-23 17:27:41.000000000 +0100
@@ -47,6 +47,7 @@ extern void contig_e820_setup(void); 
 extern unsigned long e820_end_of_ram(void);
 extern void e820_reserve_resources(void);
 extern void e820_print_map(char *who);
+extern int is_e820_reserved(u64 address);
 extern int e820_mapped(unsigned long start, unsigned long end, unsigned type);
 
 extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end);


^ permalink raw reply	[flat|nested] 21+ messages in thread
* Re: [patch] Ignore MCFG if the mmconfig area isn't reserved in the e820 table.
@ 2006-05-18  2:53 Konrad Rzeszutek
  2006-05-18 13:03 ` Arjan van de Ven
  0 siblings, 1 reply; 21+ messages in thread
From: Konrad Rzeszutek @ 2006-05-18  2:53 UTC (permalink / raw)
  To: linux-kernel, konradr, konradr, arjan

> Hi,
> 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. 
> [snip]

Arjan,

I am not sure if your analysis and your solution to the problem is correct. 
It was my understanding that any memory NOT defined in the E820 tables 
is NOT considered system memory. Therefore memory addresses defined in the 
ACPI MCFG table do not have to show up in the E820 table.

Also the ACPI spec v3.0 (pg 405 of PDF, section 14.2, titled:
"E820 Assumptions and Limitations") agrees with this:

"The BIOS does not return a range description for the memory mapping
of PCI devices, ISA Option ROMs, and the ISA PNP cards because the OS
has mechanisms available to detect them."

(The ACPI v2.0c spec has this in section 15.2).

Obviously specifications are sometimes outdated, or assumptions are made in
some specifications which are not in other specification, so I was wondering 
if you could tell me which specification defines that the memory addresses 
in ACPI MCFG table have to be reserved in the E820 tables?

If this is not a specification issue, I was wondering if perhaps for the 
machines you refer to, their BIOS bug is that the E820 have memory ranges
which also encompass what MMCONF points to?

Thanks!

Konrad Rzeszutek
IBM, (617)-693-1718

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2006-05-18 18:15 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-23 18:22 [patch] Ignore MCFG if the mmconfig area isn't reserved in the e820 table Arjan van de Ven
2006-03-23 17:56 ` Andi Kleen
2006-03-23 19:02   ` Arjan van de Ven
2006-03-23 19:15     ` Arjan van de Ven
2006-03-24 12:19       ` Andi Kleen
2006-03-24 13:36         ` Arjan van de Ven
2006-03-24 21:25         ` Greg KH
2006-03-24 15:22       ` [patch] Ignore MCFG if the mmconfig area isn't reserved in thee820 table Ashok Raj
2006-03-24 15:24         ` Arjan van de Ven
2006-03-24 15:39           ` Andi Kleen
2006-03-24 15:42             ` Arjan van de Ven
2006-03-24 15:48               ` Ashok Raj
2006-03-24 15:48                 ` Arjan van de Ven
2006-03-24 15:48               ` Andi Kleen
2006-03-24 15:50                 ` Arjan van de Ven
  -- strict thread matches above, loose matches on Subject: below --
2006-05-18  2:53 [patch] Ignore MCFG if the mmconfig area isn't reserved in the e820 table Konrad Rzeszutek
2006-05-18 13:03 ` Arjan van de Ven
2006-05-18 15:56   ` Konrad Rzeszutek
2006-05-18 16:46     ` Arjan van de Ven
2006-05-18 18:06       ` Petr Vandrovec
2006-05-18 18:15         ` Arjan van de Ven

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox