Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 437f9963 authored by Pavel Fedin's avatar Pavel Fedin Committed by Christoffer Dall
Browse files

KVM: arm/arm64: Do not inject spurious interrupts



When lowering a level-triggered line from userspace, we forgot to lower
the pending bit on the emulated CPU interface and we also did not
re-compute the pending_on_cpu bitmap for the CPU affected by the change.

Update vgic_update_irq_pending() to fix the two issues above and also
raise a warning in vgic_quue_irq_to_lr if we encounter an interrupt
pending on a CPU which is neither marked active nor pending.

  [ Commit text reworked completely - Christoffer ]

Signed-off-by: default avatarPavel Fedin <p.fedin@samsung.com>
Signed-off-by: default avatarChristoffer Dall <christoffer.dall@linaro.org>
parent 920552b2
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -1132,7 +1132,8 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
		kvm_debug("Set active, clear distributor: 0x%x\n", vlr.state);
		vgic_irq_clear_active(vcpu, irq);
		vgic_update_state(vcpu->kvm);
	} else if (vgic_dist_irq_is_pending(vcpu, irq)) {
	} else {
		WARN_ON(!vgic_dist_irq_is_pending(vcpu, irq));
		vlr.state |= LR_STATE_PENDING;
		kvm_debug("Set pending: 0x%x\n", vlr.state);
	}
@@ -1607,8 +1608,12 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
	} else {
		if (level_triggered) {
			vgic_dist_irq_clear_level(vcpu, irq_num);
			if (!vgic_dist_irq_soft_pend(vcpu, irq_num))
			if (!vgic_dist_irq_soft_pend(vcpu, irq_num)) {
				vgic_dist_irq_clear_pending(vcpu, irq_num);
				vgic_cpu_irq_clear(vcpu, irq_num);
				if (!compute_pending_for_cpu(vcpu))
					clear_bit(cpuid, dist->irq_pending_on_cpu);
			}
		}

		ret = false;