summaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2015-12-21 19:52:33 -0500
committerChristoffer Dall <christoffer.dall@linaro.org>2016-05-20 09:40:09 -0400
commit568e8c901eaa62004640cad8b9773819f27461a0 (patch)
tree910e2d67765897df1ca30ccff4eb2bc9d1d5ad96 /virt
parent03f0c94c73b9d7d55e057e4035cf3127ac44d41e (diff)
KVM: arm/arm64: vgic-new: implement mapped IRQ handling
We now store the mapped hardware IRQ number in our struct, so we don't need the irq_phys_map for the new VGIC. Implement the hardware IRQ mapping on top of the reworked arch timer interface. Signed-off-by: Andre Przywara <andre.przywara@arm.com> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/vgic/vgic.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index 331885528ead..69b61abefa19 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -312,6 +312,47 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid,
312 return vgic_update_irq_pending(kvm, cpuid, intid, level, false); 312 return vgic_update_irq_pending(kvm, cpuid, intid, level, false);
313} 313}
314 314
315int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid, unsigned int intid,
316 bool level)
317{
318 return vgic_update_irq_pending(kvm, cpuid, intid, level, true);
319}
320
321int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, u32 virt_irq, u32 phys_irq)
322{
323 struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, virt_irq);
324
325 BUG_ON(!irq);
326
327 spin_lock(&irq->irq_lock);
328
329 irq->hw = true;
330 irq->hwintid = phys_irq;
331
332 spin_unlock(&irq->irq_lock);
333
334 return 0;
335}
336
337int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq)
338{
339 struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, virt_irq);
340
341 BUG_ON(!irq);
342
343 if (!vgic_initialized(vcpu->kvm))
344 return -EAGAIN;
345
346 spin_lock(&irq->irq_lock);
347
348 irq->hw = false;
349 irq->hwintid = 0;
350
351 spin_unlock(&irq->irq_lock);
352
353 return 0;
354}
355
315/** 356/**
316 * vgic_prune_ap_list - Remove non-relevant interrupts from the list 357 * vgic_prune_ap_list - Remove non-relevant interrupts from the list
317 * 358 *
@@ -564,3 +605,15 @@ void vgic_kick_vcpus(struct kvm *kvm)
564 kvm_vcpu_kick(vcpu); 605 kvm_vcpu_kick(vcpu);
565 } 606 }
566} 607}
608
609bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq)
610{
611 struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, virt_irq);
612 bool map_is_active;
613
614 spin_lock(&irq->irq_lock);
615 map_is_active = irq->hw && irq->active;
616 spin_unlock(&irq->irq_lock);
617
618 return map_is_active;
619}