powerpc/book3s64/pkeys: Move pkey related bits in the linux page table
authorAneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Thu, 9 Jul 2020 03:29:27 +0000 (08:59 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Mon, 20 Jul 2020 12:57:57 +0000 (22:57 +1000)
To keep things simple, all the pkey related bits are kept together
in linux page table for 64K config with hash translation. With hash-4k
kernel requires 4 bits to store slots details. This is done by overloading
some of the RPN bits for storing the slot details. Due to this PKEY_BIT0 on
the 4K config is used for storing hash slot details.

64K before

|....|RSV1| RSV2| RSV3 | RSV4 | RPN44| RPN43   |.... | RSV5|
|....| P4 |  P3 |  P2  |  P1  | Busy | HASHPTE |.... |  P0 |

after

|....|RSV1| RSV2| RSV3 | RSV4 | RPN44 | RPN43   |.... | RSV5 |
|....| P4 |  P3 |  P2  |  P1  | P0    | HASHPTE |.... | Busy |

4k before

|....| RSV1 | RSV2     | RSV3 | RSV4 | RPN44| RPN43.... | RSV5|
|....| Busy |  HASHPTE |  P2  |  P1  | F_SEC| F_GIX.... |  P0 |

after

|....| RSV1    | RSV2| RSV3 | RSV4 | Free | RPN43.... | RSV5 |
|....| HASHPTE |  P2 |  P1  |  P0  | F_SEC| F_GIX.... | BUSY |

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200709032946.881753-5-aneesh.kumar@linux.ibm.com
arch/powerpc/include/asm/book3s/64/hash-4k.h
arch/powerpc/include/asm/book3s/64/hash-64k.h
arch/powerpc/include/asm/book3s/64/pgtable.h

index f889d56..082b988 100644 (file)
 #define H_PUD_TABLE_SIZE       (sizeof(pud_t) << H_PUD_INDEX_SIZE)
 #define H_PGD_TABLE_SIZE       (sizeof(pgd_t) << H_PGD_INDEX_SIZE)
 
-#define H_PAGE_F_GIX_SHIFT     53
-#define H_PAGE_F_SECOND        _RPAGE_RPN44    /* HPTE is in 2ndary HPTEG */
-#define H_PAGE_F_GIX   (_RPAGE_RPN43 | _RPAGE_RPN42 | _RPAGE_RPN41)
-#define H_PAGE_BUSY    _RPAGE_RSV1     /* software: PTE & hash are busy */
-#define H_PAGE_HASHPTE _RPAGE_RSV2     /* software: PTE & hash are busy */
+#define H_PAGE_F_GIX_SHIFT     _PAGE_PA_MAX
+#define H_PAGE_F_SECOND                _RPAGE_PKEY_BIT0 /* HPTE is in 2ndary HPTEG */
+#define H_PAGE_F_GIX           (_RPAGE_RPN43 | _RPAGE_RPN42 | _RPAGE_RPN41)
+#define H_PAGE_BUSY            _RPAGE_RSV1
+#define H_PAGE_HASHPTE         _RPAGE_PKEY_BIT4
 
 /* PTE flags to conserve for HPTE identification */
 #define _PAGE_HPTEFLAGS (H_PAGE_BUSY | H_PAGE_HASHPTE | \
@@ -59,9 +59,9 @@
 /* memory key bits, only 8 keys supported */
 #define H_PTE_PKEY_BIT4        0
 #define H_PTE_PKEY_BIT3        0
-#define H_PTE_PKEY_BIT2        _RPAGE_RSV3
-#define H_PTE_PKEY_BIT1        _RPAGE_RSV4
-#define H_PTE_PKEY_BIT0        _RPAGE_RSV5
+#define H_PTE_PKEY_BIT2        _RPAGE_PKEY_BIT3
+#define H_PTE_PKEY_BIT1        _RPAGE_PKEY_BIT2
+#define H_PTE_PKEY_BIT0        _RPAGE_PKEY_BIT1
 
 
 /*
index 0a15fd1..f20de11 100644 (file)
  */
 #define H_PAGE_COMBO   _RPAGE_RPN0 /* this is a combo 4k page */
 #define H_PAGE_4K_PFN  _RPAGE_RPN1 /* PFN is for a single 4k page */
-#define H_PAGE_BUSY    _RPAGE_RPN44     /* software: PTE & hash are busy */
+#define H_PAGE_BUSY    _RPAGE_RSV1     /* software: PTE & hash are busy */
 #define H_PAGE_HASHPTE _RPAGE_RPN43    /* PTE has associated HPTE */
 
 /* memory key bits. */
-#define H_PTE_PKEY_BIT4        _RPAGE_RSV1
-#define H_PTE_PKEY_BIT3        _RPAGE_RSV2
-#define H_PTE_PKEY_BIT2        _RPAGE_RSV3
-#define H_PTE_PKEY_BIT1        _RPAGE_RSV4
-#define H_PTE_PKEY_BIT0        _RPAGE_RSV5
+#define H_PTE_PKEY_BIT4                _RPAGE_PKEY_BIT4
+#define H_PTE_PKEY_BIT3                _RPAGE_PKEY_BIT3
+#define H_PTE_PKEY_BIT2                _RPAGE_PKEY_BIT2
+#define H_PTE_PKEY_BIT1                _RPAGE_PKEY_BIT1
+#define H_PTE_PKEY_BIT0                _RPAGE_PKEY_BIT0
 
 /*
  * We need to differentiate between explicit huge page and THP huge
index 25c3cb8..495fc0c 100644 (file)
 #define _RPAGE_SW1             0x00800
 #define _RPAGE_SW2             0x00400
 #define _RPAGE_SW3             0x00200
-#define _RPAGE_RSV1            0x1000000000000000UL
-#define _RPAGE_RSV2            0x0800000000000000UL
-#define _RPAGE_RSV3            0x0400000000000000UL
-#define _RPAGE_RSV4            0x0200000000000000UL
-#define _RPAGE_RSV5            0x00040UL
+#define _RPAGE_RSV1            0x00040UL
+
+#define _RPAGE_PKEY_BIT4       0x1000000000000000UL
+#define _RPAGE_PKEY_BIT3       0x0800000000000000UL
+#define _RPAGE_PKEY_BIT2       0x0400000000000000UL
+#define _RPAGE_PKEY_BIT1       0x0200000000000000UL
+#define _RPAGE_PKEY_BIT0       0x0100000000000000UL
 
 #define _PAGE_PTE              0x4000000000000000UL    /* distinguishes PTEs from pointers */
 #define _PAGE_PRESENT          0x8000000000000000UL    /* pte contains a translation */
  */
 #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
+#define _RPAGE_PA_MAX          56
 
 /*
  * Max physical address bit we will use for now.
                         _PAGE_ACCESSED | _PAGE_SPECIAL | _PAGE_PTE |   \
                         _PAGE_SOFT_DIRTY | _PAGE_DEVMAP)
 
-#define H_PTE_PKEY  (H_PTE_PKEY_BIT0 | H_PTE_PKEY_BIT1 | H_PTE_PKEY_BIT2 | \
-                    H_PTE_PKEY_BIT3 | H_PTE_PKEY_BIT4)
 /*
  * We define 2 sets of base prot bits, one for basic pages (ie,
  * cacheable kernel and user pages) and one for non cacheable