All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: sashiko-reviews@lists.linux.dev
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH 3/4] KVM: x86: Recompute EFER.LMA instead of inheriting the current value on EFER writes
Date: Mon, 26 Oct 2026 11:09:01 -0700	[thread overview]
Message-ID: <at-XPai1zCM_Zr2z@google.com> (raw)
In-Reply-To: <at-TP7Il6rWcd5Xh@google.com>

On Mon, Oct 26, 2026, Sean Christopherson wrote:
> On Thu, Oct 22, 2026, sashiko-bot@kernel.org wrote:
> > Because svm_set_cr0() sets EFER_LMA without checking is_pae(vcpu) (for
> > example on an SEV-SNP AP created via SVM_VMGEXIT_AP_CREATE where
> > sev_snp_init_protected_guest_state() calls kvm_vcpu_reset() and clears
> > vcpu->arch.cr4 while the VMSA has CR4.PAE=1), 

Wait, no, kvm_vcpu_reset() also immediately clears EFER:

	kvm_x86_call(set_cr4)(vcpu, 0);
	kvm_x86_call(set_efer)(vcpu, 0);  <===

and svm_set_efer() sets vcpu->arch.efer verbatim.

> > or if a guest clears CR4.PAE observed via cr_trap() while EFER_LMA=1,

And I'm pretty sure Sashiko is wrong on this one too, as this can't happen.
Clearing CR4.PAE while long mode is active results in a #GP, and hardware should
enforcee that when MOV CR4 intercepts are trap-like.

So I don't think the vcpu->kvm->arch.has_protected_state waiver is needed (though
I do think it makes sense to WARN and continute, not WARN and reject).

> a subsequent efer_trap() ->
> > set_efer() sees EFER_LMA=1 with !is_pae(vcpu) and triggers the WARN_ON_ONCE()
> > and #GP.
> 
> Ugh.  I _want_ this to be a KVM bug, e.g. as is already pointed out by the comment:
> 
> 	 * Clear EFER_LMSLE for a related reason: EFER writes are *trapped*,
> 	 * not intercepted, i.e. hardware has already committed the write by
> 	 * the time KVM gains control, and the trap is enabled if and only if
> 	 * the guest is SEV-ES, whose EFER lives in the encrypted VMSA and so
> 	 * can't be fixed up by KVM.  Rejecting EFER.LMSLE=1 would inject a #GP
> 	 * *and* leave EFER.LMSLE set in the guest, which is strictly worse
> 	 * than honoring a write that hardware itself allowed.
> 
> "rejecting" a value and injecting a #GP is completely pointless.  The guest already
> has the "bad" value in EFER, and a misbehaving guest can simply eat the #GP.
> 
> But the issue is really just that KVM simply doesn't have visibility into EFER.LMA
> being set.  Heh, which technically makes this a bug fix, since IIUC, the current
> code will never set EFER.LMA in this case?
> 
> I can't think of any way to do the right thing other than to rely on hardware to
> not screw up?  E.g.
> 
> diff --git a/arch/x86/kvm/msrs.c b/arch/x86/kvm/msrs.c
> index 41f3ec6eb286..3a6a0ebf1932 100644
> --- a/arch/x86/kvm/msrs.c
> +++ b/arch/x86/kvm/msrs.c
> @@ -648,7 +648,8 @@ static int set_efer(struct kvm_vcpu *vcpu, u64 efer)
>  	 * it means KVM allowed architecturally invalid state at some point in
>  	 * the past, i.e. allowed EFER.LMA=1 && (!CR0.PG || !CR4.PAE).
>  	 */
> -	if (WARN_ON_ONCE((efer & EFER_LMA) != (vcpu->arch.efer & EFER_LMA)))
> +	if (WARN_ON_ONCE((efer & EFER_LMA) != (vcpu->arch.efer & EFER_LMA) &&
> +			 !vcpu->kvm->arch.has_protected_state))
>  		return 1;
>  
>  	r = kvm_x86_call(set_efer)(vcpu, efer);
> 
> 
> Hmm, though all of these cases make me wonder if we'd better off with just a WARN,
> i.e. no #GP, since the goal is to enforce a consistent model, which is what the
> new code does.
> 
> 	/*
> 	 * Toggling EFER.LMA on a bare write to EFER should be impossible, as
> 	 * it means KVM allowed architecturally invalid state at some point in
> 	 * the past, i.e. allowed EFER.LMA=1 && (!CR0.PG || !CR4.PAE).
> 	 */
> 	WARN_ON_ONCE((efer & EFER_LMA) != (vcpu->arch.efer & EFER_LMA) &&
> 		     !vcpu->kvm->arch.has_protected_state);
> 

  reply	other threads:[~2026-10-26 18:09 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-22 22:30 [PATCH 0/4] KVM: x86: More EFER.LMA vs. CR4.PAE fixes Sean Christopherson
2026-10-22 22:30 ` [PATCH 1/4] Revert "KVM: x86: Skip EFER vs. guest CPUID checks for host-initiated writes" Sean Christopherson
2026-10-22 22:38   ` sashiko-bot
2026-10-22 22:30 ` [PATCH 2/4] KVM: nSVM: Synthesize #GP instead of SHUTDOWN if L2 attempts to clear EFER.SVME Sean Christopherson
2026-10-22 22:41   ` sashiko-bot
2026-10-26 18:17     ` Sean Christopherson
2026-10-22 22:30 ` [PATCH 3/4] KVM: x86: Recompute EFER.LMA instead of inheriting the current value on EFER writes Sean Christopherson
2026-10-22 22:48   ` sashiko-bot
2026-10-26 17:51     ` Sean Christopherson
2026-10-26 18:09       ` Sean Christopherson [this message]
2026-10-23 15:04   ` Yosry Ahmed
2026-10-26 17:37     ` Sean Christopherson
2026-10-22 22:30 ` [PATCH 4/4] KVM: selftests: Update nSVM EFER test to expect #GP when clearing SVME in L2 Sean Christopherson
2026-10-22 22:51   ` sashiko-bot

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=at-XPai1zCM_Zr2z@google.com \
    --to=seanjc@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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.