mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v5 0/2] KVM: nSVM: Intercept STGI/CLGI as needed to inject #UD
@ 2026-03-04  0:30 Sean Christopherson
  2026-03-04  0:30 ` [PATCH v5 1/2] KVM: SVM: Move STGI and CLGI intercept handling Sean Christopherson
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Sean Christopherson @ 2026-03-04  0:30 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, Kevin Cheng

The STGI/CLGI fixes from Kevin's broader "Align SVM with APM defined behaviors"
series.

v5:
 - Separate the STGI/CLGI fixes from everything else.
 - Apply the Intel compatibiliy weirdness only to VMLOAD/VMSAVE (to fixup
   SYSENTER MSRs).
 - Re-remove STGI/CLGI intercept clearing in init_vmcb().

v4:
  - https://lore.kernel.org/all/20260228033328.2285047-1-chengkev@google.com
  - Dropped "KVM: SVM: Inject #UD for STGI if EFER.SVME=0 and SVM Lock
    and DEV are not available" as per Sean
  - Added back STGI and CLGI intercept clearing in init_vmcb to maintain
    previous behavior on intel guests. Previously intel guests always
    had STGI and CLGI intercepts cleared if vgif was enabled. In V3,
    because the clearing of the intercepts was moved from init_vmcb() to
    the !guest_cpuid_is_intel_compatible() case in
    svm_recalc_instruction_intercepts(), the CLGI intercept would be
    indefinitely set on intel guests. I added back the clearing to
    init_vmcb() to retain intel guest behavior before this patch.
  - In "Raise #UD if VMMCALL instruction is not intercepted" patch:
      - Exempt Hyper-V L2 TLB flush hypercalls from the #UD injection,
        as L0 intentionally intercepts these VMMCALLs on behalf of L1
	via the direct hypercall enlightenment.
      - Added nested_svm_is_l2_tlb_flush_hcall() which just returns true
        if the hypercall was a Hyper-V L2 TLB flush hypercall.

v3:
  - https://lore.kernel.org/kvm/20260122045755.205203-1-chengkev@google.com/
  - 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
  - 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 (2):
  KVM: SVM: Move STGI and CLGI intercept handling
  KVM: SVM: Recalc instructions intercepts when EFER.SVME is toggled

 arch/x86/kvm/svm/svm.c | 53 +++++++++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 13 deletions(-)


base-commit: 11439c4635edd669ae435eec308f4ab8a0804808
-- 
2.53.0.473.g4a7958ca14-goog


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

* [PATCH v5 1/2] KVM: SVM: Move STGI and CLGI intercept handling
  2026-03-04  0:30 [PATCH v5 0/2] KVM: nSVM: Intercept STGI/CLGI as needed to inject #UD Sean Christopherson
@ 2026-03-04  0:30 ` Sean Christopherson
  2026-03-04  1:19   ` Yosry Ahmed
  2026-03-04  0:30 ` [PATCH v5 2/2] KVM: SVM: Recalc instructions intercepts when EFER.SVME is toggled Sean Christopherson
  2026-03-05 17:08 ` [PATCH v5 0/2] KVM: nSVM: Intercept STGI/CLGI as needed to inject #UD Sean Christopherson
  2 siblings, 1 reply; 6+ messages in thread
From: Sean Christopherson @ 2026-03-04  0:30 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, Kevin Cheng

From: Kevin Cheng <chengkev@google.com>

Move STGI/CLGI intercept handling to svm_recalc_instruction_intercepts()
in preparation for making the function EFER.SVME-aware.  This will allow
configuring STGI/CLGI intercepts along with other intercepts for other SVM
instructions when EFER.SVME is toggled (KVM needs to intercept SVM
instructions when EFER.SVME=0 to inject #UD).

When clearing the STGI intercept in particular, request KVM_REQ_EVENT if
there is at least one 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>
[sean: keep vgif handling out of the "Intel CPU model" path]
Signed-off-by: Sean Christopherson <seanjc@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 8f8bc863e214..5975a1e14ac9 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -1009,6 +1009,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)
 {
@@ -1052,6 +1060,20 @@ static void svm_recalc_instruction_intercepts(struct kvm_vcpu *vcpu)
 		}
 	}
 
+	if (vgif) {
+		svm_clr_intercept(svm, INTERCEPT_STGI);
+		svm_clr_intercept(svm, INTERCEPT_CLGI);
+
+		/*
+		 * Process pending events when clearing STGI/CLGI intercepts if
+		 * there's at least one pending event that is masked by GIF, so
+		 * that KVM re-evaluates if the intercept needs to be set again
+		 * to track when GIF is re-enabled (e.g. for NMI injection).
+		 */
+		if (svm_has_pending_gif_event(svm))
+			kvm_make_request(KVM_REQ_EVENT, &svm->vcpu);
+	}
+
 	if (kvm_need_rdpmc_intercept(vcpu))
 		svm_set_intercept(svm, INTERCEPT_RDPMC);
 	else
@@ -1195,11 +1217,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 (vls)
 		svm->vmcb->control.virt_ext |= VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK;
@@ -2320,10 +2339,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.53.0.473.g4a7958ca14-goog


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

* [PATCH v5 2/2] KVM: SVM: Recalc instructions intercepts when EFER.SVME is toggled
  2026-03-04  0:30 [PATCH v5 0/2] KVM: nSVM: Intercept STGI/CLGI as needed to inject #UD Sean Christopherson
  2026-03-04  0:30 ` [PATCH v5 1/2] KVM: SVM: Move STGI and CLGI intercept handling Sean Christopherson
