powerpc/mm: Add 64TB support
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Mon, 10 Sep 2012 02:52:55 +0000 (02:52 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Mon, 17 Sep 2012 06:31:51 +0000 (16:31 +1000)
Increase max addressable range to 64TB. This is not tested on
real hardware yet.

Reviewed-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/include/asm/mmu-hash64.h
arch/powerpc/include/asm/pgtable-ppc64-4k.h
arch/powerpc/include/asm/pgtable-ppc64-64k.h
arch/powerpc/include/asm/processor.h
arch/powerpc/include/asm/sparsemem.h
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/mm/slb_low.S

index 7cbd541f915f8f9675fc2a94949d2f424643de74..23730ee65aa0afbe60aa67313732eae9d9d22630 100644 (file)
@@ -370,17 +370,21 @@ extern void slb_set_size(u16 size);
  * (head.S) and ASM_VSID_SCRAMBLE (below) are changed accordingly.
  */
 
-#define VSID_MULTIPLIER_256M   ASM_CONST(200730139)    /* 28-bit prime */
-#define VSID_BITS_256M         36
+/*
+ * This should be computed such that protovosid * vsid_mulitplier
+ * doesn't overflow 64 bits. It should also be co-prime to vsid_modulus
+ */
+#define VSID_MULTIPLIER_256M   ASM_CONST(12538073)     /* 24-bit prime */
+#define VSID_BITS_256M         38
 #define VSID_MODULUS_256M      ((1UL<<VSID_BITS_256M)-1)
 
 #define VSID_MULTIPLIER_1T     ASM_CONST(12538073)     /* 24-bit prime */
-#define VSID_BITS_1T           24
+#define VSID_BITS_1T           26
 #define VSID_MODULUS_1T                ((1UL<<VSID_BITS_1T)-1)
 
 #define CONTEXT_BITS           19
-#define USER_ESID_BITS         16
-#define USER_ESID_BITS_1T      4
+#define USER_ESID_BITS         18
+#define USER_ESID_BITS_1T      6
 
 #define USER_VSID_RANGE        (1UL << (USER_ESID_BITS + SID_SHIFT))
 
@@ -500,12 +504,32 @@ typedef struct {
        })
 #endif /* 1 */
 
-/* This is only valid for addresses >= PAGE_OFFSET */
+/*
+ * This is only valid for addresses >= PAGE_OFFSET
+ * The proto-VSID space is divided into two class
+ * User:   0 to 2^(CONTEXT_BITS + USER_ESID_BITS) -1
+ * kernel: 2^(CONTEXT_BITS + USER_ESID_BITS) to 2^(VSID_BITS) - 1
+ *
+ * With KERNEL_START at 0xc000000000000000, the proto vsid for
+ * the kernel ends up with 0xc00000000 (36 bits). With 64TB
+ * support we need to have kernel proto-VSID in the
+ * [2^37 to 2^38 - 1] range due to the increased USER_ESID_BITS.
+ */
 static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
 {
-       if (ssize == MMU_SEGSIZE_256M)
-               return vsid_scramble(ea >> SID_SHIFT, 256M);
-       return vsid_scramble(ea >> SID_SHIFT_1T, 1T);
+       unsigned long proto_vsid;
+       /*
+        * We need to make sure proto_vsid for the kernel is
+        * >= 2^(CONTEXT_BITS + USER_ESID_BITS[_1T])
+        */
+       if (ssize == MMU_SEGSIZE_256M) {
+               proto_vsid = ea >> SID_SHIFT;
+               proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS));
+               return vsid_scramble(proto_vsid, 256M);
+       }
+       proto_vsid = ea >> SID_SHIFT_1T;
+       proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS_1T));
+       return vsid_scramble(proto_vsid, 1T);
 }
 
 /* Returns the segment size indicator for a user address */
