Separate out the hashing function from kvmppc_hv_find_lock_hpte() as kvmppc_hv_get_hash_value() to allow this function to be reused and prevent code duplication. No functional change. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@xxxxxxxxx> --- arch/powerpc/kvm/book3s_hv_rm_mmu.c | 60 ++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index a939782d8a5e..c8a379a6f533 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c @@ -1162,6 +1162,40 @@ static struct mmio_hpte_cache_entry * return &vcpu->arch.mmio_cache.entry[index]; } +/* + * Given an effective address and a slb entry, work out the hash and the + * virtual page number + */ +unsigned long kvmppc_hv_get_hash_value(struct kvm_hpt_info *hpt, gva_t eaddr, + unsigned long slb_v, unsigned long *avpn, + unsigned int *pshift_p) +{ + unsigned long hash, somask, vsid; + unsigned int pshift = 12; + + if (slb_v & SLB_VSID_L) + pshift = slb_base_page_shift[(slb_v & SLB_VSID_LP) >> 4]; + if (slb_v & SLB_VSID_B_1T) { + somask = (1UL << 40) - 1; + vsid = (slb_v & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T; + vsid ^= vsid << 25; + } else { + somask = (1UL << 28) - 1; + vsid = (slb_v & ~SLB_VSID_B) >> SLB_VSID_SHIFT; + } + hash = (vsid ^ ((eaddr & somask) >> pshift)) & kvmppc_hpt_mask(hpt); + *avpn = slb_v & ~(somask >> 16); /* also includes B */ + *avpn |= (eaddr & somask) >> 16; + + if (pshift >= 24) + *avpn &= ~((1UL << (pshift - 16)) - 1); + else + *avpn &= ~0x7fUL; + *pshift_p = pshift; + + return hash; +} + /* When called from virtmode, this func should be protected by * preempt_disable(), otherwise, the holding of HPTE_V_HVLOCK * can trigger deadlock issue. @@ -1171,39 +1205,17 @@ long kvmppc_hv_find_lock_hpte(struct kvm_hpt_info *hpt, gva_t eaddr, { unsigned int i; unsigned int pshift; - unsigned long somask; - unsigned long vsid, hash; - unsigned long avpn; __be64 *hpte; - unsigned long mask, val; + unsigned long hash, mask, val; unsigned long v, r, orig_v; /* Get page shift, work out hash and AVPN etc. */ mask = SLB_VSID_B | HPTE_V_AVPN | HPTE_V_SECONDARY; - val = 0; - pshift = 12; + hash = kvmppc_hv_get_hash_value(hpt, eaddr, slb_v, &val, &pshift); if (slb_v & SLB_VSID_L) { mask |= HPTE_V_LARGE; val |= HPTE_V_LARGE; - pshift = slb_base_page_shift[(slb_v & SLB_VSID_LP) >> 4]; - } - if (slb_v & SLB_VSID_B_1T) { - somask = (1UL << 40) - 1; - vsid = (slb_v & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T; - vsid ^= vsid << 25; - } else { - somask = (1UL << 28) - 1; - vsid = (slb_v & ~SLB_VSID_B) >> SLB_VSID_SHIFT; } - hash = (vsid ^ ((eaddr & somask) >> pshift)) & kvmppc_hpt_mask(hpt); - avpn = slb_v & ~(somask >> 16); /* also includes B */ - avpn |= (eaddr & somask) >> 16; - - if (pshift >= 24) - avpn &= ~((1UL << (pshift - 16)) - 1); - else - avpn &= ~0x7fUL; - val |= avpn; for (;;) { hpte = (__be64 *)(hpt->virt + (hash << 7)); -- 2.13.6