powerpc/32s: fix suspend/resume when IBATs 4-7 are used [Linux 5.3]

This Linux kernel change "powerpc/32s: fix suspend/resume when IBATs 4-7 are used" is included in the Linux 5.3 release. This change is authored by Christophe Leroy <christophe.leroy [at] c-s.fr> on Mon Jun 17 21:42:14 2019 +0000. The commit for this change in Linux stable tree is 6ecb78e (patch).

powerpc/32s: fix suspend/resume when IBATs 4-7 are used

Previously, only IBAT1 and IBAT2 were used to map kernel linear mem.
Since commit 63b2bc619565 ("powerpc/mm/32s: Use BATs for
STRICT_KERNEL_RWX"), we may have all 8 BATs used for mapping
kernel text. But the suspend/restore functions only save/restore
BATs 0 to 3, and clears BATs 4 to 7.

Make suspend and restore functions respectively save and reload
the 8 BATs on CPUs having MMU_FTR_USE_HIGH_BATS feature.

Reported-by: Andreas Schwab <schwab@linux-m68k.org>
Cc: stable@vger.kernel.org
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

There are 141 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 arch/powerpc/kernel/swsusp_32.S         | 73 +++++++++++++++++++++++++++++----
 arch/powerpc/platforms/powermac/sleep.S | 68 +++++++++++++++++++++++++++---
 2 files changed, 128 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/kernel/swsusp_32.S b/arch/powerpc/kernel/swsusp_32.S
index 7a919e9..cbdf862 100644
--- a/arch/powerpc/kernel/swsusp_32.S
+++ b/arch/powerpc/kernel/swsusp_32.S
@@ -25,11 +25,19 @@
 #define SL_IBAT2   0x48
 #define SL_DBAT3   0x50
 #define SL_IBAT3   0x58
-#define SL_TB      0x60
-#define SL_R2      0x68
-#define SL_CR      0x6c
-#define SL_LR      0x70
-#define SL_R12     0x74    /* r12 to r31 */
+#define SL_DBAT4   0x60
+#define SL_IBAT4   0x68
+#define SL_DBAT5   0x70
+#define SL_IBAT5   0x78
+#define SL_DBAT6   0x80
+#define SL_IBAT6   0x88
+#define SL_DBAT7   0x90
+#define SL_IBAT7   0x98
+#define SL_TB      0xa0
+#define SL_R2      0xa8
+#define SL_CR      0xac
+#define SL_LR      0xb0
+#define SL_R12     0xb4    /* r12 to r31 */
 #define SL_SIZE        (SL_R12 + 80)

    .section .data
@@ -114,6 +122,41 @@ _GLOBAL(swsusp_arch_suspend)
    mfibatl r4,3
    stw r4,SL_IBAT3+4(r11)

+BEGIN_MMU_FTR_SECTION
+   mfspr   r4,SPRN_DBAT4U
+   stw r4,SL_DBAT4(r11)
+   mfspr   r4,SPRN_DBAT4L
+   stw r4,SL_DBAT4+4(r11)
+   mfspr   r4,SPRN_DBAT5U
+   stw r4,SL_DBAT5(r11)
+   mfspr   r4,SPRN_DBAT5L
+   stw r4,SL_DBAT5+4(r11)
+   mfspr   r4,SPRN_DBAT6U
+   stw r4,SL_DBAT6(r11)
+   mfspr   r4,SPRN_DBAT6L
+   stw r4,SL_DBAT6+4(r11)
+   mfspr   r4,SPRN_DBAT7U
+   stw r4,SL_DBAT7(r11)
+   mfspr   r4,SPRN_DBAT7L
+   stw r4,SL_DBAT7+4(r11)
+   mfspr   r4,SPRN_IBAT4U
+   stw r4,SL_IBAT4(r11)
+   mfspr   r4,SPRN_IBAT4L
+   stw r4,SL_IBAT4+4(r11)
+   mfspr   r4,SPRN_IBAT5U
+   stw r4,SL_IBAT5(r11)
+   mfspr   r4,SPRN_IBAT5L
+   stw r4,SL_IBAT5+4(r11)
+   mfspr   r4,SPRN_IBAT6U
+   stw r4,SL_IBAT6(r11)
+   mfspr   r4,SPRN_IBAT6L
+   stw r4,SL_IBAT6+4(r11)
+   mfspr   r4,SPRN_IBAT7U
+   stw r4,SL_IBAT7(r11)
+   mfspr   r4,SPRN_IBAT7L
+   stw r4,SL_IBAT7+4(r11)
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
+
 #if  0
    /* Backup various CPU config stuffs */
    bl  __save_cpu_setup
@@ -279,27 +322,41 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
    mtibatu 3,r4
    lwz r4,SL_IBAT3+4(r11)
    mtibatl 3,r4
-#endif
-
 BEGIN_MMU_FTR_SECTION
-   li  r4,0
+   lwz r4,SL_DBAT4(r11)
    mtspr   SPRN_DBAT4U,r4
+   lwz r4,SL_DBAT4+4(r11)
    mtspr   SPRN_DBAT4L,r4
+   lwz r4,SL_DBAT5(r11)
    mtspr   SPRN_DBAT5U,r4
+   lwz r4,SL_DBAT5+4(r11)
    mtspr   SPRN_DBAT5L,r4
+   lwz r4,SL_DBAT6(r11)
    mtspr   SPRN_DBAT6U,r4
+   lwz r4,SL_DBAT6+4(r11)
    mtspr   SPRN_DBAT6L,r4
+   lwz r4,SL_DBAT7(r11)
    mtspr   SPRN_DBAT7U,r4
+   lwz r4,SL_DBAT7+4(r11)
    mtspr   SPRN_DBAT7L,r4
+   lwz r4,SL_IBAT4(r11)
    mtspr   SPRN_IBAT4U,r4
+   lwz r4,SL_IBAT4+4(r11)
    mtspr   SPRN_IBAT4L,r4
+   lwz r4,SL_IBAT5(r11)
    mtspr   SPRN_IBAT5U,r4
+   lwz r4,SL_IBAT5+4(r11)
    mtspr   SPRN_IBAT5L,r4
+   lwz r4,SL_IBAT6(r11)
    mtspr   SPRN_IBAT6U,r4
+   lwz r4,SL_IBAT6+4(r11)
    mtspr   SPRN_IBAT6L,r4
+   lwz r4,SL_IBAT7(r11)
    mtspr   SPRN_IBAT7U,r4
+   lwz r4,SL_IBAT7+4(r11)
    mtspr   SPRN_IBAT7L,r4
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
+#endif

    /* Flush all TLBs */
    lis r4,0x1000
diff --git a/arch/powerpc/platforms/powermac/sleep.S b/arch/powerpc/platforms/powermac/sleep.S
index fb64b09..eb583bd9 100644
--- a/arch/powerpc/platforms/powermac/sleep.S
+++ b/arch/powerpc/platforms/powermac/sleep.S
@@ -38,10 +38,18 @@
 #define SL_IBAT2   0x48
 #define SL_DBAT3   0x50
 #define SL_IBAT3   0x58
-#define SL_TB      0x60
-#define SL_R2      0x68
-#define SL_CR      0x6c
-#define SL_R12     0x70    /* r12 to r31 */
+#define SL_DBAT4   0x60
+#define SL_IBAT4   0x68
+#define SL_DBAT5   0x70
+#define SL_IBAT5   0x78
+#define SL_DBAT6   0x80
+#define SL_IBAT6   0x88
+#define SL_DBAT7   0x90
+#define SL_IBAT7   0x98
+#define SL_TB      0xa0
+#define SL_R2      0xa8
+#define SL_CR      0xac
+#define SL_R12     0xb0    /* r12 to r31 */
 #define SL_SIZE        (SL_R12 + 80)

    .section .text
@@ -126,6 +134,41 @@ _GLOBAL(low_sleep_handler)
    mfibatl r4,3
    stw r4,SL_IBAT3+4(r1)

+BEGIN_MMU_FTR_SECTION
+   mfspr   r4,SPRN_DBAT4U
+   stw r4,SL_DBAT4(r1)
+   mfspr   r4,SPRN_DBAT4L
+   stw r4,SL_DBAT4+4(r1)
+   mfspr   r4,SPRN_DBAT5U
+   stw r4,SL_DBAT5(r1)
+   mfspr   r4,SPRN_DBAT5L
+   stw r4,SL_DBAT5+4(r1)
+   mfspr   r4,SPRN_DBAT6U
+   stw r4,SL_DBAT6(r1)
+   mfspr   r4,SPRN_DBAT6L
+   stw r4,SL_DBAT6+4(r1)
+   mfspr   r4,SPRN_DBAT7U
+   stw r4,SL_DBAT7(r1)
+   mfspr   r4,SPRN_DBAT7L
+   stw r4,SL_DBAT7+4(r1)
+   mfspr   r4,SPRN_IBAT4U
+   stw r4,SL_IBAT4(r1)
+   mfspr   r4,SPRN_IBAT4L
+   stw r4,SL_IBAT4+4(r1)
+   mfspr   r4,SPRN_IBAT5U
+   stw r4,SL_IBAT5(r1)
+   mfspr   r4,SPRN_IBAT5L
+   stw r4,SL_IBAT5+4(r1)
+   mfspr   r4,SPRN_IBAT6U
+   stw r4,SL_IBAT6(r1)
+   mfspr   r4,SPRN_IBAT6L
+   stw r4,SL_IBAT6+4(r1)
+   mfspr   r4,SPRN_IBAT7U
+   stw r4,SL_IBAT7(r1)
+   mfspr   r4,SPRN_IBAT7L
+   stw r4,SL_IBAT7+4(r1)
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
+
    /* Backup various CPU config stuffs */
    bl  __save_cpu_setup

@@ -326,22 +369,37 @@ grackle_wake_up:
    mtibatl 3,r4

 BEGIN_MMU_FTR_SECTION
-   li  r4,0
+   lwz r4,SL_DBAT4(r1)
    mtspr   SPRN_DBAT4U,r4
+   lwz r4,SL_DBAT4+4(r1)
    mtspr   SPRN_DBAT4L,r4
+   lwz r4,SL_DBAT5(r1)
    mtspr   SPRN_DBAT5U,r4
+   lwz r4,SL_DBAT5+4(r1)
    mtspr   SPRN_DBAT5L,r4
+   lwz r4,SL_DBAT6(r1)
    mtspr   SPRN_DBAT6U,r4
+   lwz r4,SL_DBAT6+4(r1)
    mtspr   SPRN_DBAT6L,r4
+   lwz r4,SL_DBAT7(r1)
    mtspr   SPRN_DBAT7U,r4
+   lwz r4,SL_DBAT7+4(r1)
    mtspr   SPRN_DBAT7L,r4
+   lwz r4,SL_IBAT4(r1)
    mtspr   SPRN_IBAT4U,r4
+   lwz r4,SL_IBAT4+4(r1)
    mtspr   SPRN_IBAT4L,r4
+   lwz r4,SL_IBAT5(r1)
    mtspr   SPRN_IBAT5U,r4
+   lwz r4,SL_IBAT5+4(r1)
    mtspr   SPRN_IBAT5L,r4
+   lwz r4,SL_IBAT6(r1)
    mtspr   SPRN_IBAT6U,r4
+   lwz r4,SL_IBAT6+4(r1)
    mtspr   SPRN_IBAT6L,r4
+   lwz r4,SL_IBAT7(r1)
    mtspr   SPRN_IBAT7U,r4
+   lwz r4,SL_IBAT7+4(r1)
    mtspr   SPRN_IBAT7L,r4
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)

Leave a Reply

Your email address will not be published. Required fields are marked *