public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH V3 0/5] Align SVM with APM defined behaviors
@ 2026-01-22  4:57 Kevin Cheng
  2026-01-22  4:57 ` [PATCH V3 1/5] KVM: SVM: Move STGI and CLGI intercept handling Kevin Cheng
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Kevin Cheng @ 2026-01-22  4:57 UTC (permalink / raw)
  To: seanjc, pbonzini; +Cc: kvm, linux-kernel, yosry.ahmed, Kevin Cheng

The APM lists the following behaviors
  - The VMRUN, VMLOAD, VMSAVE, CLGI, VMMCALL, and INVLPGA instructions
    can be used when the EFER.SVME is set to 1; otherwise, these
    instructions generate a #UD exception.
  - If VMMCALL instruction is not intercepted, the instruction raises a
    #UD exception.
  - STGI instruction causes a #UD exception if SVM is not enabled and
    neither SVM Lock nor the device exclusion vector (DEV) are
    supported.

The patches in this series fix current SVM bugs that do not adhere to
the APM listed behaviors.

v2 -> v3:
  - Elaborated on 'Move STGI and CLGI intercept handling' commit message
    as per Sean
  - Fixed bug due to interaction with svm_enable_nmi_window() and 'Move
    STGI and CLGI intercept handling' as pointed out by Yosry. Code
    changes suggested by Sean/Yosry.
  - Removed open-coded nested_svm_check_permissions() in STGI
    interception function as per Yosry

v2: https://lore.kernel.org/all/20260112174535.3132800-1-chengkev@google.com/

v1 -> v2:
  - Split up the series into smaller more logical changes as suggested
    by Sean
  - Added patch for injecting #UD for STGI under APM defined conditions
    as suggested by Sean
  - Combined EFER.SVME=0 conditional with intel CPU logic in
    svm_recalc_instruction_intercepts

Kevin Cheng (5):
  KVM: SVM: Move STGI and CLGI intercept handling
  KVM: SVM: Inject #UD for STGI if EFER.SVME=0 and SVM Lock and DEV are
    not available
  KVM: SVM: Inject #UD for INVLPGA if EFER.SVME=0
  KVM: SVM: Recalc instructions intercepts when EFER.SVME is toggled
  KVM: SVM: Raise #UD if VMMCALL instruction is not intercepted

 arch/x86/kvm/svm/nested.c |  9 +++--
 arch/x86/kvm/svm/svm.c    | 74 +++++++++++++++++++++++++++++++++------
 arch/x86/kvm/svm/svm.h    |  1 +
 3 files changed, 71 insertions(+), 13 deletions(-)

--
2.52.0.457.g6b5491de43-goog


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH V3 1/5] KVM: SVM: Move STGI and CLGI intercept handling
  2026-01-22  4:57 [PATCH V3 0/5] Align SVM with APM defined behaviors Kevin Cheng
@ 2026-01-22  4:57 ` Kevin Cheng
  2026-01-22  4:57 ` [PATCH V3 2/5] KVM: SVM: Inject #UD for STGI if EFER.SVME=0 and SVM Lock and DEV are not available Kevin Cheng
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Kevin Cheng @ 2026-01-22  4:57 UTC (permalink / raw)
  To: seanjc, pbonzini; +Cc: kvm, linux-kernel, yosry.ahmed, Kevin Cheng

Move the STGI/CLGI intercept handling to
svm_recalc_instruction_intercepts() in preparation for making the
function EFER-aware. A later patch will recalculate instruction
intercepts when EFER.SVME is toggled, which is needed to inject #UD on
STGI/CLGI when the guest clears EFER.SVME.

When clearing the STGI intercept with vgif enabled, request
KVM_REQ_EVENT if there is a pending GIF-controlled event. This avoids
breaking NMI/SMI window tracking, as enable_{nmi,smi}_window() sets
INTERCEPT_STGI to detect when NMIs become unblocked. KVM_REQ_EVENT
forces kvm_check_and_inject_events() to re-evaluate pending events and
re-enable the intercept if needed.

Extract the pending GIF event check into a helper function
svm_has_pending_gif_event() to deduplicate the logic between
svm_recalc_instruction_intercepts() and svm_set_gif().

Signed-off-by: Kevin Cheng <chengkev@google.com>
---
 arch/x86/kvm/svm/svm.c | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 24d59ccfa40d9..7a854e81b6560 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -972,6 +972,14 @@ void svm_write_tsc_multiplier(struct kvm_vcpu *vcpu)
 	preempt_enable();
 }
 
+static bool svm_has_pending_gif_event(struct vcpu_svm *svm)
+{
+	return svm->vcpu.arch.smi_pending ||
+	       svm->vcpu.arch.nmi_pending ||
+	       kvm_cpu_has_injectable_intr(&svm->vcpu) ||
+	       kvm_apic_has_pending_init_or_sipi(&svm->vcpu);
+}
+
 /* Evaluate instruction intercepts that depend on guest CPUID features. */
 static void svm_recalc_instruction_intercepts(struct kvm_vcpu *vcpu)
 {
@@ -1010,6 +1018,20 @@ static void svm_recalc_instruction_intercepts(struct kvm_vcpu *vcpu)
 			svm_clr_intercept(svm, INTERCEPT_VMSAVE);
 			svm->vmcb->control.virt_ext |= VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK;
 		}
+
+		if (vgif) {
+			/*
+			 * If there is a pending interrupt controlled by GIF, set
+			 * KVM_REQ_EVENT to re-evaluate if the intercept needs to be set
+			 * again to track when GIF is re-enabled (e.g. for NMI
+			 * injection).
+			 */
+			svm_clr_intercept(svm, INTERCEPT_STGI);
+			if (svm_has_pending_gif_event(svm))
+				kvm_make_request(KVM_REQ_EVENT, &svm->vcpu);
+
+			svm_clr_intercept(svm, INTERCEPT_CLGI);
+		}
 	}
 }
 
@@ -1147,11 +1169,8 @@ static void init_vmcb(struct kvm_vcpu *vcpu, bool init_event)
 	if (vnmi)
 		svm->vmcb->control.int_ctl |= V_NMI_ENABLE_MASK;
 
-	if (vgif) {
-		svm_clr_intercept(svm, INTERCEPT_STGI);
-		svm_clr_intercept(svm, INTERCEPT_CLGI);
+	if (vgif)
 		svm->vmcb->control.int_ctl |= V_GIF_ENABLE_MASK;
-	}
 
 	if (vcpu->kvm->arch.bus_lock_detection_enabled)
 		svm_set_intercept(svm, INTERCEPT_BUSLOCK);
@@ -2247,10 +2266,7 @@ void svm_set_gif(struct vcpu_svm *svm, bool value)
 			svm_clear_vintr(svm);
 
 		enable_gif(svm);
-		if (svm->vcpu.arch.smi_pending ||
-		    svm->vcpu.arch.nmi_pending ||
-		    kvm_cpu_has_injectable_intr(&svm->vcpu) ||
-		    kvm_apic_has_pending_init_or_sipi(&svm->vcpu))
+		if (svm_has_pending_gif_event(svm))
 			kvm_make_request(KVM_REQ_EVENT, &svm->vcpu);
 	} else {
 		disable_gif(svm);
-- 
2.52.0.457.g6b5491de43-goog


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH V3 2/5] KVM: SVM: Inject #UD for STGI if EFER.SVME=0 and SVM Lock and DEV are not available
  2026-01-22  4:57 [PATCH V3 0/5] Align SVM with APM defined behaviors Kevin Cheng
  2026-01-22  4:57 ` [PATCH V3 1/5] KVM: SVM: Move STGI and CLGI intercept handling Kevin Cheng
