[PATCH v5 10/26] KVM: arm/arm64: GICv4: Wire mapping/unmapping of VLPIs in VFIO irq bypass

Christoffer Dall cdall at linaro.org
Fri Nov 10 01:41:34 PST 2017


On Fri, Nov 10, 2017 at 10:05 AM, Marc Zyngier <marc.zyngier at arm.com> wrote:
> On 10/11/17 08:28, Christoffer Dall wrote:
>> Hi Eric and Marc,
>>
>> On Tue, Nov 07, 2017 at 02:42:44PM +0000, Marc Zyngier wrote:
>>> Hi Eric,
>>>
>>> On 07/11/17 13:06, Auger Eric wrote:
>>>> Hi Marc,
>>>>
>>>> On 27/10/2017 16:28, Marc Zyngier wrote:
>>>>> Let's use the irq bypass mechanism introduced for platform device
>>>>> interrupts
>>>> nit: I would remove "introduced for platform device interrupts"
>>>> as this is not upstream yet. x86 posted interrupts also use it.
>>>>
>>>>>
>>>>  and establish our LPI->VLPI mapping.
>>
>> I have tweaked the commit message.
>>
>>>>>
>>>>> Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
>>>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>>>> ---
>>>>>  include/kvm/arm_vgic.h      |   8 ++++
>>>>>  virt/kvm/arm/arm.c          |   6 ++-
>>>>>  virt/kvm/arm/vgic/vgic-v4.c | 108 ++++++++++++++++++++++++++++++++++++++++++++
>>>>>  3 files changed, 120 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>>>> index 7eeb6c2a2f9c..2f750c770bf2 100644
>>>>> --- a/include/kvm/arm_vgic.h
>>>>> +++ b/include/kvm/arm_vgic.h
>>>>> @@ -373,4 +373,12 @@ int kvm_vgic_setup_default_irq_routing(struct kvm *kvm);
>>>>>
>>>>>  int kvm_vgic_set_owner(struct kvm_vcpu *vcpu, unsigned int intid, void *owner);
>>>>>
>>>>> +struct kvm_kernel_irq_routing_entry;
>>>>> +
>>>>> +int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int irq,
>>>>> +                         struct kvm_kernel_irq_routing_entry *irq_entry);
>>>>> +
>>>>> +int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int irq,
>>>>> +                           struct kvm_kernel_irq_routing_entry *irq_entry);
>>>>> +
>>>>>  #endif /* __KVM_ARM_VGIC_H */
>>>>> diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
>>>>> index 5d5218ecd547..8388c1cc23f6 100644
>>>>> --- a/virt/kvm/arm/arm.c
>>>>> +++ b/virt/kvm/arm/arm.c
>>>>> @@ -1462,7 +1462,8 @@ int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
>>>>>    struct kvm_kernel_irqfd *irqfd =
>>>>>            container_of(cons, struct kvm_kernel_irqfd, consumer);
>>>>>
>>>>> -  return 0;
>>>>> +  return kvm_vgic_v4_set_forwarding(irqfd->kvm, prod->irq,
>>>>> +                                    &irqfd->irq_entry);
>>>>>  }
>>>>>  void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
>>>>>                                  struct irq_bypass_producer *prod)
>>>>> @@ -1470,7 +1471,8 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
>>>>>    struct kvm_kernel_irqfd *irqfd =
>>>>>            container_of(cons, struct kvm_kernel_irqfd, consumer);
>>>>>
>>>>> -  return;
>>>>> +  kvm_vgic_v4_unset_forwarding(irqfd->kvm, prod->irq,
>>>>> +                               &irqfd->irq_entry);
>>>>>  }
>>>>>
>>>>>  void kvm_arch_irq_bypass_stop(struct irq_bypass_consumer *cons)
>>>>> diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c
>>>>> index c794f0cef09e..01a2889b7b7c 100644
>>>>> --- a/virt/kvm/arm/vgic/vgic-v4.c
>>>>> +++ b/virt/kvm/arm/vgic/vgic-v4.c
>>>>> @@ -18,6 +18,7 @@
>>>>>  #include <linux/interrupt.h>
>>>>>  #include <linux/irqdomain.h>
>>>>>  #include <linux/kvm_host.h>
>>>>> +#include <linux/irqchip/arm-gic-v3.h>
>>>>>
>>>>>  #include "vgic.h"
>>>>>
>>>>> @@ -81,3 +82,110 @@ void vgic_v4_teardown(struct kvm *kvm)
>>>>>    its_vm->nr_vpes = 0;
>>>>>    its_vm->vpes = NULL;
>>>>>  }
>>>>> +
>>>>> +static struct vgic_its *vgic_get_its(struct kvm *kvm,
>>>>> +                               struct kvm_kernel_irq_routing_entry *irq_entry)
>>>>> +{
>>>>> +  struct kvm_msi msi  = (struct kvm_msi) {
>>>>> +          .address_lo     = irq_entry->msi.address_lo,
>>>>> +          .address_hi     = irq_entry->msi.address_hi,
>>>>> +          .data           = irq_entry->msi.data,
>>>>> +          .flags          = irq_entry->msi.flags,
>>>>> +          .devid          = irq_entry->msi.devid,
>>>>> +  };
>>>>> +
>>>>> +  /*
>>>>> +   * Get a reference on the LPI. If NULL, this is not a valid
>>>>> +   * translation for any of our vITSs.
>>>>> +   */
>>>> I don't understand the relevance of the above comment.
>>>
>>> Hmmm. The first part looks like an outdated leftover, as the ITS is not
>>> refcounted, and we don't deal with LPIs here.
>>>
>>
>> I simply removed this comment.
>>
>> [...]
>>
>> I think the only thing left to fix on this patch is the IRQ_DISABLE_LAZY
>> thing on its_map_vlpi() failures, which Marc can fix post -rc1.
>
> Here's what I've queued on the irqchip side:
>
> From 9c0733704b99c89773416af3a412332b0e8bd2a4 Mon Sep 17 00:00:00 2001
> From: Marc Zyngier <marc.zyngier at arm.com>
> Date: Fri, 10 Nov 2017 09:00:41 +0000
> Subject: [PATCH] irqchip/gic-v4: Clear IRQ_DISABLE_UNLAZY again if mapping
>  fails
>
> Should the call to irq_set_vcpu_affinity() fail at map time,
> we should restore the normal lazy-disable behaviour instead
> of staying with the eager disable that GICv4 requires.
>
> Reported-by: Eric Auger <eric.auger at redhat.com>
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  drivers/irqchip/irq-gic-v4.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
> index cd0bcc3b7e33..dba9d67cb9c1 100644
> --- a/drivers/irqchip/irq-gic-v4.c
> +++ b/drivers/irqchip/irq-gic-v4.c
> @@ -177,6 +177,7 @@ int its_map_vlpi(int irq, struct its_vlpi_map *map)
>                         .map      = map,
>                 },
>         };
> +       int ret;
>
>         /*
>          * The host will never see that interrupt firing again, so it
> @@ -184,7 +185,11 @@ int its_map_vlpi(int irq, struct its_vlpi_map *map)
>          */
>         irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
>
> -       return irq_set_vcpu_affinity(irq, &info);
> +       ret = irq_set_vcpu_affinity(irq, &info);
> +       if (ret)
> +               irq_clear_status_flags(irq, IRQ_DISABLE_UNLAZY);
> +
> +       return ret;
>  }
>
>  int its_get_vlpi(int irq, struct its_vlpi_map *map)
> --
> 2.14.2
>
>

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



More information about the linux-arm-kernel mailing list