Hi Marc,

On 6/1/21 11:40 AM, Marc Zyngier wrote:
> We already have the option to attach a callback to an interrupt
> to retrieve its pending state. As we are planning to expand this
> facility, move this callback into its own data structure.
>
> This will limit the size of individual interrupts as the ops
> structures can be shared across multiple interrupts.

I can't figure out what you mean by that. If you are referring to struct 
vgic_irq,
the change I am seeing is a pointer being replaced by another pointer, which
shouldn't affect its size. Are you referring to something else?

>
> Signed-off-by: Marc Zyngier <[email protected]>
> ---
>  arch/arm64/kvm/arch_timer.c |  8 ++++++--
>  arch/arm64/kvm/vgic/vgic.c  | 14 +++++++-------
>  include/kvm/arm_vgic.h      | 28 +++++++++++++++++-----------
>  3 files changed, 30 insertions(+), 20 deletions(-)
>
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index 74e0699661e9..e2288b6bf435 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -1116,6 +1116,10 @@ bool kvm_arch_timer_get_input_level(int vintid)
>       return kvm_timer_should_fire(timer);
>  }
>  
> +static struct irq_ops arch_timer_irq_ops = {
> +     .get_input_level = kvm_arch_timer_get_input_level,

Since kvm_arch_timer_get_input_level() is used only indirectly, through the
get_input_level field of the static struct, I think we can make
kvm_arch_timer_get_input_level() static and remove the declaration from
include/kvm/arm_arch_timer.h.

Other than that, everything else looks correct.

Thanks,

Alex

> +};
> +
>  int kvm_timer_enable(struct kvm_vcpu *vcpu)
>  {
>       struct arch_timer_cpu *timer = vcpu_timer(vcpu);
> @@ -1143,7 +1147,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
>       ret = kvm_vgic_map_phys_irq(vcpu,
>                                   map.direct_vtimer->host_timer_irq,
>                                   map.direct_vtimer->irq.irq,
> -                                 kvm_arch_timer_get_input_level);
> +                                 &arch_timer_irq_ops);
>       if (ret)
>               return ret;
>  
> @@ -1151,7 +1155,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
>               ret = kvm_vgic_map_phys_irq(vcpu,
>                                           map.direct_ptimer->host_timer_irq,
>                                           map.direct_ptimer->irq.irq,
> -                                         kvm_arch_timer_get_input_level);
> +                                         &arch_timer_irq_ops);
>       }
>  
>       if (ret)
> diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
> index 15b666200f0b..111bff47e471 100644
> --- a/arch/arm64/kvm/vgic/vgic.c
> +++ b/arch/arm64/kvm/vgic/vgic.c
> @@ -182,8 +182,8 @@ bool vgic_get_phys_line_level(struct vgic_irq *irq)
>  
>       BUG_ON(!irq->hw);
>  
> -     if (irq->get_input_level)
> -             return irq->get_input_level(irq->intid);
> +     if (irq->ops && irq->ops->get_input_level)
> +             return irq->ops->get_input_level(irq->intid);
>  
>       WARN_ON(irq_get_irqchip_state(irq->host_irq,
>                                     IRQCHIP_STATE_PENDING,
> @@ -480,7 +480,7 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, 
> unsigned int intid,
>  /* @irq->irq_lock must be held */
>  static int kvm_vgic_map_irq(struct kvm_vcpu *vcpu, struct vgic_irq *irq,
>                           unsigned int host_irq,
> -                         bool (*get_input_level)(int vindid))
> +                         struct irq_ops *ops)
>  {
>       struct irq_desc *desc;
>       struct irq_data *data;
> @@ -500,7 +500,7 @@ static int kvm_vgic_map_irq(struct kvm_vcpu *vcpu, struct 
> vgic_irq *irq,
>       irq->hw = true;
>       irq->host_irq = host_irq;
>       irq->hwintid = data->hwirq;
> -     irq->get_input_level = get_input_level;
> +     irq->ops = ops;
>       return 0;
>  }
>  
> @@ -509,11 +509,11 @@ static inline void kvm_vgic_unmap_irq(struct vgic_irq 
> *irq)
>  {
>       irq->hw = false;
>       irq->hwintid = 0;
> -     irq->get_input_level = NULL;
> +     irq->ops = NULL;
>  }
>  
>  int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq,
> -                       u32 vintid, bool (*get_input_level)(int vindid))
> +                       u32 vintid, struct irq_ops *ops)
>  {
>       struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
>       unsigned long flags;
> @@ -522,7 +522,7 @@ int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned 
> int host_irq,
>       BUG_ON(!irq);
>  
>       raw_spin_lock_irqsave(&irq->irq_lock, flags);
> -     ret = kvm_vgic_map_irq(vcpu, irq, host_irq, get_input_level);
> +     ret = kvm_vgic_map_irq(vcpu, irq, host_irq, ops);
>       raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
>       vgic_put_irq(vcpu->kvm, irq);
>  
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index e45b26e8d479..e5f06df000f2 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -92,6 +92,21 @@ enum vgic_irq_config {
>       VGIC_CONFIG_LEVEL
>  };
>  
> +/*
> + * Per-irq ops overriding some common behavious.
> + *
> + * Always called in non-preemptible section and the functions can use
> + * kvm_arm_get_running_vcpu() to get the vcpu pointer for private IRQs.
> + */
> +struct irq_ops {
> +     /*
> +      * Callback function pointer to in-kernel devices that can tell us the
> +      * state of the input level of mapped level-triggered IRQ faster than
> +      * peaking into the physical GIC.
> +      */
> +     bool (*get_input_level)(int vintid);
> +};
> +
>  struct vgic_irq {
>       raw_spinlock_t irq_lock;        /* Protects the content of the struct */
>       struct list_head lpi_list;      /* Used to link all LPIs together */
> @@ -129,16 +144,7 @@ struct vgic_irq {
>       u8 group;                       /* 0 == group 0, 1 == group 1 */
>       enum vgic_irq_config config;    /* Level or edge */
>  
> -     /*
> -      * Callback function pointer to in-kernel devices that can tell us the
> -      * state of the input level of mapped level-triggered IRQ faster than
> -      * peaking into the physical GIC.
> -      *
> -      * Always called in non-preemptible section and the functions can use
> -      * kvm_arm_get_running_vcpu() to get the vcpu pointer for private
> -      * IRQs.
> -      */
> -     bool (*get_input_level)(int vintid);
> +     struct irq_ops *ops;
>  
>       void *owner;                    /* Opaque pointer to reserve an 
> interrupt
>                                          for in-kernel devices. */
> @@ -355,7 +361,7 @@ void kvm_vgic_init_cpu_hardware(void);
>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid,
>                       bool level, void *owner);
>  int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq,
> -                       u32 vintid, bool (*get_input_level)(int vindid));
> +                       u32 vintid, struct irq_ops *ops);
>  int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid);
>  bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid);
>  
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to