powerpc/mm: Move hash specific pte bits to be top bits of RPN
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Tue, 28 Mar 2017 04:21:12 +0000 (15:21 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Fri, 31 Mar 2017 12:09:52 +0000 (23:09 +1100)
We don't support the full 57 bits of physical address and hence can
overload the top bits of RPN as hash specific pte bits.

Add a BUILD_BUG_ON() to enforce the relationship between H_PAGE_F_SECOND
and H_PAGE_F_GIX.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Reviewed-by: Paul Mackerras <paulus@ozlabs.org>
[mpe: Move the BUILD_BUG_ON() into hash_utils_64.c and comment it]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/book3s/64/hash.h
arch/powerpc/include/asm/book3s/64/pgtable.h
arch/powerpc/mm/hash_utils_64.c

index ec2828b1db0712f5d9aee2b8f170f95293c479dd..4e957b027fe0a3c9307fb72f921ada394fa002c5 100644 (file)
@@ -6,20 +6,13 @@
  * Common bits between 4K and 64K pages in a linux-style PTE.
  * Additional bits may be defined in pgtable-hash64-*.h
  *
- * Note: We only support user read/write permissions. Supervisor always
- * have full read/write to pages above PAGE_OFFSET (pages below that
- * always use the user access permissions).
- *
- * We could create separate kernel read-only if we used the 3 PP bits
- * combinations that newer processors provide but we currently don't.
  */
-#define H_PAGE_BUSY            _RPAGE_SW1 /* software: PTE & hash are busy */
 #define H_PTE_NONE_MASK                _PAGE_HPTEFLAGS
-#define H_PAGE_F_GIX_SHIFT     57
-/* (7ul << 57) HPTE index within HPTEG */
-#define H_PAGE_F_GIX           (_RPAGE_RSV2 | _RPAGE_RSV3 | _RPAGE_RSV4)
-#define H_PAGE_F_SECOND                _RPAGE_RSV1     /* HPTE is in 2ndary HPTEG */
-#define H_PAGE_HASHPTE         _RPAGE_SW0      /* PTE has associated HPTE */
+#define H_PAGE_F_GIX_SHIFT     56
+#define H_PAGE_BUSY            _RPAGE_RSV1 /* software: PTE & hash are busy */
+#define H_PAGE_F_SECOND                _RPAGE_RSV2     /* HPTE is in 2ndary HPTEG */
+#define H_PAGE_F_GIX           (_RPAGE_RSV3 | _RPAGE_RSV4 | _RPAGE_RPN44)
+#define H_PAGE_HASHPTE         _RPAGE_RPN43    /* PTE has associated HPTE */
 
 #ifdef CONFIG_PPC_64K_PAGES
 #include <asm/book3s/64/hash-64k.h>
index 1f9e9848bbd595c83a87b61789c962a368ad6222..fb72ff6b98e63cc77e7ad48c08b62b888a494415 100644 (file)
 #define _RPAGE_RSV2            0x0800000000000000UL
 #define _RPAGE_RSV3            0x0400000000000000UL
 #define _RPAGE_RSV4            0x0200000000000000UL
+
+#define _PAGE_PTE              0x4000000000000000UL    /* distinguishes PTEs from pointers */
+#define _PAGE_PRESENT          0x8000000000000000UL    /* pte contains a translation */
+
+/*
+ * Top and bottom bits of RPN which can be used by hash
+ * translation mode, because we expect them to be zero
+ * otherwise.
+ */
 #define _RPAGE_RPN0            0x01000
 #define _RPAGE_RPN1            0x02000
+#define _RPAGE_RPN44           0x0100000000000000UL
+#define _RPAGE_RPN43           0x0080000000000000UL
+#define _RPAGE_RPN42           0x0040000000000000UL
+#define _RPAGE_RPN41           0x0020000000000000UL
 
 /* Max physical address bit as per radix table */
 #define _RPAGE_PA_MAX          57
@@ -65,9 +78,6 @@
 
 #define _PAGE_SOFT_DIRTY       _RPAGE_SW3 /* software: software dirty tracking */
 #define _PAGE_SPECIAL          _RPAGE_SW2 /* software: special page */
-
-#define _PAGE_PTE              0x4000000000000000UL    /* distinguishes PTEs from pointers */
-#define _PAGE_PRESENT          0x8000000000000000UL    /* pte contains a translation */
 /*
  * Drivers request for cache inhibited pte mapping using _PAGE_NO_CACHE
  * Instead of fixing all of them, add an alternate define which
index c554768b1fa2d42f2f5bb6d1c97a57e23d8241af..d0ee17029e99e6b49bb7f4c198cc45c35cf6c5fe 100644 (file)
@@ -981,6 +981,19 @@ void __init hash__early_init_devtree(void)
 
 void __init hash__early_init_mmu(void)
 {
+       /*
+        * We have code in __hash_page_64K() and elsewhere, which assumes it can
+        * do the following:
+        *   new_pte |= (slot << H_PAGE_F_GIX_SHIFT) & (H_PAGE_F_SECOND | H_PAGE_F_GIX);
+        *
+        * Where the slot number is between 0-15, and values of 8-15 indicate
+        * the secondary bucket. For that code to work H_PAGE_F_SECOND and
+        * H_PAGE_F_GIX must occupy four contiguous bits in the PTE, and
+        * H_PAGE_F_SECOND must be placed above H_PAGE_F_GIX. Assert that here
+        * with a BUILD_BUG_ON().
+        */
+       BUILD_BUG_ON(H_PAGE_F_SECOND != (1ul  << (H_PAGE_F_GIX_SHIFT + 3)));
+
        htab_init_page_sizes();
 
        /*