[PATCH v3 54/55] KVM: arm/arm64: vgic-new: implement mapped IRQ handling

Christoffer Dall christoffer.dall at linaro.org
Thu May 12 12:36:28 PDT 2016


On Fri, May 06, 2016 at 11:46:07AM +0100, Andre Przywara wrote:
> 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 at arm.com>
> ---
> Changelog RFC..v1:
> - adapt to new arch_timer mapped IRQ interface
> - implement inject_mapped_irq() as a macro (since it is identical to
>   the "un-mapped" IRQ implementation)
> 
> Changelog v1 .. v2:
> - replace inject_mapped_irq() macro with a separate implementation,
>   which only allows mapped IRQs to be injected via this interface
> 
>  include/kvm/vgic/vgic.h  |  5 +++++
>  virt/kvm/arm/vgic/vgic.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 55 insertions(+)
> 
> diff --git a/include/kvm/vgic/vgic.h b/include/kvm/vgic/vgic.h
> index 07c3011..64aca0c 100644
> --- a/include/kvm/vgic/vgic.h
> +++ b/include/kvm/vgic/vgic.h
> @@ -213,6 +213,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);
>  
> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
> index 068389a..3f854c5 100644
> --- a/virt/kvm/arm/vgic/vgic.c
> +++ b/virt/kvm/arm/vgic/vgic.c
> @@ -310,6 +310,44 @@ 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);
> +
> +	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
>   *
> @@ -563,3 +601,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;
> +}
> -- 
> 2.7.3
> 

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>



More information about the linux-arm-kernel mailing list