mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 19:13:47 +02:00
KVM: SVM: Move STGI and CLGI intercept handling
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]
Reviewed-by: Yosry Ahmed <yosry@kernel.org>
Link: https://patch.msgid.link/20260304003010.1108257-2-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
parent
33d3617a52
commit
69f779f79e
|
|
@ -999,6 +999,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)
|
||||
{
|
||||
|
|
@ -1042,6 +1050,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
|
||||
|
|
@ -1185,11 +1207,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;
|
||||
|
|
@ -2306,10 +2325,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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user