From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: Alexander Graf <graf@amazon.com>,
Vitaly Kuznetsov <vkuznets@redhat.com>,
Wanpeng Li <wanpengli@tencent.com>,
Jim Mattson <jmattson@google.com>, Joerg Roedel <joro@8bytes.org>,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
KarimAllah Raslan <karahmed@amazon.de>
Subject: Re: [PATCH v2] KVM: nVMX: Skip IBPB when switching between vmcs01 and vmcs02
Date: Mon, 4 May 2020 07:29:33 -0700 [thread overview]
Message-ID: <20200504142933.GA16949@linux.intel.com> (raw)
In-Reply-To: <9d0d09da-3920-16d6-11ae-51b864171b66@redhat.com>
On Mon, May 04, 2020 at 03:12:36PM +0200, Paolo Bonzini wrote:
> On 04/05/20 14:01, Alexander Graf wrote:
> > I like the WARN_ON :). It should be almost free during execution, but
> > helps us catch problems early.
>
> Yes, it's nice. I didn't mind the "buddy" argument either, but if we're
> going to get a bool I prefer positive logic so I'd like to squash this:
I don't love need_ibpb as a param name, it doesn't provide any information
as to why the IBPB is needed. But, I can't come up with anything better
that isn't absurdly long because e.g. "different_guest" isn't necessarily
true in the vmx_vcpu_load() path.
What about going the @buddy route and adding the comment and WARN in
vmx_vcpu_load_vmcs()? E.g.
prev = per_cpu(current_vmcs, cpu);
if (prev != vmx->loaded_vmcs->vmcs) {
per_cpu(current_vmcs, cpu) = vmx->loaded_vmcs->vmcs;
vmcs_load(vmx->loaded_vmcs->vmcs);
/*
* No indirect branch prediction barrier needed when switching
* the active VMCS within a guest, e.g. on nested VM-Enter.
* The L1 VMM can protect itself with retpolines, IBPB or IBRS.
*/
if (!buddy || WARN_ON_ONCE(buddy->vmcs != prev))
indirect_branch_prediction_barrier();
}
> diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> index b57420f3dd8f..299393750a18 100644
> --- a/arch/x86/kvm/vmx/nested.c
> +++ b/arch/x86/kvm/vmx/nested.c
> @@ -304,7 +304,13 @@ static void vmx_switch_vmcs(struct kvm_vcpu *vcpu, struct loaded_vmcs *vmcs)
> prev = vmx->loaded_vmcs;
> WARN_ON_ONCE(prev->cpu != cpu || prev->vmcs != per_cpu(current_vmcs, cpu));
> vmx->loaded_vmcs = vmcs;
> - vmx_vcpu_load_vmcs(vcpu, cpu, true);
> +
> + /*
> + * This is the same guest from our point of view, so no
> + * indirect branch prediction barrier is needed. The L1
> + * guest can protect itself with retpolines, IBPB or IBRS.
> + */
> + vmx_vcpu_load_vmcs(vcpu, cpu, false);
> vmx_sync_vmcs_host_state(vmx, prev);
> put_cpu();
>
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index 669e14947ba9..0f9c8d2dd7f6 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -1311,7 +1311,7 @@ static void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu)
> pi_set_on(pi_desc);
> }
>
> -void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu, bool nested_switch)
> +void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu, bool need_ibpb)
> {
> struct vcpu_vmx *vmx = to_vmx(vcpu);
> bool already_loaded = vmx->loaded_vmcs->cpu == cpu;
> @@ -1336,7 +1336,7 @@ void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu, bool nested_switch)
> if (per_cpu(current_vmcs, cpu) != vmx->loaded_vmcs->vmcs) {
> per_cpu(current_vmcs, cpu) = vmx->loaded_vmcs->vmcs;
> vmcs_load(vmx->loaded_vmcs->vmcs);
> - if (!nested_switch)
> + if (need_ibpb)
> indirect_branch_prediction_barrier();
> }
>
> @@ -1378,7 +1378,7 @@ void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
> {
> struct vcpu_vmx *vmx = to_vmx(vcpu);
>
> - vmx_vcpu_load_vmcs(vcpu, cpu, false);
> + vmx_vcpu_load_vmcs(vcpu, cpu, true);
>
> vmx_vcpu_pi_load(vcpu, cpu);
>
> diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
> index fa61dc802183..e584ee9b3e94 100644
> --- a/arch/x86/kvm/vmx/vmx.h
> +++ b/arch/x86/kvm/vmx/vmx.h
> @@ -320,7 +320,7 @@ struct kvm_vmx {
> };
>
> bool nested_vmx_allowed(struct kvm_vcpu *vcpu);
> -void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu, bool nested_switch);
> +void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu, bool need_ibpb);
> void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
> int allocate_vpid(void);
> void free_vpid(int vpid);
>
>
> Paolo
>
prev parent reply other threads:[~2020-05-04 14:29 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-01 16:31 [PATCH v2] KVM: nVMX: Skip IBPB when switching between vmcs01 and vmcs02 Sean Christopherson
2020-05-04 12:01 ` Alexander Graf
2020-05-04 13:12 ` Paolo Bonzini
2020-05-04 14:29 ` Sean Christopherson [this message]
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=20200504142933.GA16949@linux.intel.com \
--to=sean.j.christopherson@intel.com \
--cc=graf@amazon.com \
--cc=jmattson@google.com \
--cc=joro@8bytes.org \
--cc=karahmed@amazon.de \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=vkuznets@redhat.com \
--cc=wanpengli@tencent.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.