@ 2026-01-22  4:57 ` Kevin Cheng
  2026-02-12 21:16   ` Sean Christopherson
  2026-01-22  4:57 ` [PATCH V3 3/5] KVM: SVM: Inject #UD for INVLPGA if EFER.SVME=0 Kevin Cheng
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Kevin Cheng @ 2026-01-22  4:57 UTC (permalink / raw)
  To: seanjc, pbonzini; +Cc: kvm, linux-kernel, yosry.ahmed, Kevin Cheng

The AMD APM states that STGI causes a #UD if SVM is not enabled and
neither SVM Lock nor the device exclusion vector (DEV) are supported.
Support for DEV is part of the SKINIT architecture. Fix the STGI exit
handler by injecting #UD when these conditions are met.

Signed-off-by: Kevin Cheng <chengkev@google.com>
---
 arch/x86/kvm/svm/nested.c |  9 +++++++--
 arch/x86/kvm/svm/svm.c    | 12 +++++++++++-
 arch/x86/kvm/svm/svm.h    |  1 +
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index ba0f11c68372b..60bb320c34bda 100644
--- a/arch/x86/kvm/svm/nested.c
+++ b/arch/x86/kvm/svm/nested.c
@@ -1466,9 +1466,9 @@ int nested_svm_exit_handled(struct vcpu_svm *svm)
 	return vmexit;
 }
 
-int nested_svm_check_permissions(struct kvm_vcpu *vcpu)
+int __nested_svm_check_permissions(struct kvm_vcpu *vcpu, bool insn_allowed)
 {
-	if (!(vcpu->arch.efer & EFER_SVME) || !is_paging(vcpu)) {
+	if (!insn_allowed || !is_paging(vcpu)) {
 		kvm_queue_exception(vcpu, UD_VECTOR);
 		return 1;
 	}
@@ -1481,6 +1481,11 @@ int nested_svm_check_permissions(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+int nested_svm_check_permissions(struct kvm_vcpu *vcpu)
+{
+	return __nested_svm_check_permissions(vcpu, vcpu->arch.efer & EFER_SVME);
+}
+
 static bool nested_svm_is_exception_vmexit(struct kvm_vcpu *vcpu, u8 vector,
 					   u32 error_code)
 {
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 7a854e81b6560..e6b1f8fa98a20 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -2283,9 +2283,19 @@ void svm_set_gif(struct vcpu_svm *svm, bool value)
 
 static int stgi_interception(struct kvm_vcpu *vcpu)
 {
+	bool insn_allowed;
 	int ret;
 
-	if (nested_svm_check_permissions(vcpu))
+	/*
+	 * According to the APM, STGI is allowed even with SVM disabled if SVM
+	 * Lock or device exclusion vector (DEV) are supported. DEV is part of
+	 * the SKINIT architecture.
+	 */
+	insn_allowed = (vcpu->arch.efer & EFER_SVME) ||
+		       guest_cpu_cap_has(vcpu, X86_FEATURE_SVML) ||
+		       guest_cpu_cap_has(vcpu, X86_FEATURE_SKINIT);
+
+	if (__nested_svm_check_permissions(vcpu, insn_allowed))
 		return 1;
 
 	ret = kvm_skip_emulated_instruction(vcpu);
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 01be93a53d077..0ec09559767a3 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -769,6 +769,7 @@ static inline int nested_svm_simple_vmexit(struct vcpu_svm *svm, u32 exit_code)
 }
 
 int nested_svm_exit_handled(struct vcpu_svm *svm);
+int __nested_svm_check_permissions(struct kvm_vcpu *vcpu, bool insn_allowed);
 int nested_svm_check_permissions(struct kvm_vcpu *vcpu);
 int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
 			       bool has_error_code, u32 error_code);
-- 
2.52.0.457.g6b5491de43-goog


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH V3 3/5] KVM: SVM: Inject #UD for INVLPGA if EFER.SVME=0
  2026-01-22  4:57 [PATCH V3 0/5] Align SVM with APM defined behaviors Kevin Cheng
  2026-01-22  4:57 ` [PATCH V3 1/5] KVM: SVM: Move STGI and CLGI intercept handling Kevin Cheng
  2026-01-22  4:57 ` [PATCH V3 2/5] KVM: SVM: Inject #UD for STGI if EFER.SVME=0 and SVM Lock and DEV are not available Kevin Cheng
@ 2026-01-22  4:57 ` Kevin Cheng
  2026-01-22  4:57 ` [PATCH V3 4/5] KVM: SVM: Recalc instructions intercepts when EFER.SVME is toggled Kevin Cheng
  2026-01-22  4:57 ` [PATCH V3 5/5] KVM: SVM: Raise #UD if VMMCALL instruction is not intercepted Kevin Cheng
  4 siblings, 0 replies; 10+ messages in thread
