Commit a089a686 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

KVM: PPC: Book3S HV P9: Don't restore PSSCR if not needed



This also moves the PSSCR update in nested entry to avoid a SPR
scoreboard stall.

Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20211123095231.1036501-42-npiggin@gmail.com
parent 9c75f65f
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -3889,7 +3889,9 @@ static int kvmhv_vcpu_entry_p9_nested(struct kvm_vcpu *vcpu, u64 time_limit, uns
	if (unlikely(load_vcpu_state(vcpu, &host_os_sprs)))
		msr = mfmsr(); /* TM restore can update msr */

	if (vcpu->arch.psscr != host_psscr)
		mtspr(SPRN_PSSCR_PR, vcpu->arch.psscr);

	kvmhv_save_hv_regs(vcpu, &hvregs);
	hvregs.lpcr = lpcr;
	vcpu->arch.regs.msr = vcpu->arch.shregs.msr;
@@ -3930,7 +3932,6 @@ static int kvmhv_vcpu_entry_p9_nested(struct kvm_vcpu *vcpu, u64 time_limit, uns
	vcpu->arch.shregs.dar = mfspr(SPRN_DAR);
	vcpu->arch.shregs.dsisr = mfspr(SPRN_DSISR);
	vcpu->arch.psscr = mfspr(SPRN_PSSCR_PR);
	mtspr(SPRN_PSSCR_PR, host_psscr);

	store_vcpu_state(vcpu);

@@ -3943,6 +3944,8 @@ static int kvmhv_vcpu_entry_p9_nested(struct kvm_vcpu *vcpu, u64 time_limit, uns
	timer_rearm_host_dec(*tb);

	restore_p9_host_os_sprs(vcpu, &host_os_sprs);
	if (vcpu->arch.psscr != host_psscr)
		mtspr(SPRN_PSSCR_PR, host_psscr);

	return trap;
}
+19 −7
Original line number Diff line number Diff line
@@ -649,6 +649,7 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
	unsigned long host_dawr0;
	unsigned long host_dawrx0;
	unsigned long host_psscr;
	unsigned long host_hpsscr;
	unsigned long host_pidr;
	unsigned long host_dawr1;
	unsigned long host_dawrx1;
@@ -666,7 +667,9 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc

	host_hfscr = mfspr(SPRN_HFSCR);
	host_ciabr = mfspr(SPRN_CIABR);
	host_psscr = mfspr(SPRN_PSSCR);
	host_psscr = mfspr(SPRN_PSSCR_PR);
	if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST))
		host_hpsscr = mfspr(SPRN_PSSCR);
	host_pidr = mfspr(SPRN_PID);

	if (dawr_enabled()) {
@@ -750,8 +753,14 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
	if (vcpu->arch.ciabr != host_ciabr)
		mtspr(SPRN_CIABR, vcpu->arch.ciabr);


	if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST)) {
		mtspr(SPRN_PSSCR, vcpu->arch.psscr | PSSCR_EC |
		      (local_paca->kvm_hstate.fake_suspend << PSSCR_FAKE_SUSPEND_LG));
	} else {
		if (vcpu->arch.psscr != host_psscr)
			mtspr(SPRN_PSSCR_PR, vcpu->arch.psscr);
	}

	mtspr(SPRN_HFSCR, vcpu->arch.hfscr);

@@ -957,7 +966,7 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc

	vcpu->arch.ic = mfspr(SPRN_IC);
	vcpu->arch.pid = mfspr(SPRN_PID);
	vcpu->arch.psscr = mfspr(SPRN_PSSCR) & PSSCR_GUEST_VIS;
	vcpu->arch.psscr = mfspr(SPRN_PSSCR_PR);

	vcpu->arch.shregs.sprg0 = mfspr(SPRN_SPRG0);
	vcpu->arch.shregs.sprg1 = mfspr(SPRN_SPRG1);
@@ -1003,9 +1012,12 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
	mtspr(SPRN_PURR, local_paca->kvm_hstate.host_purr);
	mtspr(SPRN_SPURR, local_paca->kvm_hstate.host_spurr);

	if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST)) {
		/* Preserve PSSCR[FAKE_SUSPEND] until we've called kvmppc_save_tm_hv */
	mtspr(SPRN_PSSCR, host_psscr |
		mtspr(SPRN_PSSCR, host_hpsscr |
		      (local_paca->kvm_hstate.fake_suspend << PSSCR_FAKE_SUSPEND_LG));
	}

	mtspr(SPRN_HFSCR, host_hfscr);
	if (vcpu->arch.ciabr != host_ciabr)
		mtspr(SPRN_CIABR, host_ciabr);