aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2009-05-06 08:06:47 -0400
committerH. Peter Anvin <hpa@zytor.com>2009-05-08 00:51:34 -0400
commit498343967613183611ac37dccb2846496d954c06 (patch)
treef0a1f93acbe49e4fb72c5dd77a25dc7f3d970e42
parent61438766514a2d7f191ce1b3cf6812eabbef4ef7 (diff)
x86-64: finish cleanup_highmaps()'s job wrt. _brk_end
With the introduction of the .brk section, special care must be taken that no unused page table entries remain if _brk_end and _end are separated by a 2M page boundary. cleanup_highmap() runs very early and hence cannot take care of that, hence potential entries needing to be removed past _brk_end must be cleared once the brk allocator has done its job. [ Impact: avoids undesirable TLB aliases ] Signed-off-by: Jan Beulich <jbeulich@novell.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--arch/x86/mm/init.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index fd3da1dda1c9..ae4f7b5d7104 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -7,6 +7,7 @@
7#include <asm/page.h> 7#include <asm/page.h>
8#include <asm/page_types.h> 8#include <asm/page_types.h>
9#include <asm/sections.h> 9#include <asm/sections.h>
10#include <asm/setup.h>
10#include <asm/system.h> 11#include <asm/system.h>
11#include <asm/tlbflush.h> 12#include <asm/tlbflush.h>
12 13
@@ -304,8 +305,23 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
304#endif 305#endif
305 306
306#ifdef CONFIG_X86_64 307#ifdef CONFIG_X86_64
307 if (!after_bootmem) 308 if (!after_bootmem && !start) {
309 pud_t *pud;
310 pmd_t *pmd;
311
308 mmu_cr4_features = read_cr4(); 312 mmu_cr4_features = read_cr4();
313
314 /*
315 * _brk_end cannot change anymore, but it and _end may be
316 * located on different 2M pages. cleanup_highmap(), however,
317 * can only consider _end when it runs, so destroy any
318 * mappings beyond _brk_end here.
319 */
320 pud = pud_offset(pgd_offset_k(_brk_end), _brk_end);
321 pmd = pmd_offset(pud, _brk_end - 1);
322 while (++pmd <= pmd_offset(pud, (unsigned long)_end - 1))
323 pmd_clear(pmd);
324 }
309#endif 325#endif
310 __flush_tlb_all(); 326 __flush_tlb_all();
311 327