Re: [PATCH v1 30/55] KVM: PPC: Book3S HV P9: Only execute mtSPR if the value changed

Fabiano Rosas <[email protected]>
Newsgroups org.kernel.vger.kvm-ppc,org.ozlabs.lists.linuxppc-dev
Message-ID <[email protected]>
Nicholas Piggin <[email protected]> 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 <[email protected]>

Reviewed-by: Fabiano Rosas <[email protected]>

> ---
>  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()) {
>  		/*
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.