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

This Linux kernel change "powerpc/32s: fix suspend/resume when IBATs 4-7 are used" is included in the Linux 4.9.187 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 dae64e9 (patch) which is from upstream commit 6ecb78e. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 6ecb78e.

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

commit 6ecb78ef56e08d2119d337ae23cb951a640dc52d upstream.

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 <[email protected]>
Cc: [email protected]
Signed-off-by: Christophe Leroy <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

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 ba4dee3..884d1c3 100644
--- a/arch/powerpc/kernel/swsusp_32.S
+++ b/arch/powerpc/kernel/swsusp_32.S
@@ -23,11 +23,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
@@ -112,6 +120,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
@@ -277,27 +320,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 1c2802f..c856cd7 100644
--- a/arch/powerpc/platforms/powermac/sleep.S
+++ b/arch/powerpc/platforms/powermac/sleep.S
@@ -37,10 +37,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
@@ -125,6 +133,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

@@ -325,22 +368,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 *