From: Kevin Cheng @ 2026-01-22  4:57 UTC (permalink / raw)
  To: seanjc, pbonzini; +Cc: kvm, linux-kernel, yosry.ahmed, Kevin Cheng

INVLPGA should cause a #UD when EFER.SVME is not set. Add a check to
properly inject #UD when EFER.SVME=0.

Signed-off-by: Kevin Cheng <chengkev@google.com>
Reviewed-by: Yosry Ahmed <yosry.ahmed@linux.dev>
---
 arch/x86/kvm/svm/svm.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index e6b1f8fa98a20..d3d7daf886b29 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -2320,6 +2320,9 @@ static int invlpga_interception(struct kvm_vcpu *vcpu)
 	gva_t gva = kvm_rax_read(vcpu);
 	u32 asid = kvm_rcx_read(vcpu);
 
+	if (nested_svm_check_permissions(vcpu))
+		return 1;
+
 	/* FIXME: Handle an address size prefix. */
 	if (!is_long_mode(vcpu))
 		gva = (u32)gva;
-- 
2.52.0.457.g6b5491de43-goog


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH V3 4/5] KVM: SVM: Recalc instructions intercepts when EFER.SVME is toggled
  2026-01-22  4:57 [PATCH V3 0/5] Align SVM with APM defined behaviors Kevin Cheng
                   ` (2 preceding siblings ...)
  2026-01-22  4:57 ` [PATCH V3 3/5] KVM: SVM: Inject #UD for INVLPGA if EFER.SVME=0 Kevin Cheng
