|
@@ -103,8 +103,8 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
|
|
* On hash insert failure we use old pte value and we don't
|
|
* On hash insert failure we use old pte value and we don't
|
|
* want slot information there if we have a insert failure.
|
|
* want slot information there if we have a insert failure.
|
|
*/
|
|
*/
|
|
- old_pte &= ~(H_PAGE_HASHPTE | H_PAGE_F_GIX | H_PAGE_F_SECOND);
|
|
|
|
- new_pte &= ~(H_PAGE_HASHPTE | H_PAGE_F_GIX | H_PAGE_F_SECOND);
|
|
|
|
|
|
+ old_pte &= ~H_PAGE_HASHPTE;
|
|
|
|
+ new_pte &= ~H_PAGE_HASHPTE;
|
|
goto htab_insert_hpte;
|
|
goto htab_insert_hpte;
|
|
}
|
|
}
|
|
/*
|
|
/*
|
|
@@ -225,6 +225,7 @@ int __hash_page_64K(unsigned long ea, unsigned long access,
|
|
unsigned long vsid, pte_t *ptep, unsigned long trap,
|
|
unsigned long vsid, pte_t *ptep, unsigned long trap,
|
|
unsigned long flags, int ssize)
|
|
unsigned long flags, int ssize)
|
|
{
|
|
{
|
|
|
|
+ real_pte_t rpte;
|
|
unsigned long hpte_group;
|
|
unsigned long hpte_group;
|
|
unsigned long rflags, pa;
|
|
unsigned long rflags, pa;
|
|
unsigned long old_pte, new_pte;
|
|
unsigned long old_pte, new_pte;
|
|
@@ -261,6 +262,7 @@ int __hash_page_64K(unsigned long ea, unsigned long access,
|
|
} while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
|
|
} while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
|
|
|
|
|
|
rflags = htab_convert_pte_flags(new_pte);
|
|
rflags = htab_convert_pte_flags(new_pte);
|
|
|
|
+ rpte = __real_pte(__pte(old_pte), ptep);
|
|
|
|
|
|
if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
|
|
if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
|
|
!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
|
|
!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
|
|
@@ -268,16 +270,13 @@ int __hash_page_64K(unsigned long ea, unsigned long access,
|
|
|
|
|
|
vpn = hpt_vpn(ea, vsid, ssize);
|
|
vpn = hpt_vpn(ea, vsid, ssize);
|
|
if (unlikely(old_pte & H_PAGE_HASHPTE)) {
|
|
if (unlikely(old_pte & H_PAGE_HASHPTE)) {
|
|
|
|
+ unsigned long gslot;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* There MIGHT be an HPTE for this pte
|
|
* There MIGHT be an HPTE for this pte
|
|
*/
|
|
*/
|
|
- hash = hpt_hash(vpn, shift, ssize);
|
|
|
|
- if (old_pte & H_PAGE_F_SECOND)
|
|
|
|
- hash = ~hash;
|
|
|
|
- slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
|
|
|
|
- slot += (old_pte & H_PAGE_F_GIX) >> H_PAGE_F_GIX_SHIFT;
|
|
|
|
-
|
|
|
|
- if (mmu_hash_ops.hpte_updatepp(slot, rflags, vpn, MMU_PAGE_64K,
|
|
|
|
|
|
+ gslot = pte_get_hash_gslot(vpn, shift, ssize, rpte, 0);
|
|
|
|
+ if (mmu_hash_ops.hpte_updatepp(gslot, rflags, vpn, MMU_PAGE_64K,
|
|
MMU_PAGE_64K, ssize,
|
|
MMU_PAGE_64K, ssize,
|
|
flags) == -1)
|
|
flags) == -1)
|
|
old_pte &= ~_PAGE_HPTEFLAGS;
|
|
old_pte &= ~_PAGE_HPTEFLAGS;
|
|
@@ -326,9 +325,9 @@ repeat:
|
|
MMU_PAGE_64K, MMU_PAGE_64K, old_pte);
|
|
MMU_PAGE_64K, MMU_PAGE_64K, old_pte);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
+
|
|
new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | H_PAGE_HASHPTE;
|
|
new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | H_PAGE_HASHPTE;
|
|
- new_pte |= (slot << H_PAGE_F_GIX_SHIFT) &
|
|
|
|
- (H_PAGE_F_SECOND | H_PAGE_F_GIX);
|
|
|
|
|
|
+ new_pte |= pte_set_hidx(ptep, rpte, 0, slot);
|
|
}
|
|
}
|
|
*ptep = __pte(new_pte & ~H_PAGE_BUSY);
|
|
*ptep = __pte(new_pte & ~H_PAGE_BUSY);
|
|
return 0;
|
|
return 0;
|