On Tue, 2011-04-12 at 09:19 +0200, Bastian Blank wrote: > On Wed, Apr 06, 2011 at 11:48:07AM +0200, Florian Wagner wrote: > > But this kernel doesn't boot as a PV domU neither on my Citrix XenServer > > 5.6 FP1 > > nor on a Debian system with Xen 3.4.3 at all. It doesn't even get so far as > > to > > provide a hvc console but crashes with a page fault on domain creation: > > It needs a backport of 67e87f0a1c5cbc750f81ebf6a128e8ff6f4376cc to not > zero parts of the memory.
I spoke to Stefano (who has been tracking these issues upstream) and he agrees and says that his patch 14988a4d350ce3b41ecad4f63c4f44c56f5ae34d has no effect without it. However, 2.6.32.37 will contain a revert of "x86: Cleanup highmap after brk is concluded" which also fixes this issue so probably we should just wait for 2.6.32.37 or take that revert early. It's in the longterm queue git repo already (attached), bugfix/x86/Save-cr4-to-mmu_cr4_features-at-boot-time.patch should go at the same time. Ian. -- Ian Campbell Current Noise: Rotting Christ - Eon Aenaos You're at the end of the road again.
>From 5988b32500933add4877201667ce7b1725254072 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman <gre...@suse.de> Date: Mon, 11 Apr 2011 16:04:59 -0700 Subject: [PATCH] Revert "x86: Cleanup highmap after brk is concluded" This reverts upstream commit e5f15b45ddf3afa2bbbb10c7ea34fb32b6de0a0e It caused problems in the stable tree and should not have been there. Cc: Yinghai Lu <ying...@kernel.org> Cc: Stefano Stabellini <stefano.stabell...@eu.citrix.com> Cc: H. Peter Anvin <h...@zytor.com> Cc: Ingo Molnar <mi...@elte.hu> Signed-off-by: Greg Kroah-Hartman <gre...@suse.de> --- arch/x86/kernel/head64.c | 3 +++ arch/x86/kernel/setup.c | 5 ----- arch/x86/mm/init.c | 19 +++++++++++++++++++ arch/x86/mm/init_64.c | 11 +++++------ 4 files changed, 27 insertions(+), 11 deletions(-) --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -76,6 +76,9 @@ void __init x86_64_start_kernel(char * r /* Make NULL pointers segfault */ zap_identity_mappings(); + /* Cleanup the over mapped high alias */ + cleanup_highmap(); + for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) { #ifdef CONFIG_EARLY_PRINTK set_intr_gate(i, &early_idt_handlers[i]); --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -294,9 +294,6 @@ static void __init init_gbpages(void) static inline void init_gbpages(void) { } -static void __init cleanup_highmap(void) -{ -} #endif static void __init reserve_brk(void) @@ -924,8 +921,6 @@ void __init setup_arch(char **cmdline_p) reserve_brk(); - cleanup_highmap(); - init_gbpages(); /* max_pfn_mapped is updated here */ --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -287,6 +287,25 @@ unsigned long __init_refok init_memory_m load_cr3(swapper_pg_dir); #endif +#ifdef CONFIG_X86_64 + 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(); if (!after_bootmem && e820_table_end > e820_table_start) --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -49,7 +49,6 @@ #include <asm/numa.h> #include <asm/cacheflush.h> #include <asm/init.h> -#include <asm/setup.h> #include <linux/bootmem.h> static unsigned long dma_reserve __initdata; @@ -258,18 +257,18 @@ void __init init_extra_mapping_uc(unsign * to the compile time generated pmds. This results in invalid pmds up * to the point where we hit the physaddr 0 mapping. * - * We limit the mappings to the region from _text to _brk_end. _brk_end - * is rounded up to the 2MB boundary. This catches the invalid pmds as + * We limit the mappings to the region from _text to _end. _end is + * rounded up to the 2MB boundary. This catches the invalid pmds as * well, as they are located before _text: */ void __init cleanup_highmap(void) { unsigned long vaddr = __START_KERNEL_map; - unsigned long vaddr_end = __START_KERNEL_map + (max_pfn_mapped << PAGE_SHIFT); - unsigned long end = roundup((unsigned long)_brk_end, PMD_SIZE) - 1; + unsigned long end = roundup((unsigned long)_end, PMD_SIZE) - 1; pmd_t *pmd = level2_kernel_pgt; + pmd_t *last_pmd = pmd + PTRS_PER_PMD; - for (; vaddr + PMD_SIZE - 1 < vaddr_end; pmd++, vaddr += PMD_SIZE) { + for (; pmd < last_pmd; pmd++, vaddr += PMD_SIZE) { if (pmd_none(*pmd)) continue; if (vaddr < (unsigned long) _text || vaddr > end)