@ 2026-01-22  4:57 ` Kevin Cheng
  2026-01-22  4:57 ` [PATCH V3 5/5] KVM: SVM: Raise #UD if VMMCALL instruction is not intercepted Kevin Cheng
  4 siblings, 0 replies; 10+ messages in thread
From: Kevin Cheng @ 2026-01-22  4:57 UTC (permalink / raw)
  To: seanjc, pbonzini; +Cc: kvm, linux-kernel, yosry.ahmed, Kevin Cheng

The AMD APM states that VMRUN, VMLOAD, VMSAVE, CLGI, VMMCALL, and
INVLPGA instructions should generate a #UD when EFER.SVME is cleared.
Currently, when VMLOAD, VMSAVE, or CLGI are executed in L1 with
EFER.SVME cleared, no #UD is generated in certain cases. This is because
the intercepts for these instructions are cleared based on whether or
not vls or vgif is enabled. The #UD fails to be generated when the
intercepts are absent.

Fix the missing #UD generation by ensuring that all relevant
instructions have intercepts set when SVME.EFER is disabled.

VMMCALL is special because KVM's ABI is that VMCALL/VMMCALL are always
supported for L1 and never fault.

Signed-off-by: Kevin Cheng <chengkev@google.com>
---
 arch/x86/kvm/svm/svm.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index d3d7daf886b29..1888211e20988 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -243,6 +243,8 @@ int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
 			if (svm_gp_erratum_intercept && !sev_guest(vcpu->kvm))
 				set_exception_intercept(svm, GP_VECTOR);
 		}
+
+		kvm_make_request(KVM_REQ_RECALC_INTERCEPTS, vcpu);
 	}
 
 	svm->vmcb->save.efer = efer | EFER_SVME;
