powerpc: Split the code trying to insert hpte repeatedly as an helper function
Move the logic trying to insert hpte in __hash_page_huge() to an helper function, so it could also be used by others. Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
This commit is contained in:
parent
2c3c0693d9
commit
b170bd3de6
|
@ -1230,6 +1230,41 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc)
|
|||
bad_page_fault(regs, address, SIGBUS);
|
||||
}
|
||||
|
||||
long hpte_insert_repeating(unsigned long hash, unsigned long vpn,
|
||||
unsigned long pa, unsigned long rflags,
|
||||
unsigned long vflags, int psize, int ssize)
|
||||
{
|
||||
unsigned long hpte_group;
|
||||
long slot;
|
||||
|
||||
repeat:
|
||||
hpte_group = ((hash & htab_hash_mask) *
|
||||
HPTES_PER_GROUP) & ~0x7UL;
|
||||
|
||||
/* Insert into the hash table, primary slot */
|
||||
slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, vflags,
|
||||
psize, ssize);
|
||||
|
||||
/* Primary is full, try the secondary */
|
||||
if (unlikely(slot == -1)) {
|
||||
hpte_group = ((~hash & htab_hash_mask) *
|
||||
HPTES_PER_GROUP) & ~0x7UL;
|
||||
slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags,
|
||||
vflags | HPTE_V_SECONDARY,
|
||||
psize, ssize);
|
||||
if (slot == -1) {
|
||||
if (mftb() & 0x1)
|
||||
hpte_group = ((hash & htab_hash_mask) *
|
||||
HPTES_PER_GROUP)&~0x7UL;
|
||||
|
||||
ppc_md.hpte_remove(hpte_group);
|
||||
goto repeat;
|
||||
}
|
||||
}
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_PAGEALLOC
|
||||
static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi)
|
||||
{
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
#include <asm/cacheflush.h>
|
||||
#include <asm/machdep.h>
|
||||
|
||||
extern long hpte_insert_repeating(unsigned long hash, unsigned long vpn,
|
||||
unsigned long pa, unsigned long rlags,
|
||||
unsigned long vflags, int psize, int ssize);
|
||||
|
||||
int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
|
||||
pte_t *ptep, unsigned long trap, int local, int ssize,
|
||||
unsigned int shift, unsigned int mmu_psize)
|
||||
|
@ -83,7 +87,6 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
|
|||
|
||||
if (likely(!(old_pte & _PAGE_HASHPTE))) {
|
||||
unsigned long hash = hpt_hash(vpn, shift, ssize);
|
||||
unsigned long hpte_group;
|
||||
|
||||
pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
|
||||
|
||||
|
@ -97,30 +100,8 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
|
|||
rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE |
|
||||
_PAGE_COHERENT | _PAGE_GUARDED));
|
||||
|
||||
repeat:
|
||||
hpte_group = ((hash & htab_hash_mask) *
|
||||
HPTES_PER_GROUP) & ~0x7UL;
|
||||
|
||||
/* Insert into the hash table, primary slot */
|
||||
slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0,
|
||||
mmu_psize, ssize);
|
||||
|
||||
/* Primary is full, try the secondary */
|
||||
if (unlikely(slot == -1)) {
|
||||
hpte_group = ((~hash & htab_hash_mask) *
|
||||
HPTES_PER_GROUP) & ~0x7UL;
|
||||
slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags,
|
||||
HPTE_V_SECONDARY,
|
||||
mmu_psize, ssize);
|
||||
if (slot == -1) {
|
||||
if (mftb() & 0x1)
|
||||
hpte_group = ((hash & htab_hash_mask) *
|
||||
HPTES_PER_GROUP)&~0x7UL;
|
||||
|
||||
ppc_md.hpte_remove(hpte_group);
|
||||
goto repeat;
|
||||
}
|
||||
}
|
||||
slot = hpte_insert_repeating(hash, vpn, pa, rflags, 0,
|
||||
mmu_psize, ssize);
|
||||
|
||||
/*
|
||||
* Hypervisor failure. Restore old pte and return -1
|
||||
|
|
Loading…
Reference in New Issue