[PATCH] x86: Only include address ranges marked as E820_RAM in kernel direct mapping

From: Jacob Shin
Date: Thu Dec 15 2011 - 10:56:14 EST


Currently, 0 ~ max_low_pfn is first mapped, then 4GB ~ max_pfn is
mapped. On some systems that have large memory holes that occur
within those two regions, we end up with PATs that mark pages that
are not backed by actual DRAM -- as cacheable.

This patch first maps 0 ~ 1MB ISA region, then iterates over the
E820 to map useable E820_RAM ranges.

Cc: stable@xxxxxxxxxx # > 2.6.32
Signed-off-by: Jacob Shin <jacob.shin@xxxxxxx>
Reviewed-by: Andreas Herrmann <Andreas.Herrmann3@xxxxxxx>
---
arch/x86/kernel/setup.c | 29 ++++++++++++++++++++++++++---
1 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index cf0ef98..eae6b41 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -691,6 +691,8 @@ early_param("reservelow", parse_reservelow);

void __init setup_arch(char **cmdline_p)
{
+ int i;
+
#ifdef CONFIG_X86_32
memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
visws_early_detect();
@@ -932,13 +934,34 @@ void __init setup_arch(char **cmdline_p)
init_gbpages();

/* max_pfn_mapped is updated here */
- max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT);
+ max_low_pfn_mapped = init_memory_mapping(0, 0x100000);
max_pfn_mapped = max_low_pfn_mapped;

+ for (i = 0; i < e820.nr_map; i++) {
+ struct e820entry *ei = &e820.map[i];
+ u64 start = ei->addr;
+ u64 end = ei->addr + ei->size;
+
+ if (ei->type != E820_RAM)
+ continue;
+
+ if (start < 0x100000)
+ continue;
+#ifdef CONFIG_X86_32
+ if ((start >> PAGE_SHIFT) >= max_low_pfn)
+ continue;
+
+ if ((end >> PAGE_SHIFT) > max_low_pfn)
+ end = max_low_pfn << PAGE_SHIFT;
+#endif
+ max_pfn_mapped = init_memory_mapping(start, end);
+
+ if ((end >> PAGE_SHIFT) == max_low_pfn)
+ max_low_pfn_mapped = max_pfn_mapped;
+ }
+
#ifdef CONFIG_X86_64
if (max_pfn > max_low_pfn) {
- max_pfn_mapped = init_memory_mapping(1UL<<32,
- max_pfn<<PAGE_SHIFT);
/* can we preseve max_low_pfn ?*/
max_low_pfn = max_pfn;
}
--
1.7.1


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/