@@ -984,6 +986,7 @@ static bool svm_has_pending_gif_event(struct vcpu_svm *svm)
 static void svm_recalc_instruction_intercepts(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
+	u64 efer = vcpu->arch.efer;
 
 	/*
 	 * Intercept INVPCID if shadow paging is enabled to sync/free shadow
@@ -1004,7 +1007,13 @@ static void svm_recalc_instruction_intercepts(struct kvm_vcpu *vcpu)
 			svm_set_intercept(svm, INTERCEPT_RDTSCP);
 	}
 
-	if (guest_cpuid_is_intel_compatible(vcpu)) {
+	/*
+	 * Intercept instructions that #UD if EFER.SVME=0, as SVME must be set even
+	 * when running the guest, i.e. hardware will only ever see EFER.SVME=1.
+	 */
+	if (guest_cpuid_is_intel_compatible(vcpu) || !(efer & EFER_SVME)) {
+		svm_set_intercept(svm, INTERCEPT_CLGI);
+		svm_set_intercept(svm, INTERCEPT_STGI);
 		svm_set_intercept(svm, INTERCEPT_VMLOAD);
 		svm_set_intercept(svm, INTERCEPT_VMSAVE);
 		svm->vmcb->control.virt_ext &= ~VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK;
-- 
2.52.0.457.g6b5491de43-goog


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH V3 5/5] KVM: SVM: Raise #UD if VMMCALL instruction is not intercepted
  2026-01-22  4:57 [PATCH V3 0/5] Align SVM with APM defined behaviors Kevin Cheng
                   ` (3 preceding siblings ...)
  2026-01-22  4:57 ` [PATCH V3 4/5] KVM: SVM: Recalc instructions intercepts when EFER.SVME is toggled Kevin Cheng
@ 2026-01-22  4:57 ` Kevin Cheng
  4 siblings, 0 replies; 10+ messages in thread
From: Kevin Cheng @ 2026-01-22  4:57 UTC (permalink / raw)
  To: seanjc, pbonzini
  Cc: kvm, linux-kernel, yosry.ahmed, Kevin Cheng, Manali Shukla

The AMD APM states that if VMMCALL instruction is not intercepted, the
instruction raises a #UD exception.

Create a vmmcall exit handler that generates a #UD if a VMMCALL exit
from L2 is being handled by L0, which means that L1 did not intercept
the VMMCALL instruction.

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Kevin Cheng <chengkev@google.com>
Reviewed-by: Yosry Ahmed <yosry.ahmed@linux.dev>
Reviewed-by: Manali Shukla <manali.shukla@amd.com>
Tested-by: Manali Shukla <manali.shukla@amd.com>
---
 arch/x86/kvm/svm/svm.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 1888211e20988..9257976ded539 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -3194,6 +3194,20 @@ static int bus_lock_exit(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+static int vmmcall_interception(struct kvm_vcpu *vcpu)
+{
+	/*
+	 * VMMCALL #UDs if it's not intercepted, and KVM reaches this point if
+	 * and only if the VMMCALL intercept is not set in vmcb12.
+	 */
+	if (is_guest_mode(vcpu)) {
+		kvm_queue_exception(vcpu, UD_VECTOR);
+		return 1;
+	}
+
+	return kvm_emulate_hypercall(vcpu);
+}
+
 static int (*const svm_exit_handlers[])(struct kvm_vcpu *vcpu) = {
 	[SVM_EXIT_READ_CR0]			= cr_interception,
 	[SVM_EXIT_READ_CR3]			= cr_interception,
@@ -3244,7 +3258,7 @@ static int (*const svm_exit_handlers[])(struct kvm_vcpu *vcpu) = {
 	[SVM_EXIT_TASK_SWITCH]			= task_switch_interception,
 	[SVM_EXIT_SHUTDOWN]			= shutdown_interception,
 	[SVM_EXIT_VMRUN]			= vmrun_interception,
-	[SVM_EXIT_VMMCALL]			= kvm_emulate_hypercall,
+	[SVM_EXIT_VMMCALL]			= vmmcall_interception,
 	[SVM_EXIT_VMLOAD]			= vmload_interception,
 	[SVM_EXIT_VMSAVE]			= vmsave_interception,
 	[SVM_EXIT_STGI]				= stgi_interception,
-- 
2.52.0.457.g6b5491de43-goog


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH V3 2/5] KVM: SVM: Inject #UD for STGI if EFER.SVME=0 and SVM Lock and DEV are not available
  2026-01-22  4:57 ` [PATCH V3 2/5] KVM: SVM: Inject #UD for STGI if EFER.SVME=0 and SVM Lock and DEV are not available Kevin Cheng
@ 2026-02-12 21:16   ` Sean Christopherson
  2026-02-12 21:18     ` Sean Christopherson
  0 siblings, 1 reply; 10+ messages in thread
From: Sean Christopherson @ 2026-02-12 21:16 UTC (permalink / raw)
  To: Kevin Cheng; +Cc: pbonzini, kvm, linux-kernel, yosry.ahmed

On Thu, Jan 22, 2026, Kevin Cheng wrote:
> The AMD APM states that STGI causes a #UD if SVM is not enabled and
> neither SVM Lock nor the device exclusion vector (DEV) are supported.
> Support for DEV is part of the SKINIT architecture. Fix the STGI exit
> handler by injecting #UD when these conditions are met.

This is entirely pointless.  SVML and SKINIT can never bet set in guest caps.
There are many things that are documented in the SDM/APM that don't have "correct"
handling in KVM, because they're completely unsupported.

_If_ this is causing someone enough heartburn to want to "fix", just add a comment
in nested_svm_check_permissions() stating that KVM doesn't support SVML or SKINIT.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V3 2/5] KVM: SVM: Inject #UD for STGI if EFER.SVME=0 and SVM Lock and DEV are not available
  2026-02-12 21:16   ` Sean Christopherson
@ 2026-02-12 21:18     ` Sean Christopherson
  2026-02-12 21:57       ` Kevin Cheng
  0 siblings, 1 reply; 10+ messages in thread
From: Sean Christopherson @ 2026-02-12 21:18 UTC (permalink / raw)
  To: Kevin Cheng; +Cc: pbonzini, kvm, linux-kernel, yosry.ahmed

On Thu, Feb 12, 2026, Sean Christopherson wrote:
> On Thu, Jan 22, 2026, Kevin Cheng wrote:
> > The AMD APM states that STGI causes a #UD if SVM is not enabled and
> > neither SVM Lock nor the device exclusion vector (DEV) are supported.
> > Support for DEV is part of the SKINIT architecture. Fix the STGI exit
> > handler by injecting #UD when these conditions are met.
> 
> This is entirely pointless.  SVML and SKINIT can never bet set in guest caps.
> There are many things that are documented in the SDM/APM that don't have "correct"
> handling in KVM, because they're completely unsupported.
> 
> _If_ this is causing someone enough heartburn to want to "fix", just add a comment
> in nested_svm_check_permissions() stating that KVM doesn't support SVML or SKINIT.

Case in point, patch 4 is flawed because it forces interception of STGI if
EFER.SVME=0.  I.e. by trying to handle the impossible, you're introducing new
and novel ways for KVM to do things "wrong".

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V3 2/5] KVM: SVM: Inject #UD for STGI if EFER.SVME=0 and SVM Lock and DEV are not available
  2026-02-12 21:18     ` Sean Christopherson
@ 2026-02-12 21:57       ` Kevin Cheng
  2026-02-13 15:06         ` Sean Christopherson
  0 siblings, 1 reply; 10+ messages in thread
From: Kevin Cheng @ 2026-02-12 21:57 UTC (permalink / raw)
  To: Sean Christopherson; +Cc: pbonzini, kvm, linux-kernel, yosry.ahmed

On Thu, Feb 12, 2026 at 4:18 PM Sean Christopherson <seanjc@google.com> wrote:
>
> On Thu, Feb 12, 2026, Sean Christopherson wrote:
> > On Thu, Jan 22, 2026, Kevin Cheng wrote:
> > > The AMD APM states that STGI causes a #UD if SVM is not enabled and
> > > neither SVM Lock nor the device exclusion vector (DEV) are supported.
> > > Support for DEV is part of the SKINIT architecture. Fix the STGI exit
> > > handler by injecting #UD when these conditions are met.
> >
> > This is entirely pointless.  SVML and SKINIT can never bet set in guest caps.
> > There are many things that are documented in the SDM/APM that don't have "correct"
> > handling in KVM, because they're completely unsupported.
> >
> > _If_ this is causing someone enough heartburn to want to "fix", just add a comment
> > in nested_svm_check_permissions() stating that KVM doesn't support SVML or SKINIT.
>
> Case in point, patch 4 is flawed because it forces interception of STGI if
> EFER.SVME=0.  I.e. by trying to handle the impossible, you're introducing new
> and novel ways for KVM to do things "wrong".

Just to clarify, do you mean patch 4 is flawed with patch 2? Or is the
forcing of STGI interception flawed regardless? I am assuming the
former here

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V3 2/5] KVM: SVM: Inject #UD for STGI if EFER.SVME=0 and SVM Lock and DEV are not available
  2026-02-12 21:57       ` Kevin Cheng
@ 2026-02-13 15:06         ` Sean Christopherson
  0 siblings, 0 replies; 10+ messages in thread
