[PATCH 0/2] KVM: nVMX: Fix ept=n bugs where KVM runs L2 with guest CR3

From: Sean Christopherson

Date: Wed Jun 03 2026 - 18:34:51 EST


Fix two bugs where KVM can run L2 with a guest-controlled CR3. The underlying
flaw dates back to commit f087a02941fe ("KVM: nVMX: Stash L1's CR3 in
vmcs01.GUEST_CR3 on nested entry w/o EPT"). Past me claimed:

Smashing vmcs01.GUEST_CR3 is safe because nested VM-Exits, and the unwind,
reset KVM's MMU, i.e. vmcs01.GUEST_CR3 is guaranteed to be overwritten with
a shadow CR3 prior to re-entering L1.

which was and is true, _if_ a nested VM-Exit or the unwind is reached. If KVM
fails directly, vmcs01.GUEST_CR3 will be left pointing at L1's actual CR3, i.e.
KVM will run with legacy shadow paging a guest-controlled CR3, which is... not
good.

Note, the vTPR fix will cause KVM-Unit-Test's TPR Threshold test to fail when
run with warn_on_missed_cc=1:

FAIL: Use TPR shadow enabled: virtual-APIC address = 8000000: vmlaunch succeeds
FAIL: Use TPR shadow enabled: virtual-APIC address = 10000000: vmlaunch succeeds
...
FAIL: Use TPR shadow enabled: virtual-APIC address = ffffffffff000: vmlaunch succeeds

due to KVM actually accessing the virtual APIC page. Given that I'm pretty
sure I'm the only person that runs with warn_on_missed_cc=1, and that IMO this
is firmly a test bug (e.g. on bare metal I'm pretty sure there's guarantee
VMLAUNCH will succeed), I don't see any reason to try and make it "work" in
KVM. I might try to figure out a way to make the KUT testcase play nice, but
for now I'll just ignore the failures in my test runs.

Sean Christopherson (2):
KVM: nVMX: Move vTPR vs. TPR Threshold consistency check into "normal"
checks
KVM: nVMX: Don't use vmcs01.GUEST_CR3 to snapshot L1's CR3 when EPT is
disabled

arch/x86/kvm/vmx/nested.c | 86 ++++++++++++++++-----------------------
arch/x86/kvm/vmx/vmx.h | 7 ++++
2 files changed, 43 insertions(+), 50 deletions(-)


base-commit: d4bfaa66fa171089b9b9fb2dc17af9245f2b9b34
--
2.54.0.1032.g2f8565e1d1-goog