[PATCH 1/3] KVM: PPC: BOOK3S: HV: Add helpers for lock/unlock hpte
Aneesh Kumar K.V
aneesh.kumar at linux.vnet.ibm.com
Tue Jan 13 16:09:27 AEDT 2015
Hi,
Any update on this patch. We could drop patch 3. Any feedback on 1 and 2
?.
-aneesh
"Aneesh Kumar K.V" <aneesh.kumar at linux.vnet.ibm.com> writes:
> This patch adds helper routine for lock and unlock hpte and use
> the same for rest of the code. We don't change any locking rules in this
> patch. In the next patch we switch some of the unlock usage to use
> the api with barrier and also document the usage without barriers.
>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/kvm_book3s_64.h | 14 ++++++++++++++
> arch/powerpc/kvm/book3s_64_mmu_hv.c | 25 ++++++++++---------------
> arch/powerpc/kvm/book3s_hv_rm_mmu.c | 27 ++++++++++-----------------
> 3 files changed, 34 insertions(+), 32 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h
> index 0aa817933e6a..ec9fb6085843 100644
> --- a/arch/powerpc/include/asm/kvm_book3s_64.h
> +++ b/arch/powerpc/include/asm/kvm_book3s_64.h
> @@ -86,6 +86,20 @@ static inline long try_lock_hpte(__be64 *hpte, unsigned long bits)
> return old == 0;
> }
>
> +static inline void unlock_hpte(__be64 *hpte, unsigned long hpte_v)
> +{
> + hpte_v &= ~HPTE_V_HVLOCK;
> + asm volatile(PPC_RELEASE_BARRIER "" : : : "memory");
> + hpte[0] = cpu_to_be64(hpte_v);
> +}
> +
> +/* Without barrier */
> +static inline void __unlock_hpte(__be64 *hpte, unsigned long hpte_v)
> +{
> + hpte_v &= ~HPTE_V_HVLOCK;
> + hpte[0] = cpu_to_be64(hpte_v);
> +}
> +
> static inline int __hpte_actual_psize(unsigned int lp, int psize)
> {
> int i, shift;
> diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
> index cebb86bc4a37..5ea4b2b6a157 100644
> --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
> @@ -475,9 +475,7 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
> v = be64_to_cpu(hptep[0]) & ~HPTE_V_HVLOCK;
> gr = kvm->arch.revmap[index].guest_rpte;
>
> - /* Unlock the HPTE */
> - asm volatile("lwsync" : : : "memory");
> - hptep[0] = cpu_to_be64(v);
> + unlock_hpte(hptep, v);
> preempt_enable();
>
> gpte->eaddr = eaddr;
> @@ -606,8 +604,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
> hpte[0] = be64_to_cpu(hptep[0]) & ~HPTE_V_HVLOCK;
> hpte[1] = be64_to_cpu(hptep[1]);
> hpte[2] = r = rev->guest_rpte;
> - asm volatile("lwsync" : : : "memory");
> - hptep[0] = cpu_to_be64(hpte[0]);
> + unlock_hpte(hptep, hpte[0]);
> preempt_enable();
>
> if (hpte[0] != vcpu->arch.pgfault_hpte[0] ||
> @@ -758,7 +755,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
>
> hptep[1] = cpu_to_be64(r);
> eieio();
> - hptep[0] = cpu_to_be64(hpte[0]);
> + __unlock_hpte(hptep, hpte[0]);
> asm volatile("ptesync" : : : "memory");
> preempt_enable();
> if (page && hpte_is_writable(r))
> @@ -777,7 +774,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
> return ret;
>
> out_unlock:
> - hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hptep, be64_to_cpu(hptep[0]));
> preempt_enable();
> goto out_put;
> }
> @@ -907,7 +904,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
> }
> }
> unlock_rmap(rmapp);
> - hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hptep, be64_to_cpu(hptep[0]));
> }
> return 0;
> }
> @@ -995,7 +992,7 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
> }
> ret = 1;
> }
> - hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hptep, be64_to_cpu(hptep[0]));
> } while ((i = j) != head);
>
> unlock_rmap(rmapp);
> @@ -1118,8 +1115,7 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp)
>
> /* Now check and modify the HPTE */
> if (!(hptep[0] & cpu_to_be64(HPTE_V_VALID))) {
> - /* unlock and continue */
> - hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hptep, be64_to_cpu(hptep[0]));
> continue;
> }
> /* need to make it temporarily absent so C is stable */
> @@ -1139,9 +1135,9 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp)
> npages_dirty = n;
> eieio();
> }
> - v &= ~(HPTE_V_ABSENT | HPTE_V_HVLOCK);
> + v &= ~HPTE_V_ABSENT;
> v |= HPTE_V_VALID;
> - hptep[0] = cpu_to_be64(v);
> + __unlock_hpte(hptep, v);
> } while ((i = j) != head);
>
> unlock_rmap(rmapp);
> @@ -1379,8 +1375,7 @@ static long record_hpte(unsigned long flags, __be64 *hptp,
> r &= ~HPTE_GR_MODIFIED;
> revp->guest_rpte = r;
> }
> - asm volatile(PPC_RELEASE_BARRIER "" : : : "memory");
> - hptp[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + unlock_hpte(hptp, be64_to_cpu(hptp[0]));
> preempt_enable();
> if (!(valid == want_valid && (first_pass || dirty)))
> ok = 0;
> diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> index 084ad54c73cd..769a5d4c0430 100644
> --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> @@ -154,12 +154,6 @@ static pte_t lookup_linux_pte_and_update(pgd_t *pgdir, unsigned long hva,
> return kvmppc_read_update_linux_pte(ptep, writing, hugepage_shift);
> }
>
> -static inline void unlock_hpte(__be64 *hpte, unsigned long hpte_v)
> -{
> - asm volatile(PPC_RELEASE_BARRIER "" : : : "memory");
> - hpte[0] = cpu_to_be64(hpte_v);
> -}
> -
> long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
> long pte_index, unsigned long pteh, unsigned long ptel,
> pgd_t *pgdir, bool realmode, unsigned long *pte_idx_ret)
> @@ -295,10 +289,10 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
> u64 pte;
> while (!try_lock_hpte(hpte, HPTE_V_HVLOCK))
> cpu_relax();
> - pte = be64_to_cpu(*hpte);
> + pte = be64_to_cpu(hpte[0]);
> if (!(pte & (HPTE_V_VALID | HPTE_V_ABSENT)))
> break;
> - *hpte &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hpte, pte);
> hpte += 2;
> }
> if (i == 8)
> @@ -314,9 +308,9 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
>
> while (!try_lock_hpte(hpte, HPTE_V_HVLOCK))
> cpu_relax();
> - pte = be64_to_cpu(*hpte);
> + pte = be64_to_cpu(hpte[0]);
> if (pte & (HPTE_V_VALID | HPTE_V_ABSENT)) {
> - *hpte &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hpte, pte);
> return H_PTEG_FULL;
> }
> }
> @@ -356,7 +350,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
>
> /* Write the first HPTE dword, unlocking the HPTE and making it valid */
> eieio();
> - hpte[0] = cpu_to_be64(pteh);
> + __unlock_hpte(hpte, pteh);
> asm volatile("ptesync" : : : "memory");
>
> *pte_idx_ret = pte_index;
> @@ -487,7 +481,7 @@ long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags,
> if ((pte & (HPTE_V_ABSENT | HPTE_V_VALID)) == 0 ||
> ((flags & H_AVPN) && (pte & ~0x7fUL) != avpn) ||
> ((flags & H_ANDCOND) && (pte & avpn) != 0)) {
> - hpte[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hpte, pte);
> return H_NOT_FOUND;
> }
>
> @@ -623,7 +617,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu)
> be64_to_cpu(hp[0]), be64_to_cpu(hp[1]));
> rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C);
> args[j] |= rcbits << (56 - 5);
> - hp[0] = 0;
> + __unlock_hpte(hp, 0);
> }
> }
>
> @@ -649,7 +643,7 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags,
> pte = be64_to_cpu(hpte[0]);
> if ((pte & (HPTE_V_ABSENT | HPTE_V_VALID)) == 0 ||
> ((flags & H_AVPN) && (pte & ~0x7fUL) != avpn)) {
> - hpte[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hpte, pte);
> return H_NOT_FOUND;
> }
>
> @@ -700,7 +694,7 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags,
> }
> hpte[1] = cpu_to_be64(r);
> eieio();
> - hpte[0] = cpu_to_be64(v & ~HPTE_V_HVLOCK);
> + __unlock_hpte(hpte, v);
> asm volatile("ptesync" : : : "memory");
> return H_SUCCESS;
> }
> @@ -841,8 +835,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v,
> /* Return with the HPTE still locked */
> return (hash << 3) + (i >> 1);
>
> - /* Unlock and move on */
> - hpte[i] = cpu_to_be64(v);
> + __unlock_hpte(&hpte[i], v);
> }
>
> if (val & HPTE_V_SECONDARY)
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the Linuxppc-dev
mailing list