]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
KVM: arm/arm64: vgic-new: implement mapped IRQ handling
authorAndre Przywara <andre.przywara@arm.com>
Tue, 22 Dec 2015 00:52:33 +0000 (00:52 +0000)
committerChristoffer Dall <christoffer.dall@linaro.org>
Fri, 20 May 2016 13:40:09 +0000 (15:40 +0200)
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>
include/kvm/vgic/vgic.h
virt/kvm/arm/vgic/vgic.c

index 17b2a73cca966935a966a75bf5dca62dc993d578..3fbd175265ae4fb921b28fa81045fa1648d1213c 100644 (file)
@@ -206,6 +206,11 @@ int kvm_vgic_hyp_init(void);
 
 int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid,
                        bool level);
+int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid, unsigned int intid,
+                              bool level);
+int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, u32 virt_irq, u32 phys_irq);
+int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq);
+bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq);
 
 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
 
index 331885528ead6060723bd88c334938164b53c2cf..69b61abefa19a84fe4ca9f46b7d158cc6a0d4ef1 100644 (file)
@@ -312,6 +312,47 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid,
        return vgic_update_irq_pending(kvm, cpuid, intid, level, false);
 }
 
+int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid, unsigned int intid,
+                              bool level)
+{
+       return vgic_update_irq_pending(kvm, cpuid, intid, level, true);
+}
+
+int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, u32 virt_irq, u32 phys_irq)
+{
+       struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, virt_irq);
+
+       BUG_ON(!irq);
+
+       spin_lock(&irq->irq_lock);
+
+       irq->hw = true;
+       irq->hwintid = phys_irq;
+
+       spin_unlock(&irq->irq_lock);
+
+       return 0;
+}
+
+int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq)
+{
+       struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, virt_irq);
+
+       BUG_ON(!irq);
+
+       if (!vgic_initialized(vcpu->kvm))
+               return -EAGAIN;
+
+       spin_lock(&irq->irq_lock);
+
+       irq->hw = false;
+       irq->hwintid = 0;
+
+       spin_unlock(&irq->irq_lock);
+
+       return 0;
+}
+
 /**
  * vgic_prune_ap_list - Remove non-relevant interrupts from the list
  *
@@ -564,3 +605,15 @@ void vgic_kick_vcpus(struct kvm *kvm)
                        kvm_vcpu_kick(vcpu);
        }
 }
+
+bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq)
+{
+       struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, virt_irq);
+       bool map_is_active;
+
+       spin_lock(&irq->irq_lock);
+       map_is_active = irq->hw && irq->active;
+       spin_unlock(&irq->irq_lock);
+
+       return map_is_active;
+}