From 6888a95d4b3e112c028e2a6e94e1c0809389c73e Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 13 Sep 2009 18:18:22 +0000 Subject: [PATCH] x86: Fix crash in text_poke_early() on 486-class processors (Closes: #515982) svn path=/dists/trunk/linux-2.6/; revision=14223 --- debian/changelog | 2 + .../bugfix/x86/fix-alternatives-on-486.patch | 80 +++++++++++++++++++ debian/patches/series/base | 1 + 3 files changed, 83 insertions(+) create mode 100644 debian/patches/bugfix/x86/fix-alternatives-on-486.patch diff --git a/debian/changelog b/debian/changelog index 29c4d875e..88069236e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -81,6 +81,8 @@ linux-2.6 (2.6.31-1~experimental.1) UNRELEASED; urgency=low * 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 diff --git a/debian/patches/bugfix/x86/fix-alternatives-on-486.patch b/debian/patches/bugfix/x86/fix-alternatives-on-486.patch new file mode 100644 index 000000000..94b7d047e --- /dev/null +++ b/debian/patches/bugfix/x86/fix-alternatives-on-486.patch @@ -0,0 +1,80 @@ +Subject: [PATCH v2] x86: Fix code patching for paravirt-alternatives on 486 +From: Ben Hutchings +To: x86@kernel.org +Cc: "H. Peter Anvin" , linux-kernel@vger.kernel.org +Date: Thu, 10 Sep 2009 02:53:51 +0100 + +As reported in and +, 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 +--- +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 diff --git a/debian/patches/series/base b/debian/patches/series/base index e6cd2436f..dab2f4a4a 100644 --- a/debian/patches/series/base +++ b/debian/patches/series/base @@ -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