]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commit
sparc64: Prevent perf from running during super critical sections
authorRob Gardner <rob.gardner@oracle.com>
Mon, 17 Jul 2017 15:22:27 +0000 (09:22 -0600)
committerThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Tue, 22 Aug 2017 09:58:19 +0000 (06:58 -0300)
commitb0b5fdd7546c802ff714c3bf90b63ec11bd42dd0
treea0ab25d079eb4a03e1d9a964df3c754c819351b3
parentdc7e8e1ec08ad64260ab12ff28299550ecd2f520
sparc64: Prevent perf from running during super critical sections

BugLink: http://bugs.launchpad.net/bugs/1711535
commit fc290a114fc6034b0f6a5a46e2fb7d54976cf87a 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>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
arch/sparc/include/asm/mmu_context_64.h
arch/sparc/kernel/tsb.S
arch/sparc/power/hibernate.c