diff options
Diffstat (limited to 'arch/powerpc/mm/slb_low.S')
-rw-r--r-- | arch/powerpc/mm/slb_low.S | 52 |
1 files changed, 33 insertions, 19 deletions
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S index b10e4707d7c1..cd1a93d4948c 100644 --- a/arch/powerpc/mm/slb_low.S +++ b/arch/powerpc/mm/slb_low.S | |||
@@ -82,31 +82,45 @@ _GLOBAL(slb_miss_kernel_load_io) | |||
82 | srdi. r9,r10,USER_ESID_BITS | 82 | srdi. r9,r10,USER_ESID_BITS |
83 | bne- 8f /* invalid ea bits set */ | 83 | bne- 8f /* invalid ea bits set */ |
84 | 84 | ||
85 | /* Figure out if the segment contains huge pages */ | 85 | |
86 | #ifdef CONFIG_HUGETLB_PAGE | 86 | /* when using slices, we extract the psize off the slice bitmaps |
87 | BEGIN_FTR_SECTION | 87 | * and then we need to get the sllp encoding off the mmu_psize_defs |
88 | b 1f | 88 | * array. |
89 | END_FTR_SECTION_IFCLR(CPU_FTR_16M_PAGE) | 89 | * |
90 | * XXX This is a bit inefficient especially for the normal case, | ||
91 | * so we should try to implement a fast path for the standard page | ||
92 | * size using the old sllp value so we avoid the array. We cannot | ||
93 | * really do dynamic patching unfortunately as processes might flip | ||
94 | * between 4k and 64k standard page size | ||
95 | */ | ||
96 | #ifdef CONFIG_PPC_MM_SLICES | ||
90 | cmpldi r10,16 | 97 | cmpldi r10,16 |
91 | 98 | ||
92 | lhz r9,PACALOWHTLBAREAS(r13) | 99 | /* Get the slice index * 4 in r11 and matching slice size mask in r9 */ |
93 | mr r11,r10 | 100 | ld r9,PACALOWSLICESPSIZE(r13) |
101 | sldi r11,r10,2 | ||
94 | blt 5f | 102 | blt 5f |
103 | ld r9,PACAHIGHSLICEPSIZE(r13) | ||
104 | srdi r11,r10,(SLICE_HIGH_SHIFT - SLICE_LOW_SHIFT - 2) | ||
105 | andi. r11,r11,0x3c | ||
95 | 106 | ||
96 | lhz r9,PACAHIGHHTLBAREAS(r13) | 107 | 5: /* Extract the psize and multiply to get an array offset */ |
97 | srdi r11,r10,(HTLB_AREA_SHIFT-SID_SHIFT) | 108 | srd r9,r9,r11 |
98 | 109 | andi. r9,r9,0xf | |
99 | 5: srd r9,r9,r11 | 110 | mulli r9,r9,MMUPSIZEDEFSIZE |
100 | andi. r9,r9,1 | ||
101 | beq 1f | ||
102 | _GLOBAL(slb_miss_user_load_huge) | ||
103 | li r11,0 | ||
104 | b 2f | ||
105 | 1: | ||
106 | #endif /* CONFIG_HUGETLB_PAGE */ | ||
107 | 111 | ||
112 | /* Now get to the array and obtain the sllp | ||
113 | */ | ||
114 | ld r11,PACATOC(r13) | ||
115 | ld r11,mmu_psize_defs@got(r11) | ||
116 | add r11,r11,r9 | ||
117 | ld r11,MMUPSIZESLLP(r11) | ||
118 | ori r11,r11,SLB_VSID_USER | ||
119 | #else | ||
120 | /* paca context sllp already contains the SLB_VSID_USER bits */ | ||
108 | lhz r11,PACACONTEXTSLLP(r13) | 121 | lhz r11,PACACONTEXTSLLP(r13) |
109 | 2: | 122 | #endif /* CONFIG_PPC_MM_SLICES */ |
123 | |||
110 | ld r9,PACACONTEXTID(r13) | 124 | ld r9,PACACONTEXTID(r13) |
111 | rldimi r10,r9,USER_ESID_BITS,0 | 125 | rldimi r10,r9,USER_ESID_BITS,0 |
112 | b slb_finish_load | 126 | b slb_finish_load |