diff mbox

[Xen-devel,v9,05/10] xen/arm: physical irq follow virtual irq

Message ID 53D67D83.1010406@linaro.org
State Not Applicable, archived
Headers show

Commit Message

Julien Grall July 28, 2014, 4:42 p.m. UTC
On 07/28/2014 05:20 PM, Stefano Stabellini wrote:
> On Mon, 28 Jul 2014, Julien Grall wrote:
>> Hi stefano,
>>
>> On 07/24/2014 06:33 PM, Stefano Stabellini wrote:
>>> +void arch_move_irqs(struct vcpu *v)
>>> +{
>>> +    const cpumask_t *cpu_mask = cpumask_of(v->processor);
>>> +    struct domain *d = v->domain;
>>> +    struct pending_irq *p;
>>> +    struct vcpu *v_target;
>>> +    int i;
>>> +
>>> +    for ( i = 32; i < d->arch.vgic.nr_lines; i++ )
>>
>> Sorry, I didn't spot this error until now.
>>
>> For the VGIC nr_lines contains the number of *SPIs* rather on the GIC
>> structure it's the number of IRQs... the name is very confusing. I have
>> a patch to rename nr_lines into nr_spis, along with adding a macro
>> vgic_number_lines.
> 
> I couldn't parse this sentence.

Sorry it was not very clear.

> I guess you are saying that vgic.nr_lines doesn't represent the number
> of spis?

Yes. In the VGIC structure nr_lines = number of SPIs.

On GIC structure nr_lines = number of IRQs.

>> I plan to send it which my device passthrough patch series. As the patch
>> may help you. It may be better if you carry the patch.
> 
> Please append it here so I can have a look.

commit 534bdbbbd65b10f2780898bda2db5cdfc892dc34
Author: Julien Grall <julien.grall@linaro.org>
Date:   Fri Jul 18 12:25:18 2014 +0100

    xen/arm: vgic: Rename nr_lines into nr_spis
    
    The field nr_lines in the arch_domain vgic structure contains the number of
    SPIs for the emulated GIC. Using the nr_lines make confusion with the GIC
    code, where it means the number of IRQs. This can lead to coding error.
    
    Also introduce vgic_nr_lines to get the number of IRQ handled by the emulated
    GIC.
    
    Signed-off-by: Julien Grall <julien.grall@linaro.org>


Regards,

Comments

Stefano Stabellini Aug. 1, 2014, 5:22 p.m. UTC | #1
On Mon, 28 Jul 2014, Julien Grall wrote:
> On 07/28/2014 05:20 PM, Stefano Stabellini wrote:
> > On Mon, 28 Jul 2014, Julien Grall wrote:
> >> Hi stefano,
> >>
> >> On 07/24/2014 06:33 PM, Stefano Stabellini wrote:
> >>> +void arch_move_irqs(struct vcpu *v)
> >>> +{
> >>> +    const cpumask_t *cpu_mask = cpumask_of(v->processor);
> >>> +    struct domain *d = v->domain;
> >>> +    struct pending_irq *p;
> >>> +    struct vcpu *v_target;
> >>> +    int i;
> >>> +
> >>> +    for ( i = 32; i < d->arch.vgic.nr_lines; i++ )
> >>
> >> Sorry, I didn't spot this error until now.
> >>
> >> For the VGIC nr_lines contains the number of *SPIs* rather on the GIC
> >> structure it's the number of IRQs... the name is very confusing. I have
> >> a patch to rename nr_lines into nr_spis, along with adding a macro
> >> vgic_number_lines.
> > 
> > I couldn't parse this sentence.
> 
> Sorry it was not very clear.
> 
> > I guess you are saying that vgic.nr_lines doesn't represent the number
> > of spis?
> 
> Yes. In the VGIC structure nr_lines = number of SPIs.
> 
> On GIC structure nr_lines = number of IRQs.

Wait a second. If in the vgic struct, nr_lines = number of SPIs, then
the code in this patch is correct as it is, isn't it?



> >> I plan to send it which my device passthrough patch series. As the patch
> >> may help you. It may be better if you carry the patch.
> > 
> > Please append it here so I can have a look.
> 
> commit 534bdbbbd65b10f2780898bda2db5cdfc892dc34
> Author: Julien Grall <julien.grall@linaro.org>
> Date:   Fri Jul 18 12:25:18 2014 +0100
> 
>     xen/arm: vgic: Rename nr_lines into nr_spis
>     
>     The field nr_lines in the arch_domain vgic structure contains the number of
>     SPIs for the emulated GIC. Using the nr_lines make confusion with the GIC
>     code, where it means the number of IRQs. This can lead to coding error.
>     
>     Also introduce vgic_nr_lines to get the number of IRQ handled by the emulated
>     GIC.
>     
>     Signed-off-by: Julien Grall <julien.grall@linaro.org>
> 
> diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
> index 19b2167..ee4f6ca 100644
> --- a/xen/arch/arm/gic-v2.c
> +++ b/xen/arch/arm/gic-v2.c
> @@ -432,8 +432,6 @@ static int gicv2v_setup(struct domain *d)
>          d->arch.vgic.cbase = GUEST_GICC_BASE;
>      }
>  
> -    d->arch.vgic.nr_lines = 0;
> -
>      /*
>       * Map the gic virtual cpu interface in the gic cpu interface
>       * region of the guest.
> diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
> index ae31dbf..fbda349 100644
> --- a/xen/arch/arm/vgic-v2.c
> +++ b/xen/arch/arm/vgic-v2.c
> @@ -54,7 +54,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info)
>          /* No secure world support for guests. */
>          vgic_lock(v);
>          *r = ( (v->domain->max_vcpus << 5) & GICD_TYPE_CPUS )
> -            |( ((v->domain->arch.vgic.nr_lines / 32)) & GICD_TYPE_LINES );
> +            |( ((v->domain->arch.vgic.nr_spis / 32)) & GICD_TYPE_LINES );
>          vgic_unlock(v);
>          return 1;
>      case GICD_IIDR:
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index 9f7ed4d..3204131 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -59,13 +59,10 @@ int domain_vgic_init(struct domain *d)
> 
>  
>      d->arch.vgic.ctlr = 0;
>  
> -    /* Currently nr_lines in vgic and gic doesn't have the same meanings
> -     * Here nr_lines = number of SPIs
> -     */
>      if ( is_hardware_domain(d) )
> -        d->arch.vgic.nr_lines = gic_number_lines() - 32;
> +        d->arch.vgic.nr_spis = gic_number_lines() - 32;
>      else
> -        d->arch.vgic.nr_lines = 0; /* We don't need SPIs for the guest */
> +        d->arch.vgic.nr_spis = 0; /* We don't need SPIs for the guest */
>  
>      switch ( gic_hw_version() )
>      {
> @@ -83,11 +80,11 @@ int domain_vgic_init(struct domain *d)
>          return -ENOMEM;
>  
>      d->arch.vgic.pending_irqs =
> -        xzalloc_array(struct pending_irq, d->arch.vgic.nr_lines);
> +        xzalloc_array(struct pending_irq, d->arch.vgic.nr_spis);
>      if ( d->arch.vgic.pending_irqs == NULL )
>          return -ENOMEM;
>  
> -    for (i=0; i<d->arch.vgic.nr_lines; i++)
> +    for (i=0; i<d->arch.vgic.nr_spis; i++)
>      {
>          INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].inflight);
>          INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].lr_queue);
> @@ -230,7 +227,7 @@ void arch_move_irqs(struct vcpu *v)
>      struct vcpu *v_target;
>      int i;
>  
> -    for ( i = 32; i < d->arch.vgic.nr_lines; i++ )
> +    for ( i = 32; i < d->arch.vgic.nr_spis; i++ )
>      {
>          v_target = vgic_get_target_vcpu(v, i);
>          p = irq_to_pending(v_target, i);
> @@ -354,7 +351,7 @@ int vgic_to_sgi(struct vcpu *v, register_t sgir, enum gic_sgi_mode irqmode, int
>  struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq)
>  {
>      struct pending_irq *n;
> -    /* Pending irqs allocation strategy: the first vgic.nr_lines irqs
> +    /* Pending irqs allocation strategy: the first vgic.nr_spis irqs
>       * are used for SPIs; the rests are used for per cpu irqs */
>      if ( irq < 32 )
>          n = &v->arch.vgic.pending_irqs[irq];
> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
> index 32d0554..5719fe5 100644
> --- a/xen/include/asm-arm/domain.h
> +++ b/xen/include/asm-arm/domain.h
> @@ -89,7 +89,7 @@ struct arch_domain
>           */
>          spinlock_t lock;
>          int ctlr;
> -        int nr_lines; /* Number of SPIs */
> +        int nr_spis; /* Number of SPIs */
>          struct vgic_irq_rank *shared_irqs;
>          /*
>           * SPIs are domain global, SGIs and PPIs are per-VCPU and stored in
> diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
> index 5d6a8ad..b94de8c 100644
> --- a/xen/include/asm-arm/vgic.h
> +++ b/xen/include/asm-arm/vgic.h
> @@ -101,7 +101,7 @@ struct vgic_ops {
>  };
>  
>  /* Number of ranks of interrupt registers for a domain */
> -#define DOMAIN_NR_RANKS(d) (((d)->arch.vgic.nr_lines+31)/32)
> +#define DOMAIN_NR_RANKS(d) (((d)->arch.vgic.nr_spis+31)/32)
>  
>  #define vgic_lock(v)   spin_lock_irq(&(v)->domain->arch.vgic.lock)
>  #define vgic_unlock(v) spin_unlock_irq(&(v)->domain->arch.vgic.lock)
> @@ -155,6 +155,8 @@ enum gic_sgi_mode;
>   */
>  #define REG_RANK_INDEX(b, n, s) ((((n) >> s) & ((b)-1)) % 32)
>  
> +#define vgic_num_irqs(d)        ((d)->arch.vgic.nr_spis + 32)
> +
>  extern int domain_vgic_init(struct domain *d);
>  extern void domain_vgic_free(struct domain *d);
>  extern int vcpu_vgic_init(struct vcpu *v);
> 
> Regards,
> 
> 
> -- 
> Julien Grall
>
Julien Grall Aug. 1, 2014, 5:54 p.m. UTC | #2
Hi Stefano,

On 01/08/14 18:22, Stefano Stabellini wrote:
> On Mon, 28 Jul 2014, Julien Grall wrote:
>> On 07/28/2014 05:20 PM, Stefano Stabellini wrote:
>>> On Mon, 28 Jul 2014, Julien Grall wrote:
>>>> Hi stefano,
>>>>
>>>> On 07/24/2014 06:33 PM, Stefano Stabellini wrote:
>>>>> +void arch_move_irqs(struct vcpu *v)
>>>>> +{
>>>>> +    const cpumask_t *cpu_mask = cpumask_of(v->processor);
>>>>> +    struct domain *d = v->domain;
>>>>> +    struct pending_irq *p;
>>>>> +    struct vcpu *v_target;
>>>>> +    int i;
>>>>> +
>>>>> +    for ( i = 32; i < d->arch.vgic.nr_lines; i++ )
>>>>
>>>> Sorry, I didn't spot this error until now.
>>>>
>>>> For the VGIC nr_lines contains the number of *SPIs* rather on the GIC
>>>> structure it's the number of IRQs... the name is very confusing. I have
>>>> a patch to rename nr_lines into nr_spis, along with adding a macro
>>>> vgic_number_lines.
>>>
>>> I couldn't parse this sentence.
>>
>> Sorry it was not very clear.
>>
>>> I guess you are saying that vgic.nr_lines doesn't represent the number
>>> of spis?
>>
>> Yes. In the VGIC structure nr_lines = number of SPIs.
>>
>> On GIC structure nr_lines = number of IRQs.
>
> Wait a second. If in the vgic struct, nr_lines = number of SPIs, then
> the code in this patch is correct as it is, isn't it?

No because your loop starts at 32 and you check against vgic.nr_lines.

The loop should be:

for ( i = 32; i < (d->arch.vgic.nr_lines + 32); i++ )

Otherwise you will forget to migrate the last 32 SPIs.

Regards,
Stefano Stabellini Aug. 1, 2014, 5:58 p.m. UTC | #3
On Fri, 1 Aug 2014, Julien Grall wrote:
> Hi Stefano,
> 
> On 01/08/14 18:22, Stefano Stabellini wrote:
> > On Mon, 28 Jul 2014, Julien Grall wrote:
> > > On 07/28/2014 05:20 PM, Stefano Stabellini wrote:
> > > > On Mon, 28 Jul 2014, Julien Grall wrote:
> > > > > Hi stefano,
> > > > > 
> > > > > On 07/24/2014 06:33 PM, Stefano Stabellini wrote:
> > > > > > +void arch_move_irqs(struct vcpu *v)
> > > > > > +{
> > > > > > +    const cpumask_t *cpu_mask = cpumask_of(v->processor);
> > > > > > +    struct domain *d = v->domain;
> > > > > > +    struct pending_irq *p;
> > > > > > +    struct vcpu *v_target;
> > > > > > +    int i;
> > > > > > +
> > > > > > +    for ( i = 32; i < d->arch.vgic.nr_lines; i++ )
> > > > > 
> > > > > Sorry, I didn't spot this error until now.
> > > > > 
> > > > > For the VGIC nr_lines contains the number of *SPIs* rather on the GIC
> > > > > structure it's the number of IRQs... the name is very confusing. I
> > > > > have
> > > > > a patch to rename nr_lines into nr_spis, along with adding a macro
> > > > > vgic_number_lines.
> > > > 
> > > > I couldn't parse this sentence.
> > > 
> > > Sorry it was not very clear.
> > > 
> > > > I guess you are saying that vgic.nr_lines doesn't represent the number
> > > > of spis?
> > > 
> > > Yes. In the VGIC structure nr_lines = number of SPIs.
> > > 
> > > On GIC structure nr_lines = number of IRQs.
> > 
> > Wait a second. If in the vgic struct, nr_lines = number of SPIs, then
> > the code in this patch is correct as it is, isn't it?
> 
> No because your loop starts at 32 and you check against vgic.nr_lines.
> 
> The loop should be:
> 
> for ( i = 32; i < (d->arch.vgic.nr_lines + 32); i++ )
> 
> Otherwise you will forget to migrate the last 32 SPIs.

Sorry, obviously I didn't think it through.

For simplicity I think it is best if I just make this change.

If you are going to base your series on this one, you might as well
cleanup this line too in your patch?
Julien Grall Aug. 1, 2014, 6 p.m. UTC | #4
On 01/08/14 18:58, Stefano Stabellini wrote:
> On Fri, 1 Aug 2014, Julien Grall wrote:
>> Hi Stefano,
>>
>> On 01/08/14 18:22, Stefano Stabellini wrote:
>>> On Mon, 28 Jul 2014, Julien Grall wrote:
>>>> On 07/28/2014 05:20 PM, Stefano Stabellini wrote:
>>>>> On Mon, 28 Jul 2014, Julien Grall wrote:
>>>>>> Hi stefano,
>>>>>>
>>>>>> On 07/24/2014 06:33 PM, Stefano Stabellini wrote:
>>>>>>> +void arch_move_irqs(struct vcpu *v)
>>>>>>> +{
>>>>>>> +    const cpumask_t *cpu_mask = cpumask_of(v->processor);
>>>>>>> +    struct domain *d = v->domain;
>>>>>>> +    struct pending_irq *p;
>>>>>>> +    struct vcpu *v_target;
>>>>>>> +    int i;
>>>>>>> +
>>>>>>> +    for ( i = 32; i < d->arch.vgic.nr_lines; i++ )
>>>>>>
>>>>>> Sorry, I didn't spot this error until now.
>>>>>>
>>>>>> For the VGIC nr_lines contains the number of *SPIs* rather on the GIC
>>>>>> structure it's the number of IRQs... the name is very confusing. I
>>>>>> have
>>>>>> a patch to rename nr_lines into nr_spis, along with adding a macro
>>>>>> vgic_number_lines.
>>>>>
>>>>> I couldn't parse this sentence.
>>>>
>>>> Sorry it was not very clear.
>>>>
>>>>> I guess you are saying that vgic.nr_lines doesn't represent the number
>>>>> of spis?
>>>>
>>>> Yes. In the VGIC structure nr_lines = number of SPIs.
>>>>
>>>> On GIC structure nr_lines = number of IRQs.
>>>
>>> Wait a second. If in the vgic struct, nr_lines = number of SPIs, then
>>> the code in this patch is correct as it is, isn't it?
>>
>> No because your loop starts at 32 and you check against vgic.nr_lines.
>>
>> The loop should be:
>>
>> for ( i = 32; i < (d->arch.vgic.nr_lines + 32); i++ )
>>
>> Otherwise you will forget to migrate the last 32 SPIs.
>
> Sorry, obviously I didn't think it through.
>
> For simplicity I think it is best if I just make this change.
>
> If you are going to base your series on this one, you might as well
> cleanup this line too in your patch?

It's fine for me.

Regards,
diff mbox

Patch

diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 19b2167..ee4f6ca 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -432,8 +432,6 @@  static int gicv2v_setup(struct domain *d)
         d->arch.vgic.cbase = GUEST_GICC_BASE;
     }
 
-    d->arch.vgic.nr_lines = 0;
-
     /*
      * Map the gic virtual cpu interface in the gic cpu interface
      * region of the guest.
diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index ae31dbf..fbda349 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -54,7 +54,7 @@  static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info)
         /* No secure world support for guests. */
         vgic_lock(v);
         *r = ( (v->domain->max_vcpus << 5) & GICD_TYPE_CPUS )
-            |( ((v->domain->arch.vgic.nr_lines / 32)) & GICD_TYPE_LINES );
+            |( ((v->domain->arch.vgic.nr_spis / 32)) & GICD_TYPE_LINES );
         vgic_unlock(v);
         return 1;
     case GICD_IIDR:
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 9f7ed4d..3204131 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -59,13 +59,10 @@  int domain_vgic_init(struct domain *d)

 
     d->arch.vgic.ctlr = 0;
 
-    /* Currently nr_lines in vgic and gic doesn't have the same meanings
-     * Here nr_lines = number of SPIs
-     */
     if ( is_hardware_domain(d) )
-        d->arch.vgic.nr_lines = gic_number_lines() - 32;
+        d->arch.vgic.nr_spis = gic_number_lines() - 32;
     else
-        d->arch.vgic.nr_lines = 0; /* We don't need SPIs for the guest */
+        d->arch.vgic.nr_spis = 0; /* We don't need SPIs for the guest */
 
     switch ( gic_hw_version() )
     {
@@ -83,11 +80,11 @@  int domain_vgic_init(struct domain *d)
         return -ENOMEM;
 
     d->arch.vgic.pending_irqs =
-        xzalloc_array(struct pending_irq, d->arch.vgic.nr_lines);
+        xzalloc_array(struct pending_irq, d->arch.vgic.nr_spis);
     if ( d->arch.vgic.pending_irqs == NULL )
         return -ENOMEM;
 
-    for (i=0; i<d->arch.vgic.nr_lines; i++)
+    for (i=0; i<d->arch.vgic.nr_spis; i++)
     {
         INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].inflight);
         INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].lr_queue);
@@ -230,7 +227,7 @@  void arch_move_irqs(struct vcpu *v)
     struct vcpu *v_target;
     int i;
 
-    for ( i = 32; i < d->arch.vgic.nr_lines; i++ )
+    for ( i = 32; i < d->arch.vgic.nr_spis; i++ )
     {
         v_target = vgic_get_target_vcpu(v, i);
         p = irq_to_pending(v_target, i);
@@ -354,7 +351,7 @@  int vgic_to_sgi(struct vcpu *v, register_t sgir, enum gic_sgi_mode irqmode, int
 struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq)
 {
     struct pending_irq *n;
-    /* Pending irqs allocation strategy: the first vgic.nr_lines irqs
+    /* Pending irqs allocation strategy: the first vgic.nr_spis irqs
      * are used for SPIs; the rests are used for per cpu irqs */
     if ( irq < 32 )
         n = &v->arch.vgic.pending_irqs[irq];
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index 32d0554..5719fe5 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -89,7 +89,7 @@  struct arch_domain
          */
         spinlock_t lock;
         int ctlr;
-        int nr_lines; /* Number of SPIs */
+        int nr_spis; /* Number of SPIs */
         struct vgic_irq_rank *shared_irqs;
         /*
          * SPIs are domain global, SGIs and PPIs are per-VCPU and stored in
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index 5d6a8ad..b94de8c 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -101,7 +101,7 @@  struct vgic_ops {
 };
 
 /* Number of ranks of interrupt registers for a domain */
-#define DOMAIN_NR_RANKS(d) (((d)->arch.vgic.nr_lines+31)/32)
+#define DOMAIN_NR_RANKS(d) (((d)->arch.vgic.nr_spis+31)/32)
 
 #define vgic_lock(v)   spin_lock_irq(&(v)->domain->arch.vgic.lock)
 #define vgic_unlock(v) spin_unlock_irq(&(v)->domain->arch.vgic.lock)
@@ -155,6 +155,8 @@  enum gic_sgi_mode;
  */
 #define REG_RANK_INDEX(b, n, s) ((((n) >> s) & ((b)-1)) % 32)
 
+#define vgic_num_irqs(d)        ((d)->arch.vgic.nr_spis + 32)
+
 extern int domain_vgic_init(struct domain *d);
 extern void domain_vgic_free(struct domain *d);
 extern int vcpu_vgic_init(struct vcpu *v);