]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
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)
committerMichael Ellerman <mpe@ellerman.id.au>
Fri, 22 Feb 2019 02:41:13 +0000 (13:41 +1100)
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>
arch/powerpc/kvm/book3s_hv_rmhandlers.S

index f24f6a2f8eb51205bec7d8cad6348b791bec20f6..25043b50cb30a4b7d5dcde8e45ba61bc3b3e547f 100644 (file)
@@ -58,6 +58,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
 #define STACK_SLOT_DAWR                (SFS-56)
 #define STACK_SLOT_DAWRX       (SFS-64)
 #define STACK_SLOT_HFSCR       (SFS-72)
+#define STACK_SLOT_AMR         (SFS-80)
+#define STACK_SLOT_UAMOR       (SFS-88)
 /* the following is used by the P9 short path */
 #define STACK_SLOT_NVGPRS      (SFS-152)       /* 18 gprs */
 
@@ -726,11 +728,9 @@ BEGIN_FTR_SECTION
        mfspr   r5, SPRN_TIDR
        mfspr   r6, SPRN_PSSCR
        mfspr   r7, SPRN_PID
-       mfspr   r8, SPRN_IAMR
        std     r5, STACK_SLOT_TID(r1)
        std     r6, STACK_SLOT_PSSCR(r1)
        std     r7, STACK_SLOT_PID(r1)
-       std     r8, STACK_SLOT_IAMR(r1)
        mfspr   r5, SPRN_HFSCR
        std     r5, STACK_SLOT_HFSCR(r1)
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
@@ -738,11 +738,18 @@ BEGIN_FTR_SECTION
        mfspr   r5, SPRN_CIABR
        mfspr   r6, SPRN_DAWR
        mfspr   r7, SPRN_DAWRX
+       mfspr   r8, SPRN_IAMR
        std     r5, STACK_SLOT_CIABR(r1)
        std     r6, STACK_SLOT_DAWR(r1)
        std     r7, STACK_SLOT_DAWRX(r1)
+       std     r8, STACK_SLOT_IAMR(r1)
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 
+       mfspr   r5, SPRN_AMR
+       std     r5, STACK_SLOT_AMR(r1)
+       mfspr   r6, SPRN_UAMOR
+       std     r6, STACK_SLOT_UAMOR(r1)
+
 BEGIN_FTR_SECTION
        /* Set partition DABR */
        /* Do this before re-enabling PMU to avoid P7 DABR corruption bug */
@@ -1631,22 +1638,25 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
        mtspr   SPRN_PSPB, r0
        mtspr   SPRN_WORT, r0
 BEGIN_FTR_SECTION
-       mtspr   SPRN_IAMR, r0
        mtspr   SPRN_TCSCR, r0
        /* Set MMCRS to 1<<31 to freeze and disable the SPMC counters */
        li      r0, 1
        sldi    r0, r0, 31
        mtspr   SPRN_MMCRS, r0
 END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
-8:
 
-       /* Save and reset AMR and UAMOR before turning on the MMU */
+       /* Save and restore AMR, IAMR and UAMOR before turning on the MMU */
+       ld      r8, STACK_SLOT_IAMR(r1)
+       mtspr   SPRN_IAMR, r8
+
+8:     /* Power7 jumps back in here */
        mfspr   r5,SPRN_AMR
        mfspr   r6,SPRN_UAMOR
        std     r5,VCPU_AMR(r9)
        std     r6,VCPU_UAMOR(r9)
-       li      r6,0
-       mtspr   SPRN_AMR,r6
+       ld      r5,STACK_SLOT_AMR(r1)
+       ld      r6,STACK_SLOT_UAMOR(r1)
+       mtspr   SPRN_AMR, r5
        mtspr   SPRN_UAMOR, r6
 
        /* Switch DSCR back to host value */
@@ -1746,11 +1756,9 @@ BEGIN_FTR_SECTION
        ld      r5, STACK_SLOT_TID(r1)
        ld      r6, STACK_SLOT_PSSCR(r1)
        ld      r7, STACK_SLOT_PID(r1)
-       ld      r8, STACK_SLOT_IAMR(r1)
        mtspr   SPRN_TIDR, r5
        mtspr   SPRN_PSSCR, r6
        mtspr   SPRN_PID, r7
-       mtspr   SPRN_IAMR, r8
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 
 #ifdef CONFIG_PPC_RADIX_MMU