[PATCH] x86-64: finish clear_highmaps()'s job wrt. _brk_end

From: Jan Beulich
Date: Wed May 06 2009 - 08:05:41 EST


Impact: bug fix

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. clear_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.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

---
arch/x86/mm/init.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)

--- linux-2.6.30-rc4/arch/x86/mm/init.c 2009-04-30 09:42:42.000000000 +0200
+++ 2.6.30-rc4-x86_64-brk_end-end/arch/x86/mm/init.c 2009-05-06 13:44:01.000000000 +0200
@@ -7,6 +7,7 @@
#include <asm/page.h>
#include <asm/page_types.h>
#include <asm/sections.h>
+#include <asm/setup.h>
#include <asm/system.h>
#include <asm/tlbflush.h>

@@ -304,8 +305,23 @@ unsigned long __init_refok init_memory_m
#endif

#ifdef CONFIG_X86_64
- if (!after_bootmem)
+ if (!after_bootmem && !start) {
+ pud_t *pud;
+ pmd_t *pmd;
+
mmu_cr4_features = read_cr4();
+
+ /*
+ * _brk_end cannot change anymore, but it and _end may be
+ * located on different 2M pages. cleanup_highmap(), however,
+ * can only consider _end when it runs, so destroy any
+ * mappings beyond _brk_end here.
+ */
+ pud = pud_offset(pgd_offset_k(_brk_end), _brk_end);
+ pmd = pmd_offset(pud, _brk_end - 1);
+ while (++pmd <= pmd_offset(pud, (unsigned long)_end - 1))
+ pmd_clear(pmd);
+ }
#endif
__flush_tlb_all();




--
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/