diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/mm/hash_native_64.c | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index 7b7fe2d7b9dc..7d722eea4ea8 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c | |||
@@ -376,31 +376,28 @@ static void hpte_decode(hpte_t *hpte, unsigned long slot, | |||
376 | } | 376 | } |
377 | } | 377 | } |
378 | 378 | ||
379 | /* | 379 | /* This works for all page sizes, and for 256M and 1T segments */ |
380 | * FIXME, the code below works for 16M, 64K, and 4K pages as these | ||
381 | * fall under the p<=23 rules for calculating the virtual address. | ||
382 | * In the case of 16M pages, an extra bit is stolen from the AVPN | ||
383 | * field to achieve the requisite 24 bits. | ||
384 | * | ||
385 | * Does not work for 16G pages or 1 TB segments. | ||
386 | */ | ||
387 | shift = mmu_psize_defs[size].shift; | 380 | shift = mmu_psize_defs[size].shift; |
388 | if (mmu_psize_defs[size].avpnm) | 381 | avpn = (HPTE_V_AVPN_VAL(hpte_v) & ~mmu_psize_defs[size].avpnm) << 23; |
389 | avpnm_bits = __ilog2_u64(mmu_psize_defs[size].avpnm) + 1; | ||
390 | else | ||
391 | avpnm_bits = 0; | ||
392 | if (shift - avpnm_bits <= 23) { | ||
393 | avpn = HPTE_V_AVPN_VAL(hpte_v) << 23; | ||
394 | 382 | ||
395 | if (shift < 23) { | 383 | if (shift < 23) { |
396 | unsigned long vpi, pteg; | 384 | unsigned long vpi, vsid, pteg; |
397 | 385 | ||
398 | pteg = slot / HPTES_PER_GROUP; | 386 | pteg = slot / HPTES_PER_GROUP; |
399 | if (hpte_v & HPTE_V_SECONDARY) | 387 | if (hpte_v & HPTE_V_SECONDARY) |
400 | pteg = ~pteg; | 388 | pteg = ~pteg; |
389 | switch (hpte_v >> HPTE_V_SSIZE_SHIFT) { | ||
390 | case MMU_SEGSIZE_256M: | ||
401 | vpi = ((avpn >> 28) ^ pteg) & htab_hash_mask; | 391 | vpi = ((avpn >> 28) ^ pteg) & htab_hash_mask; |
402 | avpn |= (vpi << mmu_psize_defs[size].shift); | 392 | break; |
393 | case MMU_SEGSIZE_1T: | ||
394 | vsid = avpn >> 40; | ||
395 | vpi = (vsid ^ (vsid << 25) ^ pteg) & htab_hash_mask; | ||
396 | break; | ||
397 | default: | ||
398 | avpn = vpi = psize = 0; | ||
403 | } | 399 | } |
400 | avpn |= (vpi << mmu_psize_defs[size].shift); | ||
404 | } | 401 | } |
405 | 402 | ||
406 | *va = avpn; | 403 | *va = avpn; |