The P9 path uses vc->dpdes only for msgsndp / SMT emulation. This adds
an ordering requirement between vcpu->doorbell_request and vc->dpdes for
no real benefit. Use vcpu->doorbell_request directly.

XXX: verify msgsndp / DPDES emulation works properly.

Signed-off-by: Nicholas Piggin <npig...@gmail.com>
---
 arch/powerpc/kvm/book3s_hv.c          | 18 ++++++++++--------
 arch/powerpc/kvm/book3s_hv_builtin.c  |  2 ++
 arch/powerpc/kvm/book3s_hv_p9_entry.c | 14 ++++++++++----
 3 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 93ecbc040529..957efde59014 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -766,6 +766,8 @@ static bool kvmppc_doorbell_pending(struct kvm_vcpu *vcpu)
 
        if (vcpu->arch.doorbell_request)
                return true;
+       if (cpu_has_feature(CPU_FTR_ARCH_300))
+               return false;
        /*
         * Ensure that the read of vcore->dpdes comes after the read
         * of vcpu->doorbell_request.  This barrier matches the
@@ -2165,8 +2167,10 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, 
u64 id,
                 * either vcore->dpdes or doorbell_request.
                 * On POWER8, doorbell_request is 0.
                 */
-               *val = get_reg_val(id, vcpu->arch.vcore->dpdes |
-                                  vcpu->arch.doorbell_request);
+               if (cpu_has_feature(CPU_FTR_ARCH_300))
+                       *val = get_reg_val(id, vcpu->arch.doorbell_request);
+               else
+                       *val = get_reg_val(id, vcpu->arch.vcore->dpdes);
                break;
        case KVM_REG_PPC_VTB:
                *val = get_reg_val(id, vcpu->arch.vcore->vtb);
@@ -2403,7 +2407,10 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, 
u64 id,
                vcpu->arch.pspb = set_reg_val(id, *val);
                break;
        case KVM_REG_PPC_DPDES:
-               vcpu->arch.vcore->dpdes = set_reg_val(id, *val);
+               if (cpu_has_feature(CPU_FTR_ARCH_300))
+                       vcpu->arch.doorbell_request = set_reg_val(id, *val) & 1;
+               else
+                       vcpu->arch.vcore->dpdes = set_reg_val(id, *val);
                break;
        case KVM_REG_PPC_VTB:
                vcpu->arch.vcore->vtb = set_reg_val(id, *val);
@@ -4431,11 +4438,6 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 
time_limit,
 
        if (!nested) {
                kvmppc_core_prepare_to_enter(vcpu);
-               if (vcpu->arch.doorbell_request) {
-                       vc->dpdes = 1;
-                       smp_wmb();
-                       vcpu->arch.doorbell_request = 0;
-               }
                if (test_bit(BOOK3S_IRQPRIO_EXTERNAL,
                             &vcpu->arch.pending_exceptions))
                        lpcr |= LPCR_MER;
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c 
b/arch/powerpc/kvm/book3s_hv_builtin.c
index be8ef1c5b1bf..9d24f4472b42 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -649,6 +649,8 @@ void kvmppc_guest_entry_inject_int(struct kvm_vcpu *vcpu)
        int ext;
        unsigned long lpcr;
 
+       WARN_ON_ONCE(cpu_has_feature(CPU_FTR_ARCH_300));
+
        /* Insert EXTERNAL bit into LPCR at the MER bit position */
        ext = (vcpu->arch.pending_exceptions >> BOOK3S_IRQPRIO_EXTERNAL) & 1;
        lpcr = mfspr(SPRN_LPCR);
diff --git a/arch/powerpc/kvm/book3s_hv_p9_entry.c 
b/arch/powerpc/kvm/book3s_hv_p9_entry.c
index 82dac23cc678..44150a29f6e0 100644
--- a/arch/powerpc/kvm/book3s_hv_p9_entry.c
+++ b/arch/powerpc/kvm/book3s_hv_p9_entry.c
@@ -677,6 +677,7 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
        unsigned long host_pidr;
        unsigned long host_dawr1;
        unsigned long host_dawrx1;
+       unsigned long dpdes;
 
        hdec = time_limit - *tb;
        if (hdec < 0)
@@ -736,8 +737,10 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
 
        if (vc->pcr)
                mtspr(SPRN_PCR, vc->pcr | PCR_MASK);
-       if (vc->dpdes)
-               mtspr(SPRN_DPDES, vc->dpdes);
+       if (vcpu->arch.doorbell_request) {
+               vcpu->arch.doorbell_request = 0;
+               mtspr(SPRN_DPDES, 1);
+       }
 
        if (dawr_enabled()) {
                if (vcpu->arch.dawr0 != host_dawr0)
@@ -968,7 +971,10 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
        vcpu->arch.shregs.sprg2 = mfspr(SPRN_SPRG2);
        vcpu->arch.shregs.sprg3 = mfspr(SPRN_SPRG3);
 
-       vc->dpdes = mfspr(SPRN_DPDES);
+       dpdes = mfspr(SPRN_DPDES);
+       if (dpdes)
+               vcpu->arch.doorbell_request = 1;
+
        vc->vtb = mfspr(SPRN_VTB);
 
        dec = mfspr(SPRN_DEC);
@@ -1030,7 +1036,7 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 
time_limit, unsigned long lpc
                }
        }
 
-       if (vc->dpdes)
+       if (dpdes)
                mtspr(SPRN_DPDES, 0);
        if (vc->pcr)
                mtspr(SPRN_PCR, PCR_MASK);
-- 
2.23.0

Reply via email to