[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#621072: linux-image-2.6.32-5-amd64: 2.6.32-33 failes to boot as PV domU on Xen



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 <gregkh@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 <yinghai@kernel.org>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Greg Kroah-Hartman <gregkh@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)

Reply to: