Revert "powerpc/8xx: Use L1 entry APG to handle _PAGE_ACCESSED for CONFIG_SWAP"
authorChristophe Leroy <christophe.leroy@c-s.fr>
Fri, 19 Oct 2018 06:54:54 +0000 (06:54 +0000)
committerMichael Ellerman <mpe@ellerman.id.au>
Fri, 26 Oct 2018 10:58:58 +0000 (21:58 +1100)
This reverts commit 4f94b2c7462d9720b2afa7e8e8d4c19446bb31ce.

That commit was buggy, as it used rlwinm instead of rlwimi.
Instead of fixing that bug, we revert the previous commit in order to
reduce the dependency between L1 entries and L2 entries

Fixes: 4f94b2c7462d9 ("powerpc/8xx: Use L1 entry APG to handle _PAGE_ACCESSED for CONFIG_SWAP")
Cc: stable@vger.kernel.org
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/mmu-8xx.h
arch/powerpc/kernel/head_8xx.S
arch/powerpc/mm/8xx_mmu.c

index 4f54775..193f531 100644 (file)
  * respectively NA for All or X for Supervisor and no access for User.
  * Then we use the APG to say whether accesses are according to Page rules or
  * "all Supervisor" rules (Access to all)
- * We also use the 2nd APG bit for _PAGE_ACCESSED when having SWAP:
- * When that bit is not set access is done iaw "all user"
- * which means no access iaw page rules.
- * Therefore, we define 4 APG groups. lsb is _PMD_USER, 2nd is _PAGE_ACCESSED
- * 0x => No access => 11 (all accesses performed as user iaw page definition)
- * 10 => No user => 01 (all accesses performed according to page definition)
- * 11 => User => 00 (all accesses performed as supervisor iaw page definition)
+ * Therefore, we define 2 APG groups. lsb is _PMD_USER
+ * 0 => No user => 01 (all accesses performed according to page definition)
+ * 1 => User => 00 (all accesses performed as supervisor iaw page definition)
  * We define all 16 groups so that all other bits of APG can take any value
  */
-#ifdef CONFIG_SWAP
-#define MI_APG_INIT    0xf4f4f4f4
-#else
 #define MI_APG_INIT    0x44444444
-#endif
 
 /* The effective page number register.  When read, contains the information
  * about the last instruction TLB miss.  When MI_RPN is written, bits in
  * Supervisor and no access for user and NA for ALL.
  * Then we use the APG to say whether accesses are according to Page rules or
  * "all Supervisor" rules (Access to all)
- * We also use the 2nd APG bit for _PAGE_ACCESSED when having SWAP:
- * When that bit is not set access is done iaw "all user"
- * which means no access iaw page rules.
- * Therefore, we define 4 APG groups. lsb is _PMD_USER, 2nd is _PAGE_ACCESSED
- * 0x => No access => 11 (all accesses performed as user iaw page definition)
- * 10 => No user => 01 (all accesses performed according to page definition)
- * 11 => User => 00 (all accesses performed as supervisor iaw page definition)
+ * Therefore, we define 2 APG groups. lsb is _PMD_USER
+ * 0 => No user => 01 (all accesses performed according to page definition)
+ * 1 => User => 00 (all accesses performed as supervisor iaw page definition)
  * We define all 16 groups so that all other bits of APG can take any value
  */
-#ifdef CONFIG_SWAP
-#define MD_APG_INIT    0xf4f4f4f4
-#else
 #define MD_APG_INIT    0x44444444
-#endif
 
 /* The effective page number register.  When read, contains the information
  * about the last instruction TLB miss.  When MD_RPN is written, bits in
  */
 #define SPRN_M_TW      799
 
-/* APGs */
-#define M_APG0         0x00000000
-#define M_APG1         0x00000020
-#define M_APG2         0x00000040
-#define M_APG3         0x00000060
-
 #ifdef CONFIG_PPC_MM_SLICES
 #include <asm/nohash/32/slice.h>
 #define SLICE_ARRAY_SIZE       (1 << (32 - SLICE_LOW_SHIFT - 1))
index 134a573..12c92a4 100644 (file)
@@ -353,13 +353,14 @@ _ENTRY(ITLBMiss_cmp)
 #if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
        mtcr    r12
 #endif
-
-#ifdef CONFIG_SWAP
-       rlwinm  r11, r10, 31, _PAGE_ACCESSED >> 1
-#endif
        /* Load the MI_TWC with the attributes for this "segment." */
        mtspr   SPRN_MI_TWC, r11        /* Set segment attributes */
 
+#ifdef CONFIG_SWAP
+       rlwinm  r11, r10, 32-5, _PAGE_PRESENT
+       and     r11, r11, r10
+       rlwimi  r10, r11, 0, _PAGE_PRESENT
+#endif
        li      r11, RPN_PATTERN | 0x200
        /* The Linux PTE won't go exactly into the MMU TLB.
         * Software indicator bits 20 and 23 must be clear.
@@ -470,14 +471,22 @@ _ENTRY(DTLBMiss_jmp)
         * above.
         */
        rlwimi  r11, r10, 0, _PAGE_GUARDED
-#ifdef CONFIG_SWAP
-       /* _PAGE_ACCESSED has to be set. We use second APG bit for that, 0
-        * on that bit will represent a Non Access group
-        */
-       rlwinm  r11, r10, 31, _PAGE_ACCESSED >> 1
-#endif
        mtspr   SPRN_MD_TWC, r11
 
+       /* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
+        * We also need to know if the insn is a load/store, so:
+        * Clear _PAGE_PRESENT and load that which will
+        * trap into DTLB Error with store bit set accordinly.
+        */
+       /* PRESENT=0x1, ACCESSED=0x20
+        * r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
+        * r10 = (r10 & ~PRESENT) | r11;
+        */
+#ifdef CONFIG_SWAP
+       rlwinm  r11, r10, 32-5, _PAGE_PRESENT
+       and     r11, r11, r10
+       rlwimi  r10, r11, 0, _PAGE_PRESENT
+#endif
        /* The Linux PTE won't go exactly into the MMU TLB.
         * Software indicator bits 24, 25, 26, and 27 must be
         * set.  All other Linux PTE bits control the behavior
@@ -637,8 +646,8 @@ InstructionBreakpoint:
  */
 DTLBMissIMMR:
        mtcr    r12
-       /* Set 512k byte guarded page and mark it valid and accessed */
-       li      r10, MD_PS512K | MD_GUARDED | MD_SVALID | M_APG2
+       /* Set 512k byte guarded page and mark it valid */
+       li      r10, MD_PS512K | MD_GUARDED | MD_SVALID
        mtspr   SPRN_MD_TWC, r10
        mfspr   r10, SPRN_IMMR                  /* Get current IMMR */
        rlwinm  r10, r10, 0, 0xfff80000         /* Get 512 kbytes boundary */
@@ -656,8 +665,8 @@ _ENTRY(dtlb_miss_exit_2)
 
 DTLBMissLinear:
        mtcr    r12
-       /* Set 8M byte page and mark it valid and accessed */
-       li      r11, MD_PS8MEG | MD_SVALID | M_APG2
+       /* Set 8M byte page and mark it valid */
+       li      r11, MD_PS8MEG | MD_SVALID
        mtspr   SPRN_MD_TWC, r11
        rlwinm  r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
        ori     r10, r10, 0xf0 | MD_SPS16K | _PAGE_SH | _PAGE_DIRTY | \
@@ -675,8 +684,8 @@ _ENTRY(dtlb_miss_exit_3)
 #ifndef CONFIG_PIN_TLB_TEXT
 ITLBMissLinear:
        mtcr    r12
-       /* Set 8M byte page and mark it valid,accessed */
-       li      r11, MI_PS8MEG | MI_SVALID | M_APG2
+       /* Set 8M byte page and mark it valid */
+       li      r11, MI_PS8MEG | MI_SVALID
        mtspr   SPRN_MI_TWC, r11
        rlwinm  r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
        ori     r10, r10, 0xf0 | MI_SPS16K | _PAGE_SH | _PAGE_DIRTY | \
@@ -960,7 +969,7 @@ initial_mmu:
        ori     r8, r8, MI_EVALID       /* Mark it valid */
        mtspr   SPRN_MI_EPN, r8
        li      r8, MI_PS8MEG /* Set 8M byte page */
-       ori     r8, r8, MI_SVALID | M_APG2      /* Make it valid, APG 2 */
+       ori     r8, r8, MI_SVALID       /* Make it valid */
        mtspr   SPRN_MI_TWC, r8
        li      r8, MI_BOOTINIT         /* Create RPN for address 0 */
        mtspr   SPRN_MI_RPN, r8         /* Store TLB entry */
@@ -987,7 +996,7 @@ initial_mmu:
        ori     r8, r8, MD_EVALID       /* Mark it valid */
        mtspr   SPRN_MD_EPN, r8
        li      r8, MD_PS512K | MD_GUARDED      /* Set 512k byte page */
-       ori     r8, r8, MD_SVALID | M_APG2      /* Make it valid and accessed */
+       ori     r8, r8, MD_SVALID       /* Make it valid */
        mtspr   SPRN_MD_TWC, r8
        mr      r8, r9                  /* Create paddr for TLB */
        ori     r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
index 36484a2..fee599c 100644 (file)
@@ -79,7 +79,7 @@ void __init MMU_init_hw(void)
        for (; i < 32 && mem >= LARGE_PAGE_SIZE_8M; i++) {
                mtspr(SPRN_MD_CTR, ctr | (i << 8));
                mtspr(SPRN_MD_EPN, (unsigned long)__va(addr) | MD_EVALID);
-               mtspr(SPRN_MD_TWC, MD_PS8MEG | MD_SVALID | M_APG2);
+               mtspr(SPRN_MD_TWC, MD_PS8MEG | MD_SVALID);
                mtspr(SPRN_MD_RPN, addr | flags | _PAGE_PRESENT);
                addr += LARGE_PAGE_SIZE_8M;
                mem -= LARGE_PAGE_SIZE_8M;