We now store the mapped hardware IRQ number in our struct, so we don't need the irq_phys_map any longer for the new VGIC. Implement the hardware IRQ mapping on top of the reworked arch timer interface. Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx> --- include/kvm/vgic/vgic.h | 15 ++++++++ virt/kvm/arm/vgic/vgic.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/include/kvm/vgic/vgic.h b/include/kvm/vgic/vgic.h index e418de9..7c1d145 100644 --- a/include/kvm/vgic/vgic.h +++ b/include/kvm/vgic/vgic.h @@ -206,6 +206,21 @@ 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); + +/* + * This is not really needed, but we need this type to keep the arch + * timer compatible with the old VGIC implementation. + * This should be removed upon retiring the old VGIC. + */ +struct irq_phys_map {}; + +struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, + u32 virt_irq, u32 irq); +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map, + u32 intid); +bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, u32 intid); int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c index 4ade7c0..65395af 100644 --- a/virt/kvm/arm/vgic/vgic.c +++ b/virt/kvm/arm/vgic/vgic.c @@ -17,6 +17,9 @@ #include <linux/kvm.h> #include <linux/kvm_host.h> #include <linux/list_sort.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/irqdesc.h> #include "vgic.h" @@ -276,6 +279,83 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, vcpu = kvm_get_vcpu(kvm, cpuid); vgic_update_irq_pending(kvm, vcpu, intid, level); + + return 0; +} + +/** + * kvm_vgic_inject_mapped_irq - Inject a hardware mapped IRQ to the vgic + * @kvm: The VM structure pointer + * @cpuid: The CPU for PPIs + * @irq_num: The INTID to inject a new state to. + * @level: Edge-triggered: true: to trigger the interrupt + * false: to ignore the call + * Level-sensitive true: raise the input signal + * false: lower the input signal + * + * The GIC is not concerned with devices being active-LOW or active-HIGH for + * level-sensitive interrupts. You can think of the level parameter as 1 + * being HIGH and 0 being LOW and all devices being active-HIGH. + */ +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid, unsigned int intid, + bool level) +{ + struct kvm_vcpu *vcpu; + int ret; + + ret = vgic_lazy_init(kvm); + if (ret) + return ret; + + vcpu = kvm_get_vcpu(kvm, cpuid); + vgic_update_irq_pending(kvm, vcpu, intid, level); + + return 0; +} + +struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, + u32 virt_irq, u32 intid) +{ + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, virt_irq); + struct irq_desc *desc; + struct irq_data *data; + + BUG_ON(!irq); + + desc = irq_to_desc(intid); + if (!desc) { + kvm_err("%s: no interrupt descriptor\n", __func__); + return NULL; + } + + data = irq_desc_get_irq_data(desc); + while (data->parent_data) + data = data->parent_data; + + spin_lock(&irq->irq_lock); + + irq->hw = true; + irq->hwintid = data->hwirq; + + spin_unlock(&irq->irq_lock); + + return NULL; +} + +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map, + u32 intid) +{ + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid); + + BUG_ON(!irq); + + spin_lock(&irq->irq_lock); + + irq->hw = false; + irq->hwintid = 0; + + spin_unlock(&irq->irq_lock); + return 0; } @@ -520,3 +600,15 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) return pending; } + +bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, u32 intid) +{ + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid); + 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; +} -- 2.7.3 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html