mirror of
https://github.com/torvalds/linux
synced 2024-10-08 12:22:38 +00:00
KVM: PPC: Book3S HV P9: Avoid SPR scoreboard stalls
Avoid interleaving mfSPR and mtSPR to reduce SPR scoreboard stalls. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20211123095231.1036501-26-npiggin@gmail.com
This commit is contained in:
parent
cb2553a093
commit
9a1e530bbb
|
@ -4321,10 +4321,6 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit,
|
|||
|
||||
store_spr_state(vcpu);
|
||||
|
||||
timer_rearm_host_dec(*tb);
|
||||
|
||||
restore_p9_host_os_sprs(vcpu, &host_os_sprs);
|
||||
|
||||
store_fp_state(&vcpu->arch.fp);
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
store_vr_state(&vcpu->arch.vr);
|
||||
|
@ -4339,6 +4335,10 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit,
|
|||
|
||||
switch_pmu_to_host(vcpu, &host_os_sprs);
|
||||
|
||||
timer_rearm_host_dec(*tb);
|
||||
|
||||
restore_p9_host_os_sprs(vcpu, &host_os_sprs);
|
||||
|
||||
vc->entry_exit_map = 0x101;
|
||||
vc->in_guest = 0;
|
||||
|
||||
|
|
|
@ -228,6 +228,9 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
|
|||
host_dawrx1 = mfspr(SPRN_DAWRX1);
|
||||
}
|
||||
|
||||
local_paca->kvm_hstate.host_purr = mfspr(SPRN_PURR);
|
||||
local_paca->kvm_hstate.host_spurr = mfspr(SPRN_SPURR);
|
||||
|
||||
if (vc->tb_offset) {
|
||||
u64 new_tb = *tb + vc->tb_offset;
|
||||
mtspr(SPRN_TBU40, new_tb);
|
||||
|
@ -244,8 +247,6 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
|
|||
mtspr(SPRN_DPDES, vc->dpdes);
|
||||
mtspr(SPRN_VTB, vc->vtb);
|
||||
|
||||
local_paca->kvm_hstate.host_purr = mfspr(SPRN_PURR);
|
||||
local_paca->kvm_hstate.host_spurr = mfspr(SPRN_SPURR);
|
||||
mtspr(SPRN_PURR, vcpu->arch.purr);
|
||||
mtspr(SPRN_SPURR, vcpu->arch.spurr);
|
||||
|
||||
|
@ -448,10 +449,8 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
|
|||
/* Advance host PURR/SPURR by the amount used by guest */
|
||||
purr = mfspr(SPRN_PURR);
|
||||
spurr = mfspr(SPRN_SPURR);
|
||||
mtspr(SPRN_PURR, local_paca->kvm_hstate.host_purr +
|
||||
purr - vcpu->arch.purr);
|
||||
mtspr(SPRN_SPURR, local_paca->kvm_hstate.host_spurr +
|
||||
spurr - vcpu->arch.spurr);
|
||||
local_paca->kvm_hstate.host_purr += purr - vcpu->arch.purr;
|
||||
local_paca->kvm_hstate.host_spurr += spurr - vcpu->arch.spurr;
|
||||
vcpu->arch.purr = purr;
|
||||
vcpu->arch.spurr = spurr;
|
||||
|
||||
|
@ -464,6 +463,9 @@ 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);
|
||||
vc->vtb = mfspr(SPRN_VTB);
|
||||
|
||||
dec = mfspr(SPRN_DEC);
|
||||
if (!(lpcr & LPCR_LD)) /* Sign extend if not using large decrementer */
|
||||
dec = (s32) dec;
|
||||
|
@ -481,6 +483,9 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
|
|||
vc->tb_offset_applied = 0;
|
||||
}
|
||||
|
||||
mtspr(SPRN_PURR, local_paca->kvm_hstate.host_purr);
|
||||
mtspr(SPRN_SPURR, local_paca->kvm_hstate.host_spurr);
|
||||
|
||||
/* Preserve PSSCR[FAKE_SUSPEND] until we've called kvmppc_save_tm_hv */
|
||||
mtspr(SPRN_PSSCR, host_psscr |
|
||||
(local_paca->kvm_hstate.fake_suspend << PSSCR_FAKE_SUSPEND_LG));
|
||||
|
@ -509,8 +514,6 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
|
|||
if (cpu_has_feature(CPU_FTR_ARCH_31))
|
||||
asm volatile(PPC_CP_ABORT);
|
||||
|
||||
vc->dpdes = mfspr(SPRN_DPDES);
|
||||
vc->vtb = mfspr(SPRN_VTB);
|
||||
mtspr(SPRN_DPDES, 0);
|
||||
if (vc->pcr)
|
||||
mtspr(SPRN_PCR, PCR_MASK);
|
||||
|
|
Loading…
Reference in a new issue