linux/arch
Ingo Molnar 5dfaf90f80 x86: mm: Read cr2 before prefetching the mmap_lock
Prefetch instructions can generate spurious faults on certain
models of older CPUs. The faults themselves cannot be stopped
and they can occur pretty much anywhere - so the way we solve
them is that we detect certain patterns and ignore the fault.

There is one small path of code where we must not take faults
though: the #PF handler execution leading up to the reading
of the CR2 (the faulting address). If we take a fault there
then we destroy the CR2 value (with that of the prefetching
instruction's) and possibly mishandle user-space or
kernel-space pagefaults.

It turns out that in current upstream we do exactly that:

	prefetchw(&mm->mmap_sem);

	/* Get the faulting address: */
	address = read_cr2();

This is not good.

So turn around the order: first read the cr2 then prefetch
the lock address. Reading cr2 is plenty fast (2 cycles) so
delaying the prefetch by this amount shouldnt be a big issue
performance-wise.

[ And this might explain a mystery fault.c warning that sometimes
  occurs on one an old AMD/Semptron based test-system i have -
  which does have such prefetch problems. ]

Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Nick Piggin <npiggin@suse.de>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Vegard Nossum <vegard.nossum@gmail.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Hugh Dickins <hugh.dickins@tiscali.co.uk>
LKML-Reference: <20090616030522.GA22162@Krystal>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-06-16 10:23:32 +02:00
..
alpha Merge branch 'linus' into irq/numa 2009-06-01 21:06:21 +02:00
arm Merge branch 'for-2.6.31' of git://git.kernel.dk/linux-2.6-block 2009-06-11 11:10:35 -07:00
avr32 avr32: drop unused CLEAN_FILES 2009-05-01 10:54:00 +02:00
blackfin flat: fix data sections alignment 2009-05-29 08:40:02 -07:00
cris Merge branch 'linus' into irq/numa 2009-06-01 21:06:21 +02:00
frv FRV: Implement new-style ptrace 2009-06-11 09:01:26 -07:00
h8300 flat: fix data sections alignment 2009-05-29 08:40:02 -07:00
ia64 Merge branch 'kvm-updates/2.6.31' of git://git.kernel.org/pub/scm/virt/kvm/kvm 2009-06-11 10:03:30 -07:00
m32r flat: fix data sections alignment 2009-05-29 08:40:02 -07:00
m68k flat: fix data sections alignment 2009-05-29 08:40:02 -07:00
m68knommu Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu 2009-04-24 08:45:53 -07:00
microblaze microblaze: Fix kind-of-intr checking against number of interrupts 2009-05-18 14:47:42 +02:00
mips Merge branch 'irq-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2009-06-10 15:25:41 -07:00
mn10300 MN10300: Add utrace/tracehooks support 2009-06-11 09:02:20 -07:00
parisc irq: change ->set_affinity() to return status 2009-04-28 12:21:16 +02:00
powerpc Merge branch 'perfcounters-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2009-06-11 14:01:07 -07:00
s390 KVM: s390: Verify memory in kvm run 2009-06-10 11:48:57 +03:00
sh sh: Tie sparseirq in to Kconfig. 2009-06-11 10:33:09 +03:00
sparc Merge branch 'futexes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2009-06-10 16:16:48 -07:00
um block: implement and enforce request peek/start/fetch 2009-05-11 09:52:18 +02:00
x86 x86: mm: Read cr2 before prefetching the mmap_lock 2009-06-16 10:23:32 +02:00
xtensa xtensa: Fix linker script to include .literal sections 2009-05-11 23:40:33 -07:00
.gitignore
Kconfig mutex: have non-spinning mutexes on s390 by default 2009-04-09 19:28:24 +02:00