[PATCH 4/6] KVM: SVM: fix races in the AVIC incomplete IPI delivery to vCPUs

Maxim Levitsky
2021-12-09T11:56:07Z

If the target vCPU has AVIC inhibited while the source vCPU isn't,
we need to set irr_pending, for the target to notice the interrupt.
Do it always to be safe, the same as in svm_deliver_avic_intr.

Also if the target has AVIC inhibited, the same kind of races
that happen in svm_deliver_avic_intr can happen here as well,
so apply the same approach of kicking the target vCPUs.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
arch/x86/kvm/svm/avic.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 8c1b934bfa9b..bdfc37caa64a 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -304,8 +304,17 @@ static void avic_kick_target_vcpus(struct kvm *kvm, struct kvm_lapic *source,
kvm_for_each_vcpu(i, vcpu, kvm) {
if (kvm_apic_match_dest(vcpu, source, icrl & APIC_SHORT_MASK,
GET_APIC_DEST_FIELD(icrh),
- icrl & APIC_DEST_MASK))
- kvm_vcpu_wake_up(vcpu);
+ icrl & APIC_DEST_MASK)) {
+
+ vcpu->arch.apic->irr_pending = true;
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
+ /*
+ * The target vCPU might have AVIC inhibited,
+ * so we have to kick it, to make sure it processes
+ * the interrupt.
+ */
+ kvm_vcpu_kick(vcpu);
+ }
}
}

--
2.26.3