From: Anil Altinay <aaltinay@google.com>
To: stable@vger.kernel.org
Cc: Jim Mattson <jmattson@google.com>,
Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>,
kvm@vger.kernel.org, Anil Altinay <aaltinay@google.com>
Subject: [PATCH 6.18.y v2 2/6] KVM: x86: Consolidate CPUID fault handling for emulator and interception logic
Date: Thu, 15 Oct 2026 16:03:42 +0000 [thread overview]
Message-ID: <20261015160346.181835-3-aaltinay@google.com> (raw)
In-Reply-To: <20261015160346.181835-1-aaltinay@google.com>
From: Sean Christopherson <seanjc@google.com>
commit cf7d65d1d6f50daadfe7c475f0c2b1bfdc288b56 upstream.
Extract the logic for emulating CPUID faulting (where CPUID #GPs at CPL>0
outside of SMM) into a dedicated helper and use the helper for both the
full emulator and the intercepted-CPUID paths.
Opportunistically drop kvm_require_cpl(), as kvm_emulate_cpuid() was the
one and only user.
No functional change intended.
[jim: Add EXPORT_STATIC_CALL_GPL(kvm_x86_get_cpl) so that KVM vendor
modules can call kvm_is_cpuid_allowed(). Fix typo in commit message.]
Signed-off-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>
Link: https://patch.msgid.link/20260527174347.2356165-2-jmattson@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
[ Resolve minor context conflict in arch/x86/include/asm/kvm_host.h ]
Signed-off-by: Anil Altinay <aaltinay@google.com>
---
arch/x86/include/asm/kvm_host.h | 1 -
arch/x86/kvm/cpuid.c | 5 +++--
arch/x86/kvm/cpuid.h | 8 ++++++++
arch/x86/kvm/emulate.c | 6 +-----
arch/x86/kvm/kvm_emulate.h | 1 +
arch/x86/kvm/x86.c | 19 +++++++------------
6 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index b2cf3431e259..0458f51a571e 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -2255,7 +2255,6 @@ void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr,
void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault);
void kvm_inject_emulated_page_fault(struct kvm_vcpu *vcpu,
struct x86_exception *fault);
-bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl);
bool kvm_require_dr(struct kvm_vcpu *vcpu, int dr);
static inline int __kvm_irq_line_state(unsigned long *irq_state,
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index bfa89fbe826b..3f2689fdc304 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -2098,9 +2098,10 @@ int kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
{
u32 eax, ebx, ecx, edx;
- if (!is_smm(vcpu) && cpuid_fault_enabled(vcpu) &&
- !kvm_require_cpl(vcpu, 0))
+ if (!kvm_is_cpuid_allowed(vcpu)) {
+ kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
return 1;
+ }
eax = kvm_rax_read(vcpu);
ecx = kvm_rcx_read(vcpu);
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index d3f5ae15a7ca..c5399ab7e5ae 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -7,6 +7,8 @@
#include <asm/processor.h>
#include <uapi/asm/kvm_para.h>
+#include "smm.h"
+
extern u32 kvm_cpu_caps[NR_KVM_CPU_CAPS] __read_mostly;
void kvm_set_cpu_caps(void);
@@ -184,6 +186,12 @@ static inline bool cpuid_fault_enabled(struct kvm_vcpu *vcpu)
MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
}
+static inline bool kvm_is_cpuid_allowed(struct kvm_vcpu *vcpu)
+{
+ return !cpuid_fault_enabled(vcpu) || is_smm(vcpu) ||
+ !kvm_x86_call(get_cpl)(vcpu);
+}
+
static __always_inline void kvm_cpu_cap_clear(unsigned int x86_feature)
{
unsigned int x86_leaf = __feature_leaf(x86_feature);
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 8aa10d0e9894..54a1528003fa 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3557,12 +3557,8 @@ static int em_sti(struct x86_emulate_ctxt *ctxt)
static int em_cpuid(struct x86_emulate_ctxt *ctxt)
{
u32 eax, ebx, ecx, edx;
- u64 msr = 0;
- ctxt->ops->get_msr(ctxt, MSR_MISC_FEATURES_ENABLES, &msr);
- if (!ctxt->ops->is_smm(ctxt) &&
- (msr & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT) &&
- ctxt->ops->cpl(ctxt))
+ if (!ctxt->ops->is_cpuid_allowed(ctxt))
return emulate_gp(ctxt, 0);
eax = reg_read(ctxt, VCPU_REGS_RAX);
diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h
index 7b5ddb787a25..c0dcfebcec07 100644
--- a/arch/x86/kvm/kvm_emulate.h
+++ b/arch/x86/kvm/kvm_emulate.h
@@ -225,6 +225,7 @@ struct x86_emulate_ops {
struct x86_instruction_info *info,
enum x86_intercept_stage stage);
+ bool (*is_cpuid_allowed)(struct x86_emulate_ctxt *ctxt);
bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt, u32 *eax, u32 *ebx,
u32 *ecx, u32 *edx, bool exact_only);
bool (*guest_has_movbe)(struct x86_emulate_ctxt *ctxt);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ae33393c9b47..6f76290e79c9 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -138,6 +138,7 @@ struct kvm_x86_ops kvm_x86_ops __read_mostly;
#include <asm/kvm-x86-ops.h>
EXPORT_STATIC_CALL_GPL(kvm_x86_get_cs_db_l_bits);
EXPORT_STATIC_CALL_GPL(kvm_x86_cache_reg);
+EXPORT_STATIC_CALL_GPL(kvm_x86_get_cpl);
#define KVM_X86_NESTED_OP(func) \
DEFINE_STATIC_CALL_NULL(kvm_x86_nested_##func, \
@@ -1011,18 +1012,6 @@ void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code)
}
EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_queue_exception_e);
-/*
- * Checks if cpl <= required_cpl; if true, return true. Otherwise queue
- * a #GP and return false.
- */
-bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl)
-{
- if (kvm_x86_call(get_cpl)(vcpu) <= required_cpl)
- return true;
- kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
- return false;
-}
-
bool kvm_require_dr(struct kvm_vcpu *vcpu, int dr)
{
if ((dr != 4 && dr != 5) || !kvm_is_cr4_bit_set(vcpu, X86_CR4_DE))
@@ -8422,6 +8411,11 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
&ctxt->exception);
}
+static bool emulator_is_cpuid_allowed(struct x86_emulate_ctxt *ctxt)
+{
+ return kvm_is_cpuid_allowed(emul_to_vcpu(ctxt));
+}
+
static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
u32 *eax, u32 *ebx, u32 *ecx, u32 *edx,
bool exact_only)
@@ -8545,6 +8539,7 @@ static const struct x86_emulate_ops emulate_ops = {
.wbinvd = emulator_wbinvd,
.fix_hypercall = emulator_fix_hypercall,
.intercept = emulator_intercept,
+ .is_cpuid_allowed = emulator_is_cpuid_allowed,
.get_cpuid = emulator_get_cpuid,
.guest_has_movbe = emulator_guest_has_movbe,
.guest_has_fxsr = emulator_guest_has_fxsr,
--
2.56.0.385.gd3acb90ef8-goog
next prev parent reply other threads:[~2026-10-15 16:03 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-15 16:03 [PATCH 6.18.y v2 0/6] KVM: x86: CPUID faulting fixes and AMD CPUID faulting virtualization Anil Altinay
2026-10-15 16:03 ` [PATCH 6.18.y v2 1/6] KVM: x86: Ignore cpuid faulting in SMM Anil Altinay
2026-10-15 16:03 ` Anil Altinay [this message]
2026-10-15 16:03 ` [PATCH 6.18.y v2 3/6] KVM: x86: Prioritize CPUID faulting over CPUID VM-exits in nested VMX Anil Altinay
2026-10-15 16:03 ` [PATCH 6.18.y v2 4/6] KVM: x86: Remove supports_cpuid_fault() helper Anil Altinay
2026-10-15 16:03 ` [PATCH 6.18.y v2 5/6] KVM: x86: Virtualize AMD CPUID faulting Anil Altinay
2026-10-15 16:03 ` [PATCH 6.18.y v2 6/6] KVM: selftests: Update hwcr_msr_test for CPUID faulting bit Anil Altinay
2026-10-16 1:09 ` [PATCH 6.18.y v2 0/6] KVM: x86: CPUID faulting fixes and AMD CPUID faulting virtualization 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=20261015160346.181835-3-aaltinay@google.com \
--to=aaltinay@google.com \
--cc=jmattson@google.com \
--cc=kvm@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=stable@vger.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.