kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrea Arcangeli <aarcange@redhat.com>
To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Vitaly Kuznetsov <vkuznets@redhat.com>,
	Sean Christopherson <sean.j.christopherson@intel.com>
Subject: [PATCH 12/14] KVM: retpolines: x86: eliminate retpoline from vmx.c exit handlers
Date: Sat, 28 Sep 2019 13:23:21 -0400	[thread overview]
Message-ID: <20190928172323.14663-13-aarcange@redhat.com> (raw)
In-Reply-To: <20190928172323.14663-1-aarcange@redhat.com>

It's enough to check the exit value and issue a direct call to avoid
the retpoline for all the common vmexit reasons.

Reducing this list to only EXIT_REASON_MSR_WRITE,
EXIT_REASON_PREEMPTION_TIMER, EXIT_REASON_EPT_MISCONFIG,
EXIT_REASON_IO_INSTRUCTION increases the computation time of the
hrtimer guest testcase on Haswell i5-4670T CPU @ 2.30GHz by 7% with
the default spectre v2 mitigation enabled in the host and guest. On
skylake as opposed there's no measurable difference with the short
list. To put things in prospective on Haswell the same hrtimer
workload (note: it never calls cpuid and it never attempts to trigger
more vmexit on purpose) in guest takes 16.3% longer to compute on
upstream KVM running in the host than with the KVM mono v1 patchset
applied to the host kernel, while on skylake the same takes only 5.4%
more time (both with the default mitigations enabled in guest and
host).

It's also unclear why EXIT_REASON_IO_INSTRUCTION should be included.

Of course CONFIG_RETPOLINE already forbids gcc not to do indirect
jumps while compiling all switch() statements, however switch() would
still allow the compiler to bisect the value, however it seems to run
slower if something and the reason is that it's better to prioritize
and do the minimal possible number of checks for the most common vmexit.

The halt and pause loop exiting may be slow paths from the point of
the guest, but not necessarily so from the point of the host. There
can be a flood of halt exit reasons (in fact that's why the cpuidle
guest haltpoll support was recently merged and we can't rely on it
here because there are older kernels and other OS that must also
perform optimally). All it takes is a pipe ping pong with a different
host CPU and the host CPUs running at full capacity.

The same consideration applies to the pause loop exiting exit reason,
if there's heavy host overcommit that collides heavily in a spinlock
the same may happen.

In the common case of a fully idle host, the halt and pause loop
exiting can't help, but adding them doesn't hurt the common case and
the expectation here is that if they would ever become measurable, it
would be because they are increasing (and not decreasing) performance.

Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
---
 arch/x86/kvm/vmx/vmx.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index de3ae2246205..2bd57a7d2be1 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -5846,9 +5846,29 @@ int kvm_x86_handle_exit(struct kvm_vcpu *vcpu)
 	}
 
 	if (exit_reason < kvm_vmx_max_exit_handlers
-	    && kvm_vmx_exit_handlers[exit_reason])
+	    && kvm_vmx_exit_handlers[exit_reason]) {
+#ifdef CONFIG_RETPOLINE
+		if (exit_reason == EXIT_REASON_MSR_WRITE)
+			return kvm_emulate_wrmsr(vcpu);
+		else if (exit_reason == EXIT_REASON_PREEMPTION_TIMER)
+			return handle_preemption_timer(vcpu);
+		else if (exit_reason == EXIT_REASON_PENDING_INTERRUPT)
+			return handle_interrupt_window(vcpu);
+		else if (exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT)
+			return handle_external_interrupt(vcpu);
+		else if (exit_reason == EXIT_REASON_HLT)
+			return kvm_emulate_halt(vcpu);
+		else if (exit_reason == EXIT_REASON_PAUSE_INSTRUCTION)
+			return handle_pause(vcpu);
+		else if (exit_reason == EXIT_REASON_MSR_READ)
+			return kvm_emulate_rdmsr(vcpu);
+		else if (exit_reason == EXIT_REASON_CPUID)
+			return kvm_emulate_cpuid(vcpu);
+		else if (exit_reason == EXIT_REASON_EPT_MISCONFIG)
+			return handle_ept_misconfig(vcpu);
+#endif
 		return kvm_vmx_exit_handlers[exit_reason](vcpu);
-	else {
+	} else {
 		vcpu_unimpl(vcpu, "vmx: unexpected exit reason 0x%x\n",
 				exit_reason);
 		dump_vmcs();

  parent reply	other threads:[~2019-09-28 17:23 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-28 17:23 [PATCH 00/14] KVM monolithic v2 Andrea Arcangeli
2019-09-28 17:23 ` [PATCH 01/14] KVM: monolithic: x86: remove kvm.ko Andrea Arcangeli
2019-10-15  1:31   ` Sean Christopherson
2019-10-15  3:18     ` Sean Christopherson
2019-10-15  8:32       ` Paolo Bonzini
2019-09-28 17:23 ` [PATCH 02/14] KVM: monolithic: x86: disable linking vmx and svm at the same time into the kernel Andrea Arcangeli
2019-10-15  3:16   ` Sean Christopherson
2019-10-15  8:21     ` Paolo Bonzini
2019-10-15 15:23       ` Sean Christopherson
2019-09-28 17:23 ` [PATCH 04/14] KVM: monolithic: x86: handle the request_immediate_exit variation Andrea Arcangeli
2019-09-28 17:23 ` [PATCH 05/14] KVM: monolithic: add more section prefixes in the KVM common code Andrea Arcangeli
2019-09-28 17:23 ` [PATCH 06/14] KVM: monolithic: x86: remove __exit section prefix from machine_unsetup Andrea Arcangeli
2019-09-28 17:23 ` [PATCH 07/14] KVM: monolithic: x86: remove __init section prefix from kvm_x86_cpu_has_kvm_support Andrea Arcangeli
2019-09-28 17:23 ` [PATCH 08/14] KVM: monolithic: x86: remove exports Andrea Arcangeli
2019-09-28 17:23 ` [PATCH 09/14] KVM: monolithic: remove exports from KVM common code Andrea Arcangeli
2019-09-28 17:23 ` [PATCH 10/14] KVM: monolithic: x86: drop the kvm_pmu_ops structure Andrea Arcangeli
2019-09-28 17:23 ` [PATCH 11/14] KVM: x86: optimize more exit handlers in vmx.c Andrea Arcangeli
2019-09-28 17:23 ` Andrea Arcangeli [this message]
2019-10-15  8:28   ` [PATCH 12/14] KVM: retpolines: x86: eliminate retpoline from vmx.c exit handlers Paolo Bonzini
2019-10-15 16:49     ` Andrea Arcangeli
2019-10-15 19:46       ` Paolo Bonzini
2019-10-15 20:35         ` Andrea Arcangeli
2019-10-15 22:22           ` Paolo Bonzini
2019-10-15 23:42             ` Andrea Arcangeli
2019-10-16  7:07               ` Paolo Bonzini
2019-10-16 16:50                 ` Andrea Arcangeli
2019-10-16 17:01                   ` Paolo Bonzini
2019-09-28 17:23 ` [PATCH 13/14] KVM: retpolines: x86: eliminate retpoline from svm.c " Andrea Arcangeli
2019-09-28 17:23 ` [PATCH 14/14] x86: retpolines: eliminate retpoline from msr event handlers Andrea Arcangeli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190928172323.14663-13-aarcange@redhat.com \
    --to=aarcange@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=sean.j.christopherson@intel.com \
    --cc=vkuznets@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).