Skip to content

Commit 413aa80

Browse files
chazyMarc Zyngier
authored andcommitted
KVM: arm/arm64: Reset mapped IRQs on VM reset
We currently don't allow resetting mapped IRQs from userspace, because their state is controlled by the hardware. But we do need to reset the state when the VM is reset, so we provide a function for the 'owner' of the mapped interrupt to reset the interrupt state. Currently only the timer uses mapped interrupts, so we call this function from the timer reset logic. Cc: [email protected] Fixes: 4c60e36 ("KVM: arm/arm64: Provide a get_input_level for the arch timer") Signed-off-by: Christoffer Dall <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
1 parent e21a4f3 commit 413aa80

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

include/kvm/arm_vgic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ void kvm_vgic_put(struct kvm_vcpu *vcpu);
360360
bool kvm_vcpu_has_pending_irqs(struct kvm_vcpu *vcpu);
361361
void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
362362
void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
363+
void kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid);
363364

364365
void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
365366

virt/kvm/arm/arch_timer.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,7 @@ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
581581

582582
int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
583583
{
584+
struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
584585
struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
585586
struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
586587

@@ -594,6 +595,9 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
594595
ptimer->cnt_ctl = 0;
595596
kvm_timer_update_state(vcpu);
596597

598+
if (timer->enabled && irqchip_in_kernel(vcpu->kvm))
599+
kvm_vgic_reset_mapped_irq(vcpu, vtimer->irq.irq);
600+
597601
return 0;
598602
}
599603

virt/kvm/arm/vgic/vgic.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,32 @@ int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq,
495495
return ret;
496496
}
497497

498+
/**
499+
* kvm_vgic_reset_mapped_irq - Reset a mapped IRQ
500+
* @vcpu: The VCPU pointer
501+
* @vintid: The INTID of the interrupt
502+
*
503+
* Reset the active and pending states of a mapped interrupt. Kernel
504+
* subsystems injecting mapped interrupts should reset their interrupt lines
505+
* when we are doing a reset of the VM.
506+
*/
507+
void kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid)
508+
{
509+
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
510+
unsigned long flags;
511+
512+
if (!irq->hw)
513+
goto out;
514+
515+
spin_lock_irqsave(&irq->irq_lock, flags);
516+
irq->active = false;
517+
irq->pending_latch = false;
518+
irq->line_level = false;
519+
spin_unlock_irqrestore(&irq->irq_lock, flags);
520+
out:
521+
vgic_put_irq(vcpu->kvm, irq);
522+
}
523+
498524
int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid)
499525
{
500526
struct vgic_irq *irq;

0 commit comments

Comments
 (0)