index d6489a2c64c8370c859bb743d0f3f883e0189283..12798c9d4b4ba5401c77c41bc605e722a11b6266 100644 (file)
@@ -7,7 +7,7 @@
  */
 #define PTE_INDEX_SIZE  9
 #define PMD_INDEX_SIZE  7
-#define PUD_INDEX_SIZE  7
+#define PUD_INDEX_SIZE  9
 #define PGD_INDEX_SIZE  9
 
 #ifndef __ASSEMBLY__
index 90533ddcd7035241cb14372fb8f0b2a284a64c5a..be4e2878fbc012b1443f27c08031aac6450d3d7e 100644 (file)
@@ -7,7 +7,7 @@
 #define PTE_INDEX_SIZE  12
 #define PMD_INDEX_SIZE  12
 #define PUD_INDEX_SIZE 0
-#define PGD_INDEX_SIZE  4
+#define PGD_INDEX_SIZE  6
 
 #ifndef __ASSEMBLY__
 #define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE)
index 83efc6e81543b3785ad422fc87835acba869f422..9dc5cd1fde1a9107614709d1082270361ac71882 100644 (file)
@@ -97,8 +97,8 @@ extern struct task_struct *last_task_used_spe;
 #endif
 
 #ifdef CONFIG_PPC64
-/* 64-bit user address space is 44-bits (16TB user VM) */
-#define TASK_SIZE_USER64 (0x0000100000000000UL)
+/* 64-bit user address space is 46-bits (64TB user VM) */
+#define TASK_SIZE_USER64 (0x0000400000000000UL)
 
 /* 
  * 32-bit user address space is 4GB - 1 page 
index 0c5fa3145615c28074208ca64e79fdac12b06170..f6fc0ee813d7afad1cd4572674b363fa5b9e0430 100644 (file)
@@ -10,8 +10,8 @@
  */
 #define SECTION_SIZE_BITS       24
 
-#define MAX_PHYSADDR_BITS       44
-#define MAX_PHYSMEM_BITS        44
+#define MAX_PHYSADDR_BITS       46
+#define MAX_PHYSMEM_BITS        46
 
 #endif /* CONFIG_SPARSEMEM */
 
index 5eb00569199fe40ea7ac85a7d1511d8f2a213ec6..10b658ad65e16b455d7239670d42c0ae5c0b4d3b 100644 (file)
@@ -1083,7 +1083,9 @@ _GLOBAL(do_stab_bolted)
        rldimi  r10,r11,7,52    /* r10 = first ste of the group */
 
        /* Calculate VSID */
-       /* This is a kernel address, so protovsid = ESID */
+       /* This is a kernel address, so protovsid = ESID | 1 << 37 */
+       li      r9,0x1
+       rldimi  r11,r9,(CONTEXT_BITS + USER_ESID_BITS),0
        ASM_VSID_SCRAMBLE(r11, r9, 256M)
        rldic   r9,r11,12,16    /* r9 = vsid << 12 */
 
index f6a262555ef2bb337ff7d3b10b525366052990d1..1a16ca2277575fef9c0614df84f6e4f93df376f1 100644 (file)
@@ -56,6 +56,12 @@ _GLOBAL(slb_allocate_realmode)
         */
 _GLOBAL(slb_miss_kernel_load_linear)
        li      r11,0
+       li      r9,0x1
+       /*
+        * for 1T we shift 12 bits more.  slb_finish_load_1T will do
+        * the necessary adjustment
+        */
+       rldimi  r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0
 BEGIN_FTR_SECTION
        b       slb_finish_load
 END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
@@ -85,6 +91,12 @@ _GLOBAL(slb_miss_kernel_load_vmemmap)
        _GLOBAL(slb_miss_kernel_load_io)
        li      r11,0
 6:
+       li      r9,0x1
+       /*
+        * for 1T we shift 12 bits more.  slb_finish_load_1T will do
+        * the necessary adjustment
+        */
+       rldimi  r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0
 BEGIN_FTR_SECTION
        b       slb_finish_load
 END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)