From: Sean Christopherson @ 2026-02-13 15:06 UTC (permalink / raw)
  To: Kevin Cheng; +Cc: pbonzini, kvm, linux-kernel, yosry.ahmed

On Thu, Feb 12, 2026, Kevin Cheng wrote:
> On Thu, Feb 12, 2026 at 4:18 PM Sean Christopherson <seanjc@google.com> wrote:
> >
> > On Thu, Feb 12, 2026, Sean Christopherson wrote:
> > > On Thu, Jan 22, 2026, Kevin Cheng wrote:
> > > > The AMD APM states that STGI causes a #UD if SVM is not enabled and
> > > > neither SVM Lock nor the device exclusion vector (DEV) are supported.
> > > > Support for DEV is part of the SKINIT architecture. Fix the STGI exit
> > > > handler by injecting #UD when these conditions are met.
> > >
> > > This is entirely pointless.  SVML and SKINIT can never bet set in guest caps.
> > > There are many things that are documented in the SDM/APM that don't have "correct"
> > > handling in KVM, because they're completely unsupported.
> > >
> > > _If_ this is causing someone enough heartburn to want to "fix", just add a comment
> > > in nested_svm_check_permissions() stating that KVM doesn't support SVML or SKINIT.
> >
> > Case in point, patch 4 is flawed because it forces interception of STGI if
> > EFER.SVME=0.  I.e. by trying to handle the impossible, you're introducing new
> > and novel ways for KVM to do things "wrong".
> 
> Just to clarify, do you mean patch 4 is flawed with patch 2? Or is the
> forcing of STGI interception flawed regardless? I am assuming the
> former here

