All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yosry Ahmed <yosry.ahmed@linux.dev>
To: Jim Mattson <jmattson@google.com>
Cc: x86@kernel.org, Sean Christopherson <seanjc@google.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	"Kaplan, David" <David.Kaplan@amd.com>,
	kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 3/3] KVM: x86: Generalize IBRS virtualization on emulated VM-exit
Date: Fri, 21 Feb 2025 18:39:05 +0000	[thread overview]
Message-ID: <Z7jISUVBeAbw8zt6@google.com> (raw)
In-Reply-To: <CALMp9eSPVDYC7v4Rm13ZUcE4wWPb8dUfm=qBx_jETAQEQrt4_w@mail.gmail.com>

On Fri, Feb 21, 2025 at 09:59:04AM -0800, Jim Mattson wrote:
> On Fri, Feb 21, 2025 at 8:34 AM Yosry Ahmed <yosry.ahmed@linux.dev> wrote:
> >
> > Commit 2e7eab81425a ("KVM: VMX: Execute IBPB on emulated VM-exit when
> > guest has IBRS") added an IBPB in the emulated VM-exit path on Intel to
> > properly virtualize IBRS by providing separate predictor modes for L1
> > and L2.
> >
> > AMD requires similar handling, except when IbrsSameMode is enumerated by
> > the host CPU (which is the case on most/all AMD CPUs). With
> > IbrsSameMode, hardware IBRS is sufficient and no extra handling is
> > needed from KVM.
> >
> > Generalize the handling in nested_vmx_vmexit() by moving it into a
> > generic function, add the AMD handling, and use it in
> > nested_svm_vmexit() too. The main reason for using a generic function is
> > to have a single place to park the huge comment about virtualizing IBRS.
> >
> > Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
> > ---
> >  arch/x86/kvm/svm/nested.c |  2 ++
> >  arch/x86/kvm/vmx/nested.c | 11 +----------
> >  arch/x86/kvm/x86.h        | 18 ++++++++++++++++++
> >  3 files changed, 21 insertions(+), 10 deletions(-)
> >
> > diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
> > index d77b094d9a4d6..61b73ff30807e 100644
> > --- a/arch/x86/kvm/svm/nested.c
> > +++ b/arch/x86/kvm/svm/nested.c
> > @@ -1041,6 +1041,8 @@ int nested_svm_vmexit(struct vcpu_svm *svm)
> >
> >         nested_svm_copy_common_state(svm->nested.vmcb02.ptr, svm->vmcb01.ptr);
> >
> > +       kvm_nested_vmexit_handle_spec_ctrl(vcpu);
> > +
> >         svm_switch_vmcb(svm, &svm->vmcb01);
> >
> >         /*
> > diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> > index 8a7af02d466e9..453d52a6e836a 100644
> > --- a/arch/x86/kvm/vmx/nested.c
> > +++ b/arch/x86/kvm/vmx/nested.c
> > @@ -5018,16 +5018,7 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason,
> >
> >         vmx_switch_vmcs(vcpu, &vmx->vmcs01);
> >
> > -       /*
> > -        * If IBRS is advertised to the vCPU, KVM must flush the indirect
> > -        * branch predictors when transitioning from L2 to L1, as L1 expects
> > -        * hardware (KVM in this case) to provide separate predictor modes.
> > -        * Bare metal isolates VMX root (host) from VMX non-root (guest), but
> > -        * doesn't isolate different VMCSs, i.e. in this case, doesn't provide
> > -        * separate modes for L2 vs L1.
> > -        */
> > -       if (guest_cpu_cap_has(vcpu, X86_FEATURE_SPEC_CTRL))
> > -               indirect_branch_prediction_barrier();
> > +       kvm_nested_vmexit_handle_spec_ctrl(vcpu);
> >
> >         /* Update any VMCS fields that might have changed while L2 ran */
> >         vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, vmx->msr_autoload.host.nr);
> > diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
> > index 7a87c5fc57f1b..008c8d381c253 100644
> > --- a/arch/x86/kvm/x86.h
> > +++ b/arch/x86/kvm/x86.h
> > @@ -116,6 +116,24 @@ static inline void kvm_leave_nested(struct kvm_vcpu *vcpu)
> >         kvm_x86_ops.nested_ops->leave_nested(vcpu);
> >  }
> >
> > +/*
> > + * If IBRS is advertised to the vCPU, KVM must flush the indirect branch
> > + * predictors when transitioning from L2 to L1, as L1 expects hardware (KVM in
> > + * this case) to provide separate predictor modes.  Bare metal isolates the host
> > + * from the guest, but doesn't isolate different guests from one another (in
> > + * this case L1 and L2). The exception is if bare metal supports same mode IBRS,
> > + * which offers protection within the same mode, and hence protects L1 from L2.
> > + */
> > +static inline void kvm_nested_vmexit_handle_spec_ctrl(struct kvm_vcpu *vcpu)
> 
> Maybe just kvm_nested_vmexit_handle_ibrs?

I was trying to use a generic name to accomodate any future handling
needed for non-IBRS speculation control virtualization. But I could just
be overthinking. Happy to take whatever name is agreed upon in during
reviews.

> 
> > +{
> > +       if (cpu_feature_enabled(X86_FEATURE_AMD_IBRS_SAME_MODE))
> > +               return;
> > +
> > +       if (guest_cpu_cap_has(vcpu, X86_FEATURE_SPEC_CTRL) ||
> > +           guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_IBRS))
> 
> This is a bit conservative, but I don't think there's any ROI in being
> more pedantic.

Could you elaborate on this?

Is this about doing the IBPB even if L1 does not actually execute an
IBRS? I thought about this for a bit, but otherwise we'd have to
intercept the MSR write IIUC, and I am not sure if that's better. Also,
that's what we are already doing so I just kept it as-is.

Or maybe about whether we need this on AMD only with AUTOIBRS? The APM
is a bit unclear to me in this regard, but I believe may be needed even
for 'normal' IBRS.

> 
> For the series,
> 
> Reviewed-by: Jim Mattson <jmattson@google.com>

Thanks!

> 
> > +               indirect_branch_prediction_barrier();
> > +}
> > +
> >  static inline bool kvm_vcpu_has_run(struct kvm_vcpu *vcpu)
> >  {
> >         return vcpu->arch.last_vmentry_cpu != -1;
> > --
> > 2.48.1.601.g30ceb7b040-goog
> >

  reply	other threads:[~2025-02-21 18:39 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-21 16:33 [PATCH 0/3] Unify IBRS virtualization Yosry Ahmed
2025-02-21 16:33 ` [PATCH 1/3] x86/cpufeatures: Define X86_FEATURE_AMD_IBRS_SAME_MODE Yosry Ahmed
2025-02-21 16:33 ` [PATCH 2/3] KVM: x86: Propagate AMD's IbrsSameMode to the guest Yosry Ahmed
2025-02-21 16:33 ` [PATCH 3/3] KVM: x86: Generalize IBRS virtualization on emulated VM-exit Yosry Ahmed
2025-02-21 17:59   ` Jim Mattson
2025-02-21 18:39     ` Yosry Ahmed [this message]
2025-02-21 19:02       ` Jim Mattson
2025-02-21 19:25         ` Yosry Ahmed
2025-02-21 19:52           ` Jim Mattson
2025-03-13 21:23 ` [PATCH 0/3] Unify IBRS virtualization Yosry Ahmed
2025-03-26 19:48   ` Sean Christopherson
2025-03-26 19:52     ` Yosry Ahmed
2025-04-25 22:37 ` Sean Christopherson

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=Z7jISUVBeAbw8zt6@google.com \
    --to=yosry.ahmed@linux.dev \
    --cc=David.Kaplan@amd.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=jmattson@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /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.