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

KVM: PPC: Book3S HV P9: Improve mtmsrd scheduling by delaying MSR[EE] disable



Moving the mtmsrd after the host SPRs are saved and before the guest
SPRs start to be loaded can prevent an SPR scoreboard stall (because
the mtmsrd is L=1 type which does not cause context synchronisation.

This is also now more convenient to combined with the mtmsrd L=0
instruction to enable facilities just below, but that is not done yet.

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-21-npiggin@gmail.com
parent 34e119c9
Loading
Loading
Loading
Loading
+18 −5
Original line number Diff line number Diff line
@@ -4169,6 +4169,18 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit,

	save_p9_host_os_sprs(&host_os_sprs);

	/*
	 * This could be combined with MSR[RI] clearing, but that expands
	 * the unrecoverable window. It would be better to cover unrecoverable
	 * with KVM bad interrupt handling rather than use MSR[RI] at all.
	 *
	 * Much more difficult and less worthwhile to combine with IR/DR
	 * disable.
	 */
	hard_irq_disable();
	if (lazy_irq_pending())
		return 0;

	/* MSR bits may have been cleared by context switch */
	msr = 0;
	if (IS_ENABLED(CONFIG_PPC_FPU))
@@ -4680,6 +4692,7 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
	struct kvmppc_vcore *vc;
	struct kvm *kvm = vcpu->kvm;
	struct kvm_nested_guest *nested = vcpu->arch.nested;
	unsigned long flags;

	trace_kvmppc_run_vcpu_enter(vcpu);

@@ -4723,11 +4736,11 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
	if (kvm_is_radix(kvm))
		kvmppc_prepare_radix_vcpu(vcpu, pcpu);

	local_irq_disable();
	hard_irq_disable();
	/* flags save not required, but irq_pmu has no disable/enable API */
	powerpc_local_irq_pmu_save(flags);
	if (signal_pending(current))
		goto sigpend;
	if (lazy_irq_pending() || need_resched() || !kvm->arch.mmu_ready)
	if (need_resched() || !kvm->arch.mmu_ready)
		goto out;

	if (!nested) {
@@ -4795,7 +4808,7 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
	}
	vtime_account_guest_exit();

	local_irq_enable();
	powerpc_local_irq_pmu_restore(flags);

	cpumask_clear_cpu(pcpu, &kvm->arch.cpu_in_guest);

@@ -4853,7 +4866,7 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
	run->exit_reason = KVM_EXIT_INTR;
	vcpu->arch.ret = -EINTR;
 out:
	local_irq_enable();
	powerpc_local_irq_pmu_restore(flags);
	preempt_enable();
	goto done;
}