Message ID | 20210726035036.739609-31-npiggin@gmail.com |
---|---|
State | New |
Headers | show |
Series | [v1,01/55] KVM: PPC: Book3S HV: Remove TM emulation from POWER7/8 path | expand |
Nicholas Piggin <npiggin@gmail.com> writes: > Keep better track of the current SPR value in places where > they are to be loaded with a new context, to reduce expensive > mtSPR operations. > > -73 cycles (7354) POWER9 virt-mode NULL hcall > > Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com> > --- > arch/powerpc/kvm/book3s_hv.c | 64 ++++++++++++++++++++++-------------- > 1 file changed, 39 insertions(+), 25 deletions(-) > > diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c > index 0d97138e6fa4..56429b53f4dc 100644 > --- a/arch/powerpc/kvm/book3s_hv.c > +++ b/arch/powerpc/kvm/book3s_hv.c > @@ -4009,19 +4009,28 @@ static void switch_pmu_to_host(struct kvm_vcpu *vcpu, > } > } > > -static void load_spr_state(struct kvm_vcpu *vcpu) > +static void load_spr_state(struct kvm_vcpu *vcpu, > + struct p9_host_os_sprs *host_os_sprs) > { > - mtspr(SPRN_DSCR, vcpu->arch.dscr); > - mtspr(SPRN_IAMR, vcpu->arch.iamr); > - mtspr(SPRN_PSPB, vcpu->arch.pspb); > - mtspr(SPRN_FSCR, vcpu->arch.fscr); > mtspr(SPRN_TAR, vcpu->arch.tar); > mtspr(SPRN_EBBHR, vcpu->arch.ebbhr); > mtspr(SPRN_EBBRR, vcpu->arch.ebbrr); > mtspr(SPRN_BESCR, vcpu->arch.bescr); > - mtspr(SPRN_TIDR, vcpu->arch.tid); > - mtspr(SPRN_AMR, vcpu->arch.amr); > - mtspr(SPRN_UAMOR, vcpu->arch.uamor); > + > + if (!cpu_has_feature(CPU_FTR_ARCH_31)) > + mtspr(SPRN_TIDR, vcpu->arch.tid); > + if (host_os_sprs->iamr != vcpu->arch.iamr) > + mtspr(SPRN_IAMR, vcpu->arch.iamr); > + if (host_os_sprs->amr != vcpu->arch.amr) > + mtspr(SPRN_AMR, vcpu->arch.amr); > + if (vcpu->arch.uamor != 0) > + mtspr(SPRN_UAMOR, vcpu->arch.uamor); > + if (host_os_sprs->fscr != vcpu->arch.fscr) > + mtspr(SPRN_FSCR, vcpu->arch.fscr); > + if (host_os_sprs->dscr != vcpu->arch.dscr) > + mtspr(SPRN_DSCR, vcpu->arch.dscr); > + if (vcpu->arch.pspb != 0) > + mtspr(SPRN_PSPB, vcpu->arch.pspb); > > /* > * DAR, DSISR, and for nested HV, SPRGs must be set with MSR[RI] > @@ -4036,28 +4045,31 @@ static void load_spr_state(struct kvm_vcpu *vcpu) > > static void store_spr_state(struct kvm_vcpu *vcpu) > { > - vcpu->arch.ctrl = mfspr(SPRN_CTRLF); > - > - vcpu->arch.iamr = mfspr(SPRN_IAMR); > - vcpu->arch.pspb = mfspr(SPRN_PSPB); > - vcpu->arch.fscr = mfspr(SPRN_FSCR); > vcpu->arch.tar = mfspr(SPRN_TAR); > vcpu->arch.ebbhr = mfspr(SPRN_EBBHR); > vcpu->arch.ebbrr = mfspr(SPRN_EBBRR); > vcpu->arch.bescr = mfspr(SPRN_BESCR); > - vcpu->arch.tid = mfspr(SPRN_TIDR); > + > + if (!cpu_has_feature(CPU_FTR_ARCH_31)) > + vcpu->arch.tid = mfspr(SPRN_TIDR); > + vcpu->arch.iamr = mfspr(SPRN_IAMR); > vcpu->arch.amr = mfspr(SPRN_AMR); > vcpu->arch.uamor = mfspr(SPRN_UAMOR); > + vcpu->arch.fscr = mfspr(SPRN_FSCR); > vcpu->arch.dscr = mfspr(SPRN_DSCR); > + vcpu->arch.pspb = mfspr(SPRN_PSPB); > + > + vcpu->arch.ctrl = mfspr(SPRN_CTRLF); > } > > static void save_p9_host_os_sprs(struct p9_host_os_sprs *host_os_sprs) > { > - host_os_sprs->dscr = mfspr(SPRN_DSCR); > - host_os_sprs->tidr = mfspr(SPRN_TIDR); > + if (!cpu_has_feature(CPU_FTR_ARCH_31)) > + host_os_sprs->tidr = mfspr(SPRN_TIDR); > host_os_sprs->iamr = mfspr(SPRN_IAMR); > host_os_sprs->amr = mfspr(SPRN_AMR); > host_os_sprs->fscr = mfspr(SPRN_FSCR); > + host_os_sprs->dscr = mfspr(SPRN_DSCR); > } > > /* vcpu guest regs must already be saved */ > @@ -4066,18 +4078,20 @@ static void restore_p9_host_os_sprs(struct kvm_vcpu *vcpu, > { > mtspr(SPRN_SPRG_VDSO_WRITE, local_paca->sprg_vdso); > > - mtspr(SPRN_PSPB, 0); > - mtspr(SPRN_UAMOR, 0); > - > - mtspr(SPRN_DSCR, host_os_sprs->dscr); > - mtspr(SPRN_TIDR, host_os_sprs->tidr); > - mtspr(SPRN_IAMR, host_os_sprs->iamr); > - > + if (!cpu_has_feature(CPU_FTR_ARCH_31)) > + mtspr(SPRN_TIDR, host_os_sprs->tidr); > + if (host_os_sprs->iamr != vcpu->arch.iamr) > + mtspr(SPRN_IAMR, host_os_sprs->iamr); > + if (vcpu->arch.uamor != 0) > + mtspr(SPRN_UAMOR, 0); > if (host_os_sprs->amr != vcpu->arch.amr) > mtspr(SPRN_AMR, host_os_sprs->amr); > - > if (host_os_sprs->fscr != vcpu->arch.fscr) > mtspr(SPRN_FSCR, host_os_sprs->fscr); > + if (host_os_sprs->dscr != vcpu->arch.dscr) > + mtspr(SPRN_DSCR, host_os_sprs->dscr); > + if (vcpu->arch.pspb != 0) > + mtspr(SPRN_PSPB, 0); > > /* Save guest CTRL register, set runlatch to 1 */ > if (!(vcpu->arch.ctrl & 1)) > @@ -4169,7 +4183,7 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, > #endif > mtspr(SPRN_VRSAVE, vcpu->arch.vrsave); > > - load_spr_state(vcpu); > + load_spr_state(vcpu, &host_os_sprs); > > if (kvmhv_on_pseries()) { > /*
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 0d97138e6fa4..56429b53f4dc 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -4009,19 +4009,28 @@ static void switch_pmu_to_host(struct kvm_vcpu *vcpu, } } -static void load_spr_state(struct kvm_vcpu *vcpu) +static void load_spr_state(struct kvm_vcpu *vcpu, + struct p9_host_os_sprs *host_os_sprs) { - mtspr(SPRN_DSCR, vcpu->arch.dscr); - mtspr(SPRN_IAMR, vcpu->arch.iamr); - mtspr(SPRN_PSPB, vcpu->arch.pspb); - mtspr(SPRN_FSCR, vcpu->arch.fscr); mtspr(SPRN_TAR, vcpu->arch.tar); mtspr(SPRN_EBBHR, vcpu->arch.ebbhr); mtspr(SPRN_EBBRR, vcpu->arch.ebbrr); mtspr(SPRN_BESCR, vcpu->arch.bescr); - mtspr(SPRN_TIDR, vcpu->arch.tid); - mtspr(SPRN_AMR, vcpu->arch.amr); - mtspr(SPRN_UAMOR, vcpu->arch.uamor); + + if (!cpu_has_feature(CPU_FTR_ARCH_31)) + mtspr(SPRN_TIDR, vcpu->arch.tid); + if (host_os_sprs->iamr != vcpu->arch.iamr) + mtspr(SPRN_IAMR, vcpu->arch.iamr); + if (host_os_sprs->amr != vcpu->arch.amr) + mtspr(SPRN_AMR, vcpu->arch.amr); + if (vcpu->arch.uamor != 0) + mtspr(SPRN_UAMOR, vcpu->arch.uamor); + if (host_os_sprs->fscr != vcpu->arch.fscr) + mtspr(SPRN_FSCR, vcpu->arch.fscr); + if (host_os_sprs->dscr != vcpu->arch.dscr) + mtspr(SPRN_DSCR, vcpu->arch.dscr); + if (vcpu->arch.pspb != 0) + mtspr(SPRN_PSPB, vcpu->arch.pspb); /* * DAR, DSISR, and for nested HV, SPRGs must be set with MSR[RI] @@ -4036,28 +4045,31 @@ static void load_spr_state(struct kvm_vcpu *vcpu) static void store_spr_state(struct kvm_vcpu *vcpu) { - vcpu->arch.ctrl = mfspr(SPRN_CTRLF); - - vcpu->arch.iamr = mfspr(SPRN_IAMR); - vcpu->arch.pspb = mfspr(SPRN_PSPB); - vcpu->arch.fscr = mfspr(SPRN_FSCR); vcpu->arch.tar = mfspr(SPRN_TAR); vcpu->arch.ebbhr = mfspr(SPRN_EBBHR); vcpu->arch.ebbrr = mfspr(SPRN_EBBRR); vcpu->arch.bescr = mfspr(SPRN_BESCR); - vcpu->arch.tid = mfspr(SPRN_TIDR); + + if (!cpu_has_feature(CPU_FTR_ARCH_31)) + vcpu->arch.tid = mfspr(SPRN_TIDR); + vcpu->arch.iamr = mfspr(SPRN_IAMR); vcpu->arch.amr = mfspr(SPRN_AMR); vcpu->arch.uamor = mfspr(SPRN_UAMOR); + vcpu->arch.fscr = mfspr(SPRN_FSCR); vcpu->arch.dscr = mfspr(SPRN_DSCR); + vcpu->arch.pspb = mfspr(SPRN_PSPB); + + vcpu->arch.ctrl = mfspr(SPRN_CTRLF); } static void save_p9_host_os_sprs(struct p9_host_os_sprs *host_os_sprs) { - host_os_sprs->dscr = mfspr(SPRN_DSCR); - host_os_sprs->tidr = mfspr(SPRN_TIDR); + if (!cpu_has_feature(CPU_FTR_ARCH_31)) + host_os_sprs->tidr = mfspr(SPRN_TIDR); host_os_sprs->iamr = mfspr(SPRN_IAMR); host_os_sprs->amr = mfspr(SPRN_AMR); host_os_sprs->fscr = mfspr(SPRN_FSCR); + host_os_sprs->dscr = mfspr(SPRN_DSCR); } /* vcpu guest regs must already be saved */ @@ -4066,18 +4078,20 @@ static void restore_p9_host_os_sprs(struct kvm_vcpu *vcpu, { mtspr(SPRN_SPRG_VDSO_WRITE, local_paca->sprg_vdso); - mtspr(SPRN_PSPB, 0); - mtspr(SPRN_UAMOR, 0); - - mtspr(SPRN_DSCR, host_os_sprs->dscr); - mtspr(SPRN_TIDR, host_os_sprs->tidr); - mtspr(SPRN_IAMR, host_os_sprs->iamr); - + if (!cpu_has_feature(CPU_FTR_ARCH_31)) + mtspr(SPRN_TIDR, host_os_sprs->tidr); + if (host_os_sprs->iamr != vcpu->arch.iamr) + mtspr(SPRN_IAMR, host_os_sprs->iamr); + if (vcpu->arch.uamor != 0) + mtspr(SPRN_UAMOR, 0); if (host_os_sprs->amr != vcpu->arch.amr) mtspr(SPRN_AMR, host_os_sprs->amr); - if (host_os_sprs->fscr != vcpu->arch.fscr) mtspr(SPRN_FSCR, host_os_sprs->fscr); + if (host_os_sprs->dscr != vcpu->arch.dscr) + mtspr(SPRN_DSCR, host_os_sprs->dscr); + if (vcpu->arch.pspb != 0) + mtspr(SPRN_PSPB, 0); /* Save guest CTRL register, set runlatch to 1 */ if (!(vcpu->arch.ctrl & 1)) @@ -4169,7 +4183,7 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, #endif mtspr(SPRN_VRSAVE, vcpu->arch.vrsave); - load_spr_state(vcpu); + load_spr_state(vcpu, &host_os_sprs); if (kvmhv_on_pseries()) { /*
Keep better track of the current SPR value in places where they are to be loaded with a new context, to reduce expensive mtSPR operations. -73 cycles (7354) POWER9 virt-mode NULL hcall Signed-off-by: Nicholas Piggin <npiggin@gmail.com> --- arch/powerpc/kvm/book3s_hv.c | 64 ++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 25 deletions(-)