@ 2026-03-04  0:30 ` Sean Christopherson
  2026-03-04  1:20   ` Yosry Ahmed
  2026-03-05 17:08 ` [PATCH v5 0/2] KVM: nSVM: Intercept STGI/CLGI as needed to inject #UD Sean Christopherson
  2 siblings, 1 reply; 6+ messages in thread
From: Sean Christopherson @ 2026-03-04  0:30 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, Kevin Cheng

From: Kevin Cheng <chengkev@google.com>

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>
[sean: isolate Intel CPU "compatibility" in EFER.SVME=1 path]
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/svm/svm.c | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 5975a1e14ac9..07b595487caf 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -244,6 +244,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;
@@ -1042,27 +1044,31 @@ static void svm_recalc_instruction_intercepts(struct kvm_vcpu *vcpu)
 	}
 
 	/*
-	 * No need to toggle VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK here, it is
-	 * always set if vls is enabled. If the intercepts are set, the bit is
-	 * meaningless anyway.
+	 * 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.
+	 *
+	 * No need to toggle any of the vgif/vls/etc. enable bits here, as they
+	 * are set when the VMCB is initialized and never cleared (if the
+	 * relevant intercepts are set, the enablements are meaningless anyway).
 	 */
-	if (guest_cpuid_is_intel_compatible(vcpu)) {
+	if (!(vcpu->arch.efer & EFER_SVME)) {
 		svm_set_intercept(svm, INTERCEPT_VMLOAD);
 		svm_set_intercept(svm, INTERCEPT_VMSAVE);
+		svm_set_intercept(svm, INTERCEPT_CLGI);
+		svm_set_intercept(svm, INTERCEPT_STGI);
 	} else {
 		/*
 		 * If hardware supports Virtual VMLOAD VMSAVE then enable it
 		 * in VMCB and clear intercepts to avoid #VMEXIT.
 		 */
-		if (vls) {
+		if (guest_cpuid_is_intel_compatible(vcpu)) {
+			svm_set_intercept(svm, INTERCEPT_VMLOAD);
+			svm_set_intercept(svm, INTERCEPT_VMSAVE);
+		} else if (vls) {
 			svm_clr_intercept(svm, INTERCEPT_VMLOAD);
 			svm_clr_intercept(svm, INTERCEPT_VMSAVE);
 		}
-	}
-
-	if (vgif) {
-		svm_clr_intercept(svm, INTERCEPT_STGI);
-		svm_clr_intercept(svm, INTERCEPT_CLGI);
 
 		/*
 		 * Process pending events when clearing STGI/CLGI intercepts if
@@ -1070,8 +1076,13 @@ static void svm_recalc_instruction_intercepts(struct kvm_vcpu *vcpu)
 		 * that KVM re-evaluates if the intercept needs to be set again
 		 * to track when GIF is re-enabled (e.g. for NMI injection).
 		 */
-		if (svm_has_pending_gif_event(svm))
-			kvm_make_request(KVM_REQ_EVENT, &svm->vcpu);
+		if (vgif) {
+			svm_clr_intercept(svm, INTERCEPT_CLGI);
+			svm_clr_intercept(svm, INTERCEPT_STGI);
+
+			if (svm_has_pending_gif_event(svm))
+				kvm_make_request(KVM_REQ_EVENT, &svm->vcpu);
+		}
 	}
 
 	if (kvm_need_rdpmc_intercept(vcpu))
-- 
2.53.0.473.g4a7958ca14-goog


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

* Re: [PATCH v5 1/2] KVM: SVM: Move STGI and CLGI intercept handling
  2026-03-04  0:30 ` [PATCH v5 1/2] KVM: SVM: Move STGI and CLGI intercept handling Sean Christopherson
