diff options
author | Andre Przywara <andre.przywara@arm.com> | 2015-12-21 19:52:33 -0500 |
---|---|---|
committer | Christoffer Dall <christoffer.dall@linaro.org> | 2016-05-20 09:40:09 -0400 |
commit | 568e8c901eaa62004640cad8b9773819f27461a0 (patch) | |
tree | 910e2d67765897df1ca30ccff4eb2bc9d1d5ad96 /virt | |
parent | 03f0c94c73b9d7d55e057e4035cf3127ac44d41e (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.c | 53 |
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 | ||
315 | int 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 | |||
321 | int 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 | |||
337 | int 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 | |||
609 | bool 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 | } | ||