aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <andi@firstfloor.org>2008-03-11 22:53:30 -0400
committerIngo Molnar <mingo@elte.hu>2008-04-17 11:41:30 -0400
commitf5c24a7fd0798d636af184cc7032e7e0cb149112 (patch)
tree398edfb6ebff645c3e7f84848c6d84eeb0d2d02d
parentc9caa02c529d5e113e40cbc77254558fcdfa4215 (diff)
x86: don't use large pages to map the first 2/4MB of memory
Intel recommends to not use large pages for the first 1MB of the physical memory because there are fixed size MTRRs there which cause splitups in the TLBs. On AMD doing so is also a good idea. The implementation is a little different between 32bit and 64bit. On 32bit I just taught the initial page table set up about this because it was very simple to do. This also has the advantage that the risk of a prefetch ever seeing the page even if it only exists for a short time is minimized. On 64bit that is not quite possible, so use set_memory_4k() a little later (in check_bugs) instead. Signed-off-by: Andi Kleen <ak@suse.de> Acked-by: andreas.herrmann3@amd.com Cc: mingo@elte.hu Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/kernel/bugs_64.c12
-rw-r--r--arch/x86/mm/init_32.c7
2 files changed, 18 insertions, 1 deletions
diff --git a/arch/x86/kernel/bugs_64.c b/arch/x86/kernel/bugs_64.c
index 60207e999a04..9a3ed0649d4e 100644
--- a/arch/x86/kernel/bugs_64.c
+++ b/arch/x86/kernel/bugs_64.c
@@ -9,6 +9,7 @@
9#include <asm/bugs.h> 9#include <asm/bugs.h>
10#include <asm/processor.h> 10#include <asm/processor.h>
11#include <asm/mtrr.h> 11#include <asm/mtrr.h>
12#include <asm/cacheflush.h>
12 13
13void __init check_bugs(void) 14void __init check_bugs(void)
14{ 15{
@@ -18,4 +19,15 @@ void __init check_bugs(void)
18 print_cpu_info(&boot_cpu_data); 19 print_cpu_info(&boot_cpu_data);
19#endif 20#endif
20 alternative_instructions(); 21 alternative_instructions();
22
23 /*
24 * Make sure the first 2MB area is not mapped by huge pages
25 * There are typically fixed size MTRRs in there and overlapping
26 * MTRRs into large pages causes slow downs.
27 *
28 * Right now we don't do that with gbpages because there seems
29 * very little benefit for that case.
30 */
31 if (!direct_gbpages)
32 set_memory_4k((unsigned long)__va(0), 1);
21} 33}
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index fc3ace2e88f1..1500dc8d63e4 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -181,8 +181,13 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
181 /* 181 /*
182 * Map with big pages if possible, otherwise 182 * Map with big pages if possible, otherwise
183 * create normal page tables: 183 * create normal page tables:
184 *
185 * Don't use a large page for the first 2/4MB of memory
186 * because there are often fixed size MTRRs in there
187 * and overlapping MTRRs into large pages can cause
188 * slowdowns.
184 */ 189 */
185 if (cpu_has_pse) { 190 if (cpu_has_pse && !(pgd_idx == 0 && pmd_idx == 0)) {
186 unsigned int addr2; 191 unsigned int addr2;
187 pgprot_t prot = PAGE_KERNEL_LARGE; 192 pgprot_t prot = PAGE_KERNEL_LARGE;
188 193