powerpc/64s: Initialize ISAv3 MMU registers before setting partition table
authorNicholas Piggin <npiggin@gmail.com>
Wed, 6 Dec 2017 08:21:14 +0000 (18:21 +1000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Dec 2017 08:52:57 +0000 (09:52 +0100)
commitf11f5c4b87164c88da85193430f36d7d14bdcec4
tree73063c93c2b980f2eeead8a226d5ae455ebcf32d
parentd46be2f67c1088077e35ab87da6fc2b0d367fb88
powerpc/64s: Initialize ISAv3 MMU registers before setting partition table

commit 371b80447ff33ddac392c189cf884a5a3e18faeb upstream.

kexec can leave MMU registers set when booting into a new kernel,
the PIDR (Process Identification Register) in particular. The boot
sequence does not zero PIDR, so it only gets set when CPUs first
switch to a userspace processes (until then it's running a kernel
thread with effective PID = 0).

This leaves a window where a process table entry and page tables are
set up due to user processes running on other CPUs, that happen to
match with a stale PID. The CPU with that PID may cause speculative
accesses that address quadrant 0 (aka userspace addresses), which will
result in cached translations and PWC (Page Walk Cache) for that
process, on a CPU which is not in the mm_cpumask and so they will not
be invalidated properly.

The most common result is the kernel hanging in infinite page fault
loops soon after kexec (usually in schedule_tail, which is usually the
first non-speculative quadrant 0 access to a new PID) due to a stale
PWC. However being a stale translation error, it could result in
anything up to security and data corruption problems.

Fix this by zeroing out PIDR at boot and kexec.

Fixes: 7e381c0ff618 ("powerpc/mm/radix: Add mmu context handling callback for radix")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/powerpc/kernel/cpu_setup_power.S