powerpc/powernv/idle: Restore AMR/UAMOR/AMOR after idle
authorMichael Ellerman <mpe@ellerman.id.au>
Thu, 18 Apr 2019 06:51:17 +0000 (16:51 +1000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 24 Apr 2020 06:00:45 +0000 (08:00 +0200)
commit 53a712bae5dd919521a58d7bad773b949358add0 upstream.

In order to implement KUAP (Kernel Userspace Access Protection) on
Power9 we will be using the AMR, and therefore indirectly the
UAMOR/AMOR.

So save/restore these regs in the idle code.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
[ajd: Backport to 4.14 tree, CVE-2020-11669]
Signed-off-by: Andrew Donnellan <ajd@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/powerpc/kernel/idle_book3s.S

index 74fc2043108261ebc183c270001a826ad846e5ae..01b823bdb49c2a4ff0a66e0e2b45722ba79014a8 100644 (file)
@@ -163,8 +163,11 @@ core_idle_lock_held:
        bne-    core_idle_lock_held
        blr
 
-/* Reuse an unused pt_regs slot for IAMR */
+/* Reuse some unused pt_regs slots for AMR/IAMR/UAMOR/UAMOR */
+#define PNV_POWERSAVE_AMR      _TRAP
 #define PNV_POWERSAVE_IAMR     _DAR
+#define PNV_POWERSAVE_UAMOR    _DSISR
+#define PNV_POWERSAVE_AMOR     RESULT
 
 /*
  * Pass requested state in r3:
@@ -198,8 +201,16 @@ pnv_powersave_common:
        SAVE_NVGPRS(r1)
 
 BEGIN_FTR_SECTION
+       mfspr   r4, SPRN_AMR
        mfspr   r5, SPRN_IAMR
+       mfspr   r6, SPRN_UAMOR
+       std     r4, PNV_POWERSAVE_AMR(r1)
        std     r5, PNV_POWERSAVE_IAMR(r1)
+       std     r6, PNV_POWERSAVE_UAMOR(r1)
+BEGIN_FTR_SECTION_NESTED(42)
+       mfspr   r7, SPRN_AMOR
+       std     r7, PNV_POWERSAVE_AMOR(r1)
+END_FTR_SECTION_NESTED_IFSET(CPU_FTR_HVMODE, 42)
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 
        mfcr    r5
@@ -951,12 +962,20 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
        REST_GPR(2, r1)
 
 BEGIN_FTR_SECTION
-       /* IAMR was saved in pnv_powersave_common() */
+       /* These regs were saved in pnv_powersave_common() */
+       ld      r4, PNV_POWERSAVE_AMR(r1)
        ld      r5, PNV_POWERSAVE_IAMR(r1)
+       ld      r6, PNV_POWERSAVE_UAMOR(r1)
+       mtspr   SPRN_AMR, r4
        mtspr   SPRN_IAMR, r5
+       mtspr   SPRN_UAMOR, r6
+BEGIN_FTR_SECTION_NESTED(42)
+       ld      r7, PNV_POWERSAVE_AMOR(r1)
+       mtspr   SPRN_AMOR, r7
+END_FTR_SECTION_NESTED_IFSET(CPU_FTR_HVMODE, 42)
        /*
-        * We don't need an isync here because the upcoming mtmsrd is
-        * execution synchronizing.
+        * We don't need an isync here after restoring IAMR because the upcoming
+        * mtmsrd is execution synchronizing.
         */
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)