From: Sean Christopherson <seanjc@google.com>
To: Paolo Bonzini <pbonzini@redhat.com>,
Sean Christopherson <seanjc@google.com>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
Mahmoud Abumandour <ma.mandourr@gmail.com>
Subject: [PATCH v3 2/5] KVM: nVMX: Honor L1-owned CR0 bits when emulating intercepted LMSW for L2
Date: Fri, 30 Oct 2026 14:37:44 -0700 [thread overview]
Message-ID: <20261030213747.2611815-3-seanjc@google.com> (raw)
In-Reply-To: <20261030213747.2611815-1-seanjc@google.com>
From: Mahmoud Abumandour <ma.mandourr@gmail.com>
When emulating an intercepted LMSW on behalf L2, i.e. when LMSW exits to L0
but not to L1, emulate it via handle_set_cr0(), as is done for MOV to CR0,
so that KVM honor's the guest/host mask and read shadow from vmcs12. This
fixes a bug where so L2 could change L1-owned CR0 bits, e.g. clear TS, and
read their effective values instead of the read shadow.
Drop kvm_lmsw() as it is no longer used, and opportunistically trace the
effectively CR0 value (previously, KVM traced the raw CR0.PE value), e.g.
so that users don't have to piece together that CR0.PE will be preserved if
it was already '1'.
Fixes: eeadf9e7558c ("KVM: nVMX: Handling of CR0 and CR4 modifying instructions")
Signed-off-by: Mahmoud Abumandour <ma.mandourr@gmail.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/regs.c | 6 ------
arch/x86/kvm/regs.h | 1 -
arch/x86/kvm/vmx/vmx.c | 6 ++++--
3 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/arch/x86/kvm/regs.c b/arch/x86/kvm/regs.c
index 3621f1a47d37..44a88c70b77b 100644
--- a/arch/x86/kvm/regs.c
+++ b/arch/x86/kvm/regs.c
@@ -303,12 +303,6 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
}
EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_set_cr0);
-void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw)
-{
- (void)kvm_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~0x0eul) | (msw & 0x0f));
-}
-EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_lmsw);
-
int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
{
bool skip_tlb_flush = false;
diff --git a/arch/x86/kvm/regs.h b/arch/x86/kvm/regs.h
index 97c17b120a57..c30ac8394271 100644
--- a/arch/x86/kvm/regs.h
+++ b/arch/x86/kvm/regs.h
@@ -62,7 +62,6 @@ int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val);
unsigned long kvm_get_dr(struct kvm_vcpu *vcpu, int dr);
unsigned long kvm_get_dr6_fixed_1(struct kvm_vcpu *vcpu);
unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu);
-void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw);
int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3);
static inline bool is_long_mode(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 544b7840897c..2d5feeb8a059 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -5743,8 +5743,10 @@ static int handle_cr(struct kvm_vcpu *vcpu)
break;
case 3: /* lmsw */
val = (exit_qualification >> LMSW_SOURCE_DATA_SHIFT) & 0x0f;
- trace_kvm_cr_write(0, (kvm_read_cr0_bits(vcpu, ~0xful) | val));
- kvm_lmsw(vcpu, val);
+ val |= kvm_read_cr0_bits(vcpu, ~0x0eul);
+
+ trace_kvm_cr_write(cr, val);
+ (void)handle_set_cr0(vcpu, val);
return kvm_skip_emulated_instruction(vcpu);
default:
--
2.56.0.385.gac671c819a-goog
next prev parent reply other threads:[~2026-10-30 21:37 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-30 21:37 [PATCH v3 0/5] KVM: nVMX: Honor L1-owned CR0 bits for LMSW Sean Christopherson
2026-10-30 21:37 ` [PATCH v3 1/5] KVM: nVMX: Preserve L1-owned bits in CR{0,4} read shadows Sean Christopherson
2026-10-30 21:37 ` Sean Christopherson [this message]
2026-10-30 21:37 ` [PATCH v3 3/5] KVM: nVMX: Synthesize #GP if L2 writes a "bad" CR0 value via LMSW Sean Christopherson
2026-10-30 21:37 ` [PATCH v3 4/5] KVM: nVMX: Take full ownership of the post-VMXON CR{0,4} must-be-1 bits Sean Christopherson
2026-10-30 21:37 ` [PATCH v3 5/5] KVM: selftests: Verify KVM handling of L1-owned CR0 bits on writes from L2 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=20261030213747.2611815-3-seanjc@google.com \
--to=seanjc@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ma.mandourr@gmail.com \
--cc=pbonzini@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®