Yes, the former.  Checking only SVME here:

	if (guest_cpuid_is_intel_compatible(vcpu) || !(efer & EFER_SVME)) {
		svm_set_intercept(svm, INTERCEPT_CLGI);
		svm_set_intercept(svm, INTERCEPT_STGI);
		svm_set_intercept(svm, INTERCEPT_VMLOAD);
		svm_set_intercept(svm, INTERCEPT_VMSAVE);

is confusing, because KVM's logic for injecting the #UD would be:

	if (!(vcpu->arch.efer & EFER_SVME) &&
	    !guest_cpu_cap_has(vcpu, X86_FEATURE_SVML) &&
	    !guest_cpu_cap_has(vcpu, X86_FEATURE_SKINIT))
		<#ud>

which raises the question of why the interception code doesn't factor in SVML and
SKINIT.  "wrong" was in quotes, because there's no functional bug, but it's weird
and confusing because KVM is blatantly contradicting itself.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-02-13 15:06 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-22  4:57 [PATCH V3 0/5] Align SVM with APM defined behaviors Kevin Cheng
2026-01-22  4:57 ` [PATCH V3 1/5] KVM: SVM: Move STGI and CLGI intercept handling Kevin Cheng
2026-01-22  4:57 ` [PATCH V3 2/5] KVM: SVM: Inject #UD for STGI if EFER.SVME=0 and SVM Lock and DEV are not available Kevin Cheng
2026-02-12 21:16   ` Sean Christopherson
2026-02-12 21:18     ` Sean Christopherson
2026-02-12 21:57       ` Kevin Cheng
2026-02-13 15:06         ` Sean Christopherson
2026-01-22  4:57 ` [PATCH V3 3/5] KVM: SVM: Inject #UD for INVLPGA if EFER.SVME=0 Kevin Cheng
2026-01-22  4:57 ` [PATCH V3 4/5] KVM: SVM: Recalc instructions intercepts when EFER.SVME is toggled Kevin Cheng
2026-01-22  4:57 ` [PATCH V3 5/5] KVM: SVM: Raise #UD if VMMCALL instruction is not intercepted Kevin Cheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox