Commit 0e9ff65f authored by Halil Pasic's avatar Halil Pasic Committed by Christian Borntraeger
Browse files

KVM: s390: preserve deliverable_mask in __airqs_kick_single_vcpu



Changing the deliverable mask in __airqs_kick_single_vcpu() is a bug. If
one idle vcpu can't take the interrupts we want to deliver, we should
look for another vcpu that can, instead of saying that we don't want
to deliver these interrupts by clearing the bits from the
deliverable_mask.

Fixes: 9f30f621 ("KVM: s390: add gib_alert_irq_handler()")
Signed-off-by: default avatarHalil Pasic <pasic@linux.ibm.com>
Reviewed-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: default avatarMichael Mueller <mimu@linux.ibm.com>
Reviewed-by: default avatarClaudio Imbrenda <imbrenda@linux.ibm.com>
Link: https://lore.kernel.org/r/20211019175401.3757927-3-pasic@linux.ibm.com


Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
parent 9b57e9d5
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -3053,13 +3053,14 @@ static void __airqs_kick_single_vcpu(struct kvm *kvm, u8 deliverable_mask)
	int vcpu_idx, online_vcpus = atomic_read(&kvm->online_vcpus);
	struct kvm_s390_gisa_interrupt *gi = &kvm->arch.gisa_int;
	struct kvm_vcpu *vcpu;
	u8 vcpu_isc_mask;

	for_each_set_bit(vcpu_idx, kvm->arch.idle_mask, online_vcpus) {
		vcpu = kvm_get_vcpu(kvm, vcpu_idx);
		if (psw_ioint_disabled(vcpu))
			continue;
		deliverable_mask &= (u8)(vcpu->arch.sie_block->gcr[6] >> 24);
		if (deliverable_mask) {
		vcpu_isc_mask = (u8)(vcpu->arch.sie_block->gcr[6] >> 24);
		if (deliverable_mask & vcpu_isc_mask) {
			/* lately kicked but not yet running */
			if (test_and_set_bit(vcpu_idx, gi->kicked_mask))
				return;