* [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
* 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
* [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 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®