diff options
author | Paul Mackerras <paulus@samba.org> | 2007-10-11 06:37:10 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-10-12 00:05:17 -0400 |
commit | 1189be6508d45183013ddb82b18f4934193de274 (patch) | |
tree | 58924481b4de56699e4a884dce8dc601e71cf7d1 /arch/powerpc/platforms/celleb/htab.c | |
parent | 287e5d6fcccfa38b953cebe307e1ddfd32363355 (diff) |
[POWERPC] Use 1TB segments
This makes the kernel use 1TB segments for all kernel mappings and for
user addresses of 1TB and above, on machines which support them
(currently POWER5+, POWER6 and PA6T).
We detect that the machine supports 1TB segments by looking at the
ibm,processor-segment-sizes property in the device tree.
We don't currently use 1TB segments for user addresses < 1T, since
that would effectively prevent 32-bit processes from using huge pages
unless we also had a way to revert to using 256MB segments. That
would be possible but would involve extra complications (such as
keeping track of which segment size was used when HPTEs were inserted)
and is not addressed here.
Parts of this patch were originally written by Ben Herrenschmidt.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/celleb/htab.c')
-rw-r--r-- | arch/powerpc/platforms/celleb/htab.c | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/arch/powerpc/platforms/celleb/htab.c b/arch/powerpc/platforms/celleb/htab.c index 5e75c77ea8f3..fbf27c74ebda 100644 --- a/arch/powerpc/platforms/celleb/htab.c +++ b/arch/powerpc/platforms/celleb/htab.c | |||
@@ -90,7 +90,7 @@ static inline unsigned int beat_read_mask(unsigned hpte_group) | |||
90 | static long beat_lpar_hpte_insert(unsigned long hpte_group, | 90 | static long beat_lpar_hpte_insert(unsigned long hpte_group, |
91 | unsigned long va, unsigned long pa, | 91 | unsigned long va, unsigned long pa, |
92 | unsigned long rflags, unsigned long vflags, | 92 | unsigned long rflags, unsigned long vflags, |
93 | int psize) | 93 | int psize, int ssize) |
94 | { | 94 | { |
95 | unsigned long lpar_rc; | 95 | unsigned long lpar_rc; |
96 | unsigned long slot; | 96 | unsigned long slot; |
@@ -105,7 +105,8 @@ static long beat_lpar_hpte_insert(unsigned long hpte_group, | |||
105 | "rflags=%lx, vflags=%lx, psize=%d)\n", | 105 | "rflags=%lx, vflags=%lx, psize=%d)\n", |
106 | hpte_group, va, pa, rflags, vflags, psize); | 106 | hpte_group, va, pa, rflags, vflags, psize); |
107 | 107 | ||
108 | hpte_v = hpte_encode_v(va, psize) | vflags | HPTE_V_VALID; | 108 | hpte_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M) | |
109 | vflags | HPTE_V_VALID; | ||
109 | hpte_r = hpte_encode_r(pa, psize) | rflags; | 110 | hpte_r = hpte_encode_r(pa, psize) | rflags; |
110 | 111 | ||
111 | if (!(vflags & HPTE_V_BOLTED)) | 112 | if (!(vflags & HPTE_V_BOLTED)) |
@@ -184,12 +185,12 @@ static void beat_lpar_hptab_clear(void) | |||
184 | static long beat_lpar_hpte_updatepp(unsigned long slot, | 185 | static long beat_lpar_hpte_updatepp(unsigned long slot, |
185 | unsigned long newpp, | 186 | unsigned long newpp, |
186 | unsigned long va, | 187 | unsigned long va, |
187 | int psize, int local) | 188 | int psize, int ssize, int local) |
188 | { | 189 | { |
189 | unsigned long lpar_rc; | 190 | unsigned long lpar_rc; |
190 | unsigned long dummy0, dummy1, want_v; | 191 | unsigned long dummy0, dummy1, want_v; |
191 | 192 | ||
192 | want_v = hpte_encode_v(va, psize); | 193 | want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); |
193 | 194 | ||
194 | DBG_LOW(" update: " | 195 | DBG_LOW(" update: " |
195 | "avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ", | 196 | "avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ", |
@@ -225,8 +226,8 @@ static long beat_lpar_hpte_find(unsigned long va, int psize) | |||
225 | long slot; | 226 | long slot; |
226 | unsigned long want_v, hpte_v; | 227 | unsigned long want_v, hpte_v; |
227 | 228 | ||
228 | hash = hpt_hash(va, mmu_psize_defs[psize].shift); | 229 | hash = hpt_hash(va, mmu_psize_defs[psize].shift, MMU_SEGSIZE_256M); |
229 | want_v = hpte_encode_v(va, psize); | 230 | want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); |
230 | 231 | ||
231 | for (j = 0; j < 2; j++) { | 232 | for (j = 0; j < 2; j++) { |
232 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; | 233 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; |
@@ -251,11 +252,11 @@ static long beat_lpar_hpte_find(unsigned long va, int psize) | |||
251 | 252 | ||
252 | static void beat_lpar_hpte_updateboltedpp(unsigned long newpp, | 253 | static void beat_lpar_hpte_updateboltedpp(unsigned long newpp, |
253 | unsigned long ea, | 254 | unsigned long ea, |
254 | int psize) | 255 | int psize, int ssize) |
255 | { | 256 | { |
256 | unsigned long lpar_rc, slot, vsid, va, dummy0, dummy1; | 257 | unsigned long lpar_rc, slot, vsid, va, dummy0, dummy1; |
257 | 258 | ||
258 | vsid = get_kernel_vsid(ea); | 259 | vsid = get_kernel_vsid(ea, MMU_SEGSIZE_256M); |
259 | va = (vsid << 28) | (ea & 0x0fffffff); | 260 | va = (vsid << 28) | (ea & 0x0fffffff); |
260 | 261 | ||
261 | spin_lock(&beat_htab_lock); | 262 | spin_lock(&beat_htab_lock); |
@@ -270,7 +271,7 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp, | |||
270 | } | 271 | } |
271 | 272 | ||
272 | static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va, | 273 | static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va, |
273 | int psize, int local) | 274 | int psize, int ssize, int local) |
274 | { | 275 | { |
275 | unsigned long want_v; | 276 | unsigned long want_v; |
276 | unsigned long lpar_rc; | 277 | unsigned long lpar_rc; |
@@ -279,7 +280,7 @@ static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va, | |||
279 | 280 | ||
280 | DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n", | 281 | DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n", |
281 | slot, va, psize, local); | 282 | slot, va, psize, local); |
282 | want_v = hpte_encode_v(va, psize); | 283 | want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); |
283 | 284 | ||
284 | spin_lock_irqsave(&beat_htab_lock, flags); | 285 | spin_lock_irqsave(&beat_htab_lock, flags); |
285 | dummy1 = beat_lpar_hpte_getword0(slot); | 286 | dummy1 = beat_lpar_hpte_getword0(slot); |
@@ -310,7 +311,7 @@ void __init hpte_init_beat(void) | |||
310 | static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, | 311 | static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, |
311 | unsigned long va, unsigned long pa, | 312 | unsigned long va, unsigned long pa, |
312 | unsigned long rflags, unsigned long vflags, | 313 | unsigned long rflags, unsigned long vflags, |
313 | int psize) | 314 | int psize, int ssize) |
314 | { | 315 | { |
315 | unsigned long lpar_rc; | 316 | unsigned long lpar_rc; |
316 | unsigned long slot; | 317 | unsigned long slot; |
@@ -325,7 +326,8 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, | |||
325 | "rflags=%lx, vflags=%lx, psize=%d)\n", | 326 | "rflags=%lx, vflags=%lx, psize=%d)\n", |
326 | hpte_group, va, pa, rflags, vflags, psize); | 327 | hpte_group, va, pa, rflags, vflags, psize); |
327 | 328 | ||
328 | hpte_v = hpte_encode_v(va, psize) | vflags | HPTE_V_VALID; | 329 | hpte_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M) | |
330 | vflags | HPTE_V_VALID; | ||
329 | hpte_r = hpte_encode_r(pa, psize) | rflags; | 331 | hpte_r = hpte_encode_r(pa, psize) | rflags; |
330 | 332 | ||
331 | if (!(vflags & HPTE_V_BOLTED)) | 333 | if (!(vflags & HPTE_V_BOLTED)) |
@@ -363,13 +365,13 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, | |||
363 | static long beat_lpar_hpte_updatepp_v3(unsigned long slot, | 365 | static long beat_lpar_hpte_updatepp_v3(unsigned long slot, |
364 | unsigned long newpp, | 366 | unsigned long newpp, |
365 | unsigned long va, | 367 | unsigned long va, |
366 | int psize, int local) | 368 | int psize, int ssize, int local) |
367 | { | 369 | { |
368 | unsigned long lpar_rc; | 370 | unsigned long lpar_rc; |
369 | unsigned long want_v; | 371 | unsigned long want_v; |
370 | unsigned long pss; | 372 | unsigned long pss; |
371 | 373 | ||
372 | want_v = hpte_encode_v(va, psize); | 374 | want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); |
373 | pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc; | 375 | pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc; |
374 | 376 | ||
375 | DBG_LOW(" update: " | 377 | DBG_LOW(" update: " |
@@ -391,7 +393,7 @@ static long beat_lpar_hpte_updatepp_v3(unsigned long slot, | |||
391 | } | 393 | } |
392 | 394 | ||
393 | static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long va, | 395 | static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long va, |
394 | int psize, int local) | 396 | int psize, int ssize, int local) |
395 | { | 397 | { |
396 | unsigned long want_v; | 398 | unsigned long want_v; |
397 | unsigned long lpar_rc; | 399 | unsigned long lpar_rc; |
@@ -399,7 +401,7 @@ static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long va, | |||
399 | 401 | ||
400 | DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n", | 402 | DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n", |
401 | slot, va, psize, local); | 403 | slot, va, psize, local); |
402 | want_v = hpte_encode_v(va, psize); | 404 | want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); |
403 | pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc; | 405 | pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc; |
404 | 406 | ||
405 | lpar_rc = beat_invalidate_htab_entry3(0, slot, want_v, pss); | 407 | lpar_rc = beat_invalidate_htab_entry3(0, slot, want_v, pss); |