linux/arch/sparc
Rob Gardner 6309eb77d8 sparc64: Prevent perf from running during super critical sections
commit fc290a114f upstream.

This fixes another cause of random segfaults and bus errors that may
occur while running perf with the callgraph option.

Critical sections beginning with spin_lock_irqsave() raise the interrupt
level to PIL_NORMAL_MAX (14) and intentionally do not block performance
counter interrupts, which arrive at PIL_NMI (15).

But some sections of code are "super critical" with respect to perf
because the perf_callchain_user() path accesses user space and may cause
TLB activity as well as faults as it unwinds the user stack.

One particular critical section occurs in switch_mm:

        spin_lock_irqsave(&mm->context.lock, flags);
        ...
        load_secondary_context(mm);
        tsb_context_switch(mm);
        ...
        spin_unlock_irqrestore(&mm->context.lock, flags);

If a perf interrupt arrives in between load_secondary_context() and
tsb_context_switch(), then perf_callchain_user() could execute with
the context ID of one process, but with an active TSB for a different
process. When the user stack is accessed, it is very likely to
incur a TLB miss, since the h/w context ID has been changed. The TLB
will then be reloaded with a translation from the TSB for one process,
but using a context ID for another process. This exposes memory from
one process to another, and since it is a mapping for stack memory,
this usually causes the new process to crash quickly.

This super critical section needs more protection than is provided
by spin_lock_irqsave() since perf interrupts must not be allowed in.

Since __tsb_context_switch already goes through the trouble of
disabling interrupts completely, we fix this by moving the secondary
context load down into this better protected region.

Orabug: 25577560

Signed-off-by: Dave Aldridge <david.j.aldridge@oracle.com>
Signed-off-by: Rob Gardner <rob.gardner@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2017-08-12 19:31:23 -07:00
..
boot sparc: Add "install" target 2014-08-04 20:45:59 -07:00
configs sparc/defconfigs: Remove CONFIG_IPV6_PRIVACY 2016-04-21 16:43:44 -04:00
crypto crypto: sparc - initialize blkcipher.ivsize 2015-10-08 21:36:48 +08:00
include sparc64: Prevent perf from running during super critical sections 2017-08-12 19:31:23 -07:00
kernel sparc64: Prevent perf from running during super critical sections 2017-08-12 19:31:23 -07:00
lib sparc64: Fix exception handling in UltraSPARC-III memcpy. 2017-08-11 08:49:34 -07:00
math-emu arch/sparc/math-emu/math_32.c: drop stray break operator 2014-08-04 20:29:06 -07:00
mm mm: larger stack guard gap, between vmas 2017-06-24 07:11:18 +02:00
net sparc: Fix misspellings in comments. 2016-03-20 21:28:58 -07:00
oprofile sparc: using HZ needs an include of linux/param.h 2009-10-05 00:46:08 -07:00
power sparc64: Prevent perf from running during super critical sections 2017-08-12 19:31:23 -07:00
prom sparc: fixing ident and beautifying code 2016-10-06 01:46:40 -04:00
Kbuild sparc64: Add SHA1 driver making use of the 'sha1' instruction. 2012-08-20 15:08:49 -07:00
Kconfig arch/sparc: support NR_CPUS = 4096 2017-06-14 15:05:54 +02:00
Kconfig.debug lib: consolidate DEBUG_STACK_USAGE option 2011-05-25 08:39:54 -07:00
Makefile sparc32: Add -Wa,-Av8 to KBUILD_CFLAGS. 2016-03-01 00:24:04 -05:00