[kernel] r14223 - in dists/trunk/linux-2.6/debian: . patches/bugfix/x86 patches/series

Ben Hutchings benh at alioth.debian.org
Sun Sep 13 18:18:24 UTC 2009


Author: benh
Date: Sun Sep 13 18:18:22 2009
New Revision: 14223

Log:
x86: Fix crash in text_poke_early() on 486-class processors (Closes: #515982)

Added:
   dists/trunk/linux-2.6/debian/patches/bugfix/x86/fix-alternatives-on-486.patch
Modified:
   dists/trunk/linux-2.6/debian/changelog
   dists/trunk/linux-2.6/debian/patches/series/base

Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog	Sun Sep 13 18:14:43 2009	(r14222)
+++ dists/trunk/linux-2.6/debian/changelog	Sun Sep 13 18:18:22 2009	(r14223)
@@ -81,6 +81,8 @@
   * rt{2860,2870,3070}sta: Use existing CCITT CRC implementation on
     firmware rather than adding an equivalent variant of ITU-T CRC
   * rd: Build as a module since we do not require initrd support
+  * x86: Fix crash in text_poke_early() on 486-class processors
+    (Closes: #515982)
 
   [ Martin Michlmayr ]
   * [armel/orion5x, armel/kirkwood] Set GPIO_SYSFS=y since these

Added: dists/trunk/linux-2.6/debian/patches/bugfix/x86/fix-alternatives-on-486.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/x86/fix-alternatives-on-486.patch	Sun Sep 13 18:18:22 2009	(r14223)
@@ -0,0 +1,80 @@
+Subject: [PATCH v2] x86: Fix code patching for paravirt-alternatives on 486
+From: Ben Hutchings <ben at decadent.org.uk>
+To: x86 at kernel.org
+Cc: "H. Peter Anvin" <hpa at zytor.com>, linux-kernel at vger.kernel.org
+Date: Thu, 10 Sep 2009 02:53:51 +0100
+
+As reported in <http://bugs.debian.org/511703> and
+<http://bugs.debian.org/515982>, kernels with paravirt-alternatives
+enabled crash in text_poke_early() on at least some 486-class
+processors.
+
+The problem is that text_poke_early() itself uses inline functions
+affected by paravirt-alternatives and so will modify instructions that
+have already been prefetched.  Pentium and later processors will
+invalidate the prefetched instructions in this case, but 486-class
+processors do not.
+
+Change sync_core() to limit prefetching on 486-class (and 386-class)
+processors, and move the call to sync_core() above the call to the
+modifiable local_irq_restore().
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+Second try, incorporating the jmp into sync_core().
+
+Also not signed as I know git has trouble with MIME.
+
+Ben.
+
+ arch/x86/include/asm/processor.h |   16 +++++++++++++---
+ arch/x86/kernel/alternative.c    |    2 +-
+ 2 files changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
+index c776826..2db56c5 100644
+--- a/arch/x86/include/asm/processor.h
++++ b/arch/x86/include/asm/processor.h
+@@ -703,13 +703,23 @@ static inline void cpu_relax(void)
+ 	rep_nop();
+ }
+ 
+-/* Stop speculative execution: */
++/* Stop speculative execution and prefetching of modified code. */
+ static inline void sync_core(void)
+ {
+ 	int tmp;
+ 
+-	asm volatile("cpuid" : "=a" (tmp) : "0" (1)
+-		     : "ebx", "ecx", "edx", "memory");
++#if defined(CONFIG_M386) || defined(CONFIG_M486)
++	if (boot_cpu_data.x86 < 5)
++		/* There is no speculative execution.
++		 * jmp is a barrier to prefetching. */
++		asm volatile("jmp 1f\n1:\n" ::: "memory");
++	else
++#endif
++		/* cpuid is a barrier to speculative execution.
++		 * Prefetched instructions are automatically
++		 * invalidated when modified. */
++		asm volatile("cpuid" : "=a" (tmp) : "0" (1)
++			     : "ebx", "ecx", "edx", "memory");
+ }
+ 
+ static inline void __monitor(const void *eax, unsigned long ecx,
+diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
+index 4869351..de7353c 100644
+--- a/arch/x86/kernel/alternative.c
++++ b/arch/x86/kernel/alternative.c
+@@ -498,8 +498,8 @@ static void *__init_or_module text_poke_early(void *addr, const void *opcode,
+ 	unsigned long flags;
+ 	local_irq_save(flags);
+ 	memcpy(addr, opcode, len);
+-	local_irq_restore(flags);
+ 	sync_core();
++	local_irq_restore(flags);
+ 	/* Could also do a CLFLUSH here to speed up CPU recovery; but
+ 	   that causes hangs on some VIA CPUs. */
+ 	return addr;
+-- 
+1.6.3.3

Modified: dists/trunk/linux-2.6/debian/patches/series/base
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/base	Sun Sep 13 18:14:43 2009	(r14222)
+++ dists/trunk/linux-2.6/debian/patches/series/base	Sun Sep 13 18:18:22 2009	(r14223)
@@ -32,3 +32,4 @@
 + features/arm/openrd-sata.patch
 + bugfix/all/drivers-scsi-qla1280-request-firmware-unlocked.patch 
 + bugfix/all/drivers-gpu-drm-r128-ioctl-add-init-test.patch
++ bugfix/x86/fix-alternatives-on-486.patch



More information about the Kernel-svn-changes mailing list