[Xen-devel,v4,14/33] xen/arm: vgic: Correctly calculate GICD_TYPER.ITLinesNumber

Message ID 1426793399-6283-15-git-send-email-julien.grall@linaro.org
State New
Headers show

Commit Message

Julien Grall March 19, 2015, 7:29 p.m.
The formula of GICD_TYPER.ITLinesNumber is 32(N + 1).

As the number of SPIs suppported by the domain may not be a multiple of
32, we have to round up the number before using it.

At the same time remove the mask GICD_TYPE_LINES which is pointless.

Signed-off-by: Julien Grall <julien.grall@linaro.org>

---
    Changes in v4:
        - Patch added
---
 xen/arch/arm/vgic-v2.c | 2 +-
 xen/arch/arm/vgic-v3.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

Comments

Julien Grall March 31, 2015, 11:28 a.m. | #1
On 31/03/15 11:46, Ian Campbell wrote:
> On Thu, 2015-03-19 at 19:29 +0000, Julien Grall wrote:
>> The formula of GICD_TYPER.ITLinesNumber is 32(N + 1).
>>
>> As the number of SPIs suppported by the domain may not be a multiple of
>> 32, we have to round up the number before using it.
>>
>> At the same time remove the mask GICD_TYPE_LINES which is pointless.
> 
> I presume because something else has ensured that nr_spis is less than
> the maximum value represented by the mask?

The number of SPIs is validated in domain_vgic_init.

We would be in trouble in the IRQ guest injection if this number is too
high.

> 
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> 
> Acked-by: Ian Campbell <ian.campbell@citrix.com>

Thanks,

Patch

diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index 40619b2..b5a8f29 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -55,7 +55,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 - 1) << GICD_TYPE_CPUS_SHIFT) )
-            |( ((v->domain->arch.vgic.nr_spis / 32)) & GICD_TYPE_LINES );
+            | DIV_ROUND_UP(v->domain->arch.vgic.nr_spis, 32);
         vgic_unlock(v);
         return 1;
     case GICD_IIDR:
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index ec79c2a..96c1be8 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -700,7 +700,7 @@  static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info)
         if ( dabt.size != DABT_WORD ) goto bad_width;
         /* No secure world support for guests. */
         *r = ((ncpus - 1) << GICD_TYPE_CPUS_SHIFT |
-              ((v->domain->arch.vgic.nr_spis / 32) & GICD_TYPE_LINES));
+              DIV_ROUND_UP(v->domain->arch.vgic.nr_spis, 32));
 
         *r |= (irq_bits - 1) << GICD_TYPE_ID_BITS_SHIFT;