Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/mm: Add 64TB support

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>

authored by

Aneesh Kumar K.V and committed by
Benjamin Herrenschmidt
048ee099 735cafc3

+54 -16
+33 -9
arch/powerpc/include/asm/mmu-hash64.h
··· 370 370 * (head.S) and ASM_VSID_SCRAMBLE (below) are changed accordingly. 371 371 */ 372 372 373 - #define VSID_MULTIPLIER_256M ASM_CONST(200730139) /* 28-bit prime */ 374 - #define VSID_BITS_256M 36 373 + /* 374 + * This should be computed such that protovosid * vsid_mulitplier 375 + * doesn't overflow 64 bits. It should also be co-prime to vsid_modulus 376 + */ 377 + #define VSID_MULTIPLIER_256M ASM_CONST(12538073) /* 24-bit prime */ 378 + #define VSID_BITS_256M 38 375 379 #define VSID_MODULUS_256M ((1UL<<VSID_BITS_256M)-1) 376 380 377 381 #define VSID_MULTIPLIER_1T ASM_CONST(12538073) /* 24-bit prime */ 378 - #define VSID_BITS_1T 24 382 + #define VSID_BITS_1T 26 379 383 #define VSID_MODULUS_1T ((1UL<<VSID_BITS_1T)-1) 380 384 381 385 #define CONTEXT_BITS 19 382 - #define USER_ESID_BITS 16 383 - #define USER_ESID_BITS_1T 4 386 + #define USER_ESID_BITS 18 387 + #define USER_ESID_BITS_1T 6 384 388 385 389 #define USER_VSID_RANGE (1UL << (USER_ESID_BITS + SID_SHIFT)) 386 390 ··· 504 500 }) 505 501 #endif /* 1 */ 506 502 507 - /* This is only valid for addresses >= PAGE_OFFSET */ 503 + /* 504 + * This is only valid for addresses >= PAGE_OFFSET 505 + * The proto-VSID space is divided into two class 506 + * User: 0 to 2^(CONTEXT_BITS + USER_ESID_BITS) -1 507 + * kernel: 2^(CONTEXT_BITS + USER_ESID_BITS) to 2^(VSID_BITS) - 1 508 + * 509 + * With KERNEL_START at 0xc000000000000000, the proto vsid for 510 + * the kernel ends up with 0xc00000000 (36 bits). With 64TB 511 + * support we need to have kernel proto-VSID in the 512 + * [2^37 to 2^38 - 1] range due to the increased USER_ESID_BITS. 513 + */ 508 514 static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize) 509 515 { 510 - if (ssize == MMU_SEGSIZE_256M) 511 - return vsid_scramble(ea >> SID_SHIFT, 256M); 512 - return vsid_scramble(ea >> SID_SHIFT_1T, 1T); 516 + unsigned long proto_vsid; 517 + /* 518 + * We need to make sure proto_vsid for the kernel is 519 + * >= 2^(CONTEXT_BITS + USER_ESID_BITS[_1T]) 520 + */ 521 + if (ssize == MMU_SEGSIZE_256M) { 522 + proto_vsid = ea >> SID_SHIFT; 523 + proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS)); 524 + return vsid_scramble(proto_vsid, 256M); 525 + } 526 + proto_vsid = ea >> SID_SHIFT_1T; 527 + proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS_1T)); 528 + return vsid_scramble(proto_vsid, 1T); 513 529 } 514 530 515 531 /* Returns the segment size indicator for a user address */
+1 -1
arch/powerpc/include/asm/pgtable-ppc64-4k.h
··· 7 7 */ 8 8 #define PTE_INDEX_SIZE 9 9 9 #define PMD_INDEX_SIZE 7 10 - #define PUD_INDEX_SIZE 7 10 + #define PUD_INDEX_SIZE 9 11 11 #define PGD_INDEX_SIZE 9 12 12 13 13 #ifndef __ASSEMBLY__
+1 -1
arch/powerpc/include/asm/pgtable-ppc64-64k.h
··· 7 7 #define PTE_INDEX_SIZE 12 8 8 #define PMD_INDEX_SIZE 12 9 9 #define PUD_INDEX_SIZE 0 10 - #define PGD_INDEX_SIZE 4 10 + #define PGD_INDEX_SIZE 6 11 11 12 12 #ifndef __ASSEMBLY__ 13 13 #define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE)
+2 -2
arch/powerpc/include/asm/processor.h
··· 97 97 #endif 98 98 99 99 #ifdef CONFIG_PPC64 100 - /* 64-bit user address space is 44-bits (16TB user VM) */ 101 - #define TASK_SIZE_USER64 (0x0000100000000000UL) 100 + /* 64-bit user address space is 46-bits (64TB user VM) */ 101 + #define TASK_SIZE_USER64 (0x0000400000000000UL) 102 102 103 103 /* 104 104 * 32-bit user address space is 4GB - 1 page
+2 -2
arch/powerpc/include/asm/sparsemem.h
··· 10 10 */ 11 11 #define SECTION_SIZE_BITS 24 12 12 13 - #define MAX_PHYSADDR_BITS 44 14 - #define MAX_PHYSMEM_BITS 44 13 + #define MAX_PHYSADDR_BITS 46 14 + #define MAX_PHYSMEM_BITS 46 15 15 16 16 #endif /* CONFIG_SPARSEMEM */ 17 17
+3 -1
arch/powerpc/kernel/exceptions-64s.S
··· 1083 1083 rldimi r10,r11,7,52 /* r10 = first ste of the group */ 1084 1084 1085 1085 /* Calculate VSID */ 1086 - /* This is a kernel address, so protovsid = ESID */ 1086 + /* This is a kernel address, so protovsid = ESID | 1 << 37 */ 1087 + li r9,0x1 1088 + rldimi r11,r9,(CONTEXT_BITS + USER_ESID_BITS),0 1087 1089 ASM_VSID_SCRAMBLE(r11, r9, 256M) 1088 1090 rldic r9,r11,12,16 /* r9 = vsid << 12 */ 1089 1091
+12
arch/powerpc/mm/slb_low.S
··· 56 56 */ 57 57 _GLOBAL(slb_miss_kernel_load_linear) 58 58 li r11,0 59 + li r9,0x1 60 + /* 61 + * for 1T we shift 12 bits more. slb_finish_load_1T will do 62 + * the necessary adjustment 63 + */ 64 + rldimi r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0 59 65 BEGIN_FTR_SECTION 60 66 b slb_finish_load 61 67 END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT) ··· 91 85 _GLOBAL(slb_miss_kernel_load_io) 92 86 li r11,0 93 87 6: 88 + li r9,0x1 89 + /* 90 + * for 1T we shift 12 bits more. slb_finish_load_1T will do 91 + * the necessary adjustment 92 + */ 93 + rldimi r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0 94 94 BEGIN_FTR_SECTION 95 95 b slb_finish_load 96 96 END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)