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

Bug#421804: linux-image-2.6.18-4-xen-686: Can crash at boot w/ >4GB memory



Package: linux-image-2.6.18-4-xen-686
Version: 2.6.18.dfsg.1-12
Severity: normal
Tags: patch


We're seeing some issues with the RHEL5 32b xen kernel that are leading
to frequent XenRT failures. Guests crash during boot when the host has
>4GB of RAM with alarmingly high probability.

The problem is that trying to clear a pte by setting it to PFN 0 can
potentially cause the entry to be temporarily invalid since it writes
the upper word first (i.e. the PTE remains present). It also not correct
to launder the 0 through p2m which set_pte will do. The combination of
these causes a crash when swapper_pg_dir and PFN 0 have MFNs on opposite
sides of the 4G boundary.

The attached patch fixes the problem. This is from:
http://xenbits.xensource.com/xen-unstable.hg?cs=c6efd6c2feaa

The same bug was reported against RHEL5 here:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=234375

Thanks,
Ian.

-- System Information:
Debian Release: 4.0
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.18-3-amd64
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
# HG changeset patch
# User kfraser@localhost.localdomain
# Date 1163425074 0
# Node ID c6efd6c2feaa3ec851685cc872a1ce989d998220
# Parent  16977bd93dbebe30060e4b4462938f21f5b14275
[LINUX] Fix clear_fixmap().

On i386-PAE, clear_fixmap() results in ill use of set_pte(). In all
contexts, p2m translations shouldn't occur here. Note that this is not
really an issue on native linux, as there is
(a) no pfn-to-mfn translation and
(b) __set_fixmap() takes an unsigned long physical address rather than
    a paddr_t, which makes it so that bits 32 and up of the physical
    address are always zero, permitting either order store when
    clearing the entry.

Signed-off-by: Jan Beulich <jbeulich@novell.com>

diff -r 16977bd93dbe -r c6efd6c2feaa linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Mon Nov 13 12:06:21 2006 +0000
+++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Mon Nov 13 13:37:54 2006 +0000
@@ -102,8 +102,11 @@ static void set_pte_pfn(unsigned long va
 		return;
 	}
 	pte = pte_offset_kernel(pmd, vaddr);
-	/* <pfn,flags> stored as-is, to permit clearing entries */
-	set_pte(pte, pfn_pte(pfn, flags));
+	if (pgprot_val(flags))
+		/* <pfn,flags> stored as-is, to permit clearing entries */
+		set_pte(pte, pfn_pte(pfn, flags));
+	else
+		pte_clear(&init_mm, vaddr, pte);
 
 	/*
 	 * It's enough to flush this one mapping.
@@ -140,8 +143,11 @@ static void set_pte_pfn_ma(unsigned long
 		return;
 	}
 	pte = pte_offset_kernel(pmd, vaddr);
-	/* <pfn,flags> stored as-is, to permit clearing entries */
-	set_pte(pte, pfn_pte_ma(pfn, flags));
+	if (pgprot_val(flags))
+		/* <pfn,flags> stored as-is, to permit clearing entries */
+		set_pte(pte, pfn_pte_ma(pfn, flags));
+	else
+		pte_clear(&init_mm, vaddr, pte);
 
 	/*
 	 * It's enough to flush this one mapping.
diff -r 16977bd93dbe -r c6efd6c2feaa linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c	Mon Nov 13 12:06:21 2006 +0000
+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c	Mon Nov 13 13:37:54 2006 +0000
@@ -260,7 +260,10 @@ static void set_pte_phys(unsigned long v
 			return;
 		}
 	}
-	new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
+	if (pgprot_val(prot))
+		new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
+	else
+		new_pte = __pte(0);
 
 	pte = pte_offset_kernel(pmd, vaddr);
 	if (!pte_none(*pte) &&

Reply to: