From: Sean Christopherson <seanjc@google.com>
To: Yosry Ahmed <yosry@kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
Stefan Teodorescu <fane@google.com>
Subject: Re: [PATCH 1/4] KVM: nSVM: Reject KVM_SET_NESTED_STATE if L1 has EFER.LMA=1 && EFER.LME=0
Date: Thu, 27 Aug 2026 11:24:23 -0700 [thread overview]
Message-ID: <apCA17CwdWTriJxf@google.com> (raw)
In-Reply-To: <CAO9r8zPtriVwkVqmvRDv5mQ8HmvOp=NrXdJvjRuog6FY_S1DRQ@mail.gmail.com>
On Thu, Aug 27, 2026, Yosry Ahmed wrote:
> On Thu, Aug 27, 2026 at 10:33 AM Sean Christopherson <seanjc@google.com> wrote:
> > > Oh yeah you're right, for some reason I thought it was paging not
> > > protected mode. Well then, it seems like
> > > nested_svm_check_permissions() is also incorrectly checking paging as
> > > well, seems like both checks are incorrect? Also, I don't see anything
> > > in the APM about checking RFLAGS.VM before VMRUN.
> >
> > Presumably it's covered by the !PROTECTED_MODE clause.
> >
> > IF ((MSR_EFER.SVME == 0) || (!PROTECTED_MODE)) // This instruction can only be executed in protected
> > EXCEPTION [#UD] // mode with SVM enabled
> >
> > Section "1.3.4 Legacy Modes" describes "Protected Mode" and "Virtual-8086 Mode"
> > as separate submodes. And the tables for most instructions differentiate between
> > Real, Virtual 8086, and Protected modes when enumerating exceptions.
> >
> > The APM weasels around 64-bit mode by also saying "Before enabling and activating
> > long mode, system software must first enable protected mode". E.g. the table for
> > SYSENTER describes the #UD due to "This instruction is not recognized in long mode"
> > as scenario that's unique to Protected Mode.
> >
> > Stating the obvious, it would be lovely if the APM explicitly stated what the
> > exact checks are, though that's about as likely as AMD gifting me a pony.
> >
> > FWIW, if that reading is wrong (though I'm pretty sure it's not), then the only
> > issue is that KVM is synthesizing #UD instead of #GP, because Virtual 8086 always
> > runs at CPL=3.
> >
> > IF (CPL != 0) // This instruction is only allowed at CPL 0
> > EXCEPTION [#GP]
>
> I see, thanks for digging this up. Either way I think we want to keep
> things consistent between here and nested_svm_check_permissions().
Yes, for sure. nested_svm_check_permissions() is... odd.
> We probably want a CPL check here,
Yes? Though FWIW, that risks breaking userspace because currently KVM completely
ignores save.cpl and forces it to '0' in svm_copy_vmrun_state(). I mean, this
change also risks breaking userspace, but at least in this case there's a very
good reason for doing so. But I'm certainly not against trying to provide sanity.
> and it would be a superset of X86_EFLAGS_VM as you mentioned.
It might not be? Both CPL and VM8086 are bizarre, I wouldn't be surprised if
save.cpl could be '0' with VM8086 active. E.g. on Intel, there is no explicit
CPL, it's derived from SS.DPL (because CPL isn't actualy its own thing without
virtualization, it's indeed a reflection of state).
P.S. vmx->rmode.vm86_active doesn't track that the guest is in VM8086, it tracks
that KVM has put the vCPU into VM8086 in order to emulate Real Mode, which
is why __vmx_get_cpl() returns '0', not '3'.
static int __vmx_get_cpl(struct kvm_vcpu *vcpu, bool no_cache)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
int ar;
if (unlikely(vmx->rmode.vm86_active))
return 0;
}
> We probably wanna drop the CR0.PG check from both places, and add an explicit
> X86_EFLAGS_VM check in nested_svm_check_permissions() to #UD instead of #GP?
And add a CR0.PE check. But to get it "right", we'll probably need to check
against real hardware, so practically speaking, I don't expect anyone to tackle
this anytime soon.
next prev parent reply other threads:[~2026-08-27 18:24 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-26 21:18 [PATCH 0/4] KVM: nSVM: Disallow bad L1 EFER for KVM_SET_NESTED_STATE Sean Christopherson
2026-08-26 21:18 ` [PATCH 1/4] KVM: nSVM: Reject KVM_SET_NESTED_STATE if L1 has EFER.LMA=1 && EFER.LME=0 Sean Christopherson
2026-08-26 21:33 ` sashiko-bot
2026-08-27 7:02 ` Yosry Ahmed
2026-08-27 13:36 ` Sean Christopherson
2026-08-27 16:29 ` Yosry Ahmed
2026-08-27 17:33 ` Sean Christopherson
2026-08-27 17:55 ` Yosry Ahmed
2026-08-27 18:24 ` Sean Christopherson [this message]
2026-08-27 21:41 ` Paolo Bonzini
2026-08-27 22:01 ` Yosry Ahmed
2026-08-28 5:26 ` Paolo Bonzini
2026-08-26 21:18 ` [PATCH 2/4] KVM: x86/mmu: Bug the VM if KVM attempts to walk more levels than the MMU has Sean Christopherson
2026-08-26 21:41 ` sashiko-bot
2026-08-26 21:56 ` Sean Christopherson
2026-08-27 7:05 ` Yosry Ahmed
2026-08-27 13:48 ` Sean Christopherson
2026-08-26 21:18 ` [PATCH 3/4] KVM: x86/mmu: Bug the VM if KVM calcs a CPU role with EFER.LMA=1 && CR4.PAE=0 Sean Christopherson
2026-08-26 21:31 ` sashiko-bot
2026-08-27 7:08 ` Yosry Ahmed
2026-08-27 14:57 ` Sean Christopherson
2026-08-27 16:38 ` Yosry Ahmed
2026-08-27 17:29 ` Sean Christopherson
2026-08-27 17:48 ` Yosry Ahmed
2026-08-27 18:13 ` Sean Christopherson
2026-08-26 21:18 ` [PATCH 4/4] KVM: x86/mmu: Convert MMU walker's bounds check from BUG_ON() to KVM_BUG_ON() Sean Christopherson
2026-08-27 7:11 ` Yosry Ahmed
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=apCA17CwdWTriJxf@google.com \
--to=seanjc@google.com \
--cc=fane@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=yosry@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox