powerpc/kvm: Save and restore host AMR/IAMR/UAMOR
authorMichael Ellerman <mpe@ellerman.id.au>
Fri, 22 Feb 2019 02:22:08 +0000 (13:22 +1100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Sep 2019 06:22:07 +0000 (08:22 +0200)
commit915c9d0a1d683c74d725c0d149afb8106f1b5303
treeac584dc37f999372897184ffb4eecea811444c02
parentb3f864b88256118a1566922c6ce079305d46662c
powerpc/kvm: Save and restore host AMR/IAMR/UAMOR

[ Upstream commit c3c7470c75566a077c8dc71dcf8f1948b8ddfab4 ]

When the hash MMU is active the AMR, IAMR and UAMOR are used for
pkeys. The AMR is directly writable by user space, and the UAMOR masks
those writes, meaning both registers are effectively user register
state. The IAMR is used to create an execute only key.

Also we must maintain the value of at least the AMR when running in
process context, so that any memory accesses done by the kernel on
behalf of the process are correctly controlled by the AMR.

Although we are correctly switching all registers when going into a
guest, on returning to the host we just write 0 into all regs, except
on Power9 where we restore the IAMR correctly.

This could be observed by a user process if it writes the AMR, then
runs a guest and we then return immediately to it without
rescheduling. Because we have written 0 to the AMR that would have the
effect of granting read/write permission to pages that the process was
trying to protect.

In addition, when using the Radix MMU, the AMR can prevent inadvertent
kernel access to userspace data, writing 0 to the AMR disables that
protection.

So save and restore AMR, IAMR and UAMOR.

Fixes: cf43d3b26452 ("powerpc: Enable pkey subsystem")
Cc: stable@vger.kernel.org # v4.16+
Signed-off-by: Russell Currey <ruscur@russell.cc>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Acked-by: Paul Mackerras <paulus@ozlabs.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/powerpc/kvm/book3s_hv_rmhandlers.S