@ 2026-03-04  1:19   ` Yosry Ahmed
  0 siblings, 0 replies; 6+ messages in thread
From: Yosry Ahmed @ 2026-03-04  1:19 UTC (permalink / raw)
  To: Sean Christopherson; +Cc: Paolo Bonzini, kvm, linux-kernel, Kevin Cheng

On Tue, Mar 03, 2026 at 04:30:09PM -0800, Sean Christopherson wrote:
> From: Kevin Cheng <chengkev@google.com>
> 
> Move STGI/CLGI intercept handling to svm_recalc_instruction_intercepts()
> in preparation for making the function EFER.SVME-aware.  This will allow
> configuring STGI/CLGI intercepts along with other intercepts for other SVM
> instructions when EFER.SVME is toggled (KVM needs to intercept SVM
> instructions when EFER.SVME=0 to inject #UD).
> 
> When clearing the STGI intercept in particular, request KVM_REQ_EVENT if
> there is at least one 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>
> [sean: keep vgif handling out of the "Intel CPU model" path]
> Signed-off-by: Sean Christopherson <seanjc@google.com>

Reviewed-by: Yosry Ahmed <yosry@kernel.org>

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

* Re: [PATCH v5 2/2] KVM: SVM: Recalc instructions intercepts when EFER.SVME is toggled
  2026-03-04  0:30 ` [PATCH v5 2/2] KVM: SVM: Recalc instructions intercepts when EFER.SVME is toggled Sean Christopherson
@ 2026-03-04  1:20   ` Yosry Ahmed
  0 siblings, 0 replies; 6+ messages in thread
From: Yosry Ahmed @ 2026-03-04  1:20 UTC (permalink / raw)
  To: Sean Christopherson; +Cc: Paolo Bonzini, kvm, linux-kernel, Kevin Cheng

On Tue, Mar 03, 2026 at 04:30:10PM -0800, Sean Christopherson wrote:
> From: Kevin Cheng <chengkev@google.com>
> 
> 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>
> [sean: isolate Intel CPU "compatibility" in EFER.SVME=1 path]
> Signed-off-by: Sean Christopherson <seanjc@google.com>

Reviewed-by: Yosry Ahmed <yosry@kernel.org>

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

* Re: [PATCH v5 0/2] KVM: nSVM: Intercept STGI/CLGI as needed to inject #UD
  2026-03-04  0:30 [PATCH v5 0/2] KVM: nSVM: Intercept STGI/CLGI as needed to inject #UD Sean Christopherson
  2026-03-04  0:30 ` [PATCH v5 1/2] KVM: SVM: Move STGI and CLGI intercept handling Sean Christopherson
  2026-03-04  0:30 ` [PATCH v5 2/2] KVM: SVM: Recalc instructions intercepts when EFER.SVME is toggled Sean Christopherson
@ 2026-03-05 17:08 ` Sean Christopherson
  2 siblings, 0 replies; 6+ messages in thread
From: Sean Christopherson @ 2026-03-05 17:08 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, Kevin Cheng

On Tue, 03 Mar 2026 16:30:08 -0800, Sean Christopherson wrote:
> The STGI/CLGI fixes from Kevin's broader "Align SVM with APM defined behaviors"
> series.
> 
> v5:
>  - Separate the STGI/CLGI fixes from everything else.
>  - Apply the Intel compatibiliy weirdness only to VMLOAD/VMSAVE (to fixup
>    SYSENTER MSRs).
>  - Re-remove STGI/CLGI intercept clearing in init_vmcb().
> 
> [...]

Applied to kvm-x86 nested, thanks!

[1/2] KVM: SVM: Move STGI and CLGI intercept handling
      https://github.com/kvm-x86/linux/commit/69f779f79e0d
[2/2] KVM: SVM: Recalc instructions intercepts when EFER.SVME is toggled
      https://github.com/kvm-x86/linux/commit/460c7eb2e759

--
https://github.com/kvm-x86/linux/tree/next

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

end of thread, other threads:[~2026-03-05 17:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-03-04  0:30 [PATCH v5 0/2] KVM: nSVM: Intercept STGI/CLGI as needed to inject #UD Sean Christopherson
2026-03-04  0:30 ` [PATCH v5 1/2] KVM: SVM: Move STGI and CLGI intercept handling Sean Christopherson
2026-03-04  1:19   ` Yosry Ahmed
2026-03-04  0:30 ` [PATCH v5 2/2] KVM: SVM: Recalc instructions intercepts when EFER.SVME is toggled Sean Christopherson
2026-03-04  1:20   ` Yosry Ahmed
2026-03-05 17:08 ` [PATCH v5 0/2] KVM: nSVM: Intercept STGI/CLGI as needed to inject #UD Sean Christopherson

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®