From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Auger Subject: Re: [RFC PATCH 43/45] KVM: arm/arm64: vgic-new: implement mapped IRQ handling Date: Fri, 1 Apr 2016 10:44:21 +0200 Message-ID: <56FE34E5.6030803@linaro.org> References: <1458871508-17279-1-git-send-email-andre.przywara@arm.com> <1458871508-17279-44-git-send-email-andre.przywara@arm.com> <20160331181517.GG4126@cbox> Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Cc: Marc Zyngier , kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org To: Christoffer Dall , Andre Przywara Return-path: Received: from mail-wm0-f48.google.com ([74.125.82.48]:38812 "EHLO mail-wm0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752055AbcDAIpc (ORCPT ); Fri, 1 Apr 2016 04:45:32 -0400 Received: by mail-wm0-f48.google.com with SMTP id 20so13869293wmh.1 for ; Fri, 01 Apr 2016 01:45:31 -0700 (PDT) In-Reply-To: <20160331181517.GG4126@cbox> Sender: kvm-owner@vger.kernel.org List-ID: On 03/31/2016 08:15 PM, Christoffer Dall wrote: > On Fri, Mar 25, 2016 at 02:05:06AM +0000, Andre Przywara wrote: >> 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 >> --- >> 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 >> #include >> #include >> +#include >> +#include >> +#include >> >> #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); > > eh, but that's not an INTID, that's a linux IRQ number then right? agreed. Also the declaration suggested it is a linux irq. Eric > >> + 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@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html From mboxrd@z Thu Jan 1 00:00:00 1970 From: eric.auger@linaro.org (Eric Auger) Date: Fri, 1 Apr 2016 10:44:21 +0200 Subject: [RFC PATCH 43/45] KVM: arm/arm64: vgic-new: implement mapped IRQ handling In-Reply-To: <20160331181517.GG4126@cbox> References: <1458871508-17279-1-git-send-email-andre.przywara@arm.com> <1458871508-17279-44-git-send-email-andre.przywara@arm.com> <20160331181517.GG4126@cbox> Message-ID: <56FE34E5.6030803@linaro.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On 03/31/2016 08:15 PM, Christoffer Dall wrote: > On Fri, Mar 25, 2016 at 02:05:06AM +0000, Andre Przywara wrote: >> 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 >> --- >> 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 >> #include >> #include >> +#include >> +#include >> +#include >> >> #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); > > eh, but that's not an INTID, that's a linux IRQ number then right? agreed. Also the declaration suggested it is a linux irq. Eric > >> + 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 at vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html