diff mbox series

[1/3] hw/intc/arm_gicv3: Move checking of redist-region-count to arm_gicv3_common_realize

Message ID 20210930150842.3810-2-peter.maydell@linaro.org
State Superseded
Headers show
Series arm_gicv3: Support multiple redistributor regions | expand

Commit Message

Peter Maydell Sept. 30, 2021, 3:08 p.m. UTC
The GICv3 devices have an array property redist-region-count.
Currently we check this for errors (bad values) in
gicv3_init_irqs_and_mmio(), just before we use it.  Move this error
checking to the arm_gicv3_common_realize() function, where we
sanity-check all of the other base-class properties. (This will
always be before gicv3_init_irqs_and_mmio() is called, because
that function is called in the subclass realize methods, after
they have called the parent-class realize.)

The motivation for this refactor is:
 * we would like to use the redist_region_count[] values in
   arm_gicv3_common_realize() in a subsequent patch, so we need
   to have already done the sanity-checking first
 * this removes the only use of the Error** argument to
   gicv3_init_irqs_and_mmio(), so we can remove some error-handling
   boilerplate

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/intc/arm_gicv3_common.h |  2 +-
 hw/intc/arm_gicv3.c                |  6 +-----
 hw/intc/arm_gicv3_common.c         | 26 +++++++++++++-------------
 hw/intc/arm_gicv3_kvm.c            |  6 +-----
 4 files changed, 16 insertions(+), 24 deletions(-)

-- 
2.20.1

Comments

Philippe Mathieu-Daudé Sept. 30, 2021, 9:54 p.m. UTC | #1
On 9/30/21 17:08, Peter Maydell wrote:
> The GICv3 devices have an array property redist-region-count.

> Currently we check this for errors (bad values) in

> gicv3_init_irqs_and_mmio(), just before we use it.  Move this error

> checking to the arm_gicv3_common_realize() function, where we

> sanity-check all of the other base-class properties. (This will

> always be before gicv3_init_irqs_and_mmio() is called, because

> that function is called in the subclass realize methods, after

> they have called the parent-class realize.)

> 

> The motivation for this refactor is:

>  * we would like to use the redist_region_count[] values in

>    arm_gicv3_common_realize() in a subsequent patch, so we need

>    to have already done the sanity-checking first

>  * this removes the only use of the Error** argument to

>    gicv3_init_irqs_and_mmio(), so we can remove some error-handling

>    boilerplate

> 

> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

> ---

>  include/hw/intc/arm_gicv3_common.h |  2 +-

>  hw/intc/arm_gicv3.c                |  6 +-----

>  hw/intc/arm_gicv3_common.c         | 26 +++++++++++++-------------

>  hw/intc/arm_gicv3_kvm.c            |  6 +-----

>  4 files changed, 16 insertions(+), 24 deletions(-)

> 

> diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h

> index aa4f0d67703..cb2b0d0ad45 100644

> --- a/include/hw/intc/arm_gicv3_common.h

> +++ b/include/hw/intc/arm_gicv3_common.h

> @@ -306,6 +306,6 @@ struct ARMGICv3CommonClass {

>  };

>  

>  void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,

> -                              const MemoryRegionOps *ops, Error **errp);

> +                              const MemoryRegionOps *ops);

>  

>  #endif

> diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c

> index 3f24707838c..bcf54a5f0a5 100644

> --- a/hw/intc/arm_gicv3.c

> +++ b/hw/intc/arm_gicv3.c

> @@ -393,11 +393,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp)

>          return;

>      }

>  

> -    gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops, &local_err);

> -    if (local_err) {

> -        error_propagate(errp, local_err);

> -        return;

> -    }

> +    gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops);

>  

>      gicv3_init_cpuif(s);

>  }

> diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c

> index 223db16feca..8e47809398b 100644

> --- a/hw/intc/arm_gicv3_common.c

> +++ b/hw/intc/arm_gicv3_common.c

> @@ -250,22 +250,11 @@ static const VMStateDescription vmstate_gicv3 = {

>  };

>  

>  void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,

> -                              const MemoryRegionOps *ops, Error **errp)

> +                              const MemoryRegionOps *ops)

>  {

>      SysBusDevice *sbd = SYS_BUS_DEVICE(s);

> -    int rdist_capacity = 0;

>      int i;

>  

> -    for (i = 0; i < s->nb_redist_regions; i++) {

> -        rdist_capacity += s->redist_region_count[i];

> -    }

> -    if (rdist_capacity < s->num_cpu) {

> -        error_setg(errp, "Capacity of the redist regions(%d) "

> -                   "is less than number of vcpus(%d)",

> -                   rdist_capacity, s->num_cpu);

> -        return;

> -    }

> -

>      /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.

>       * GPIO array layout is thus:

>       *  [0..N-1] spi

> @@ -308,7 +297,7 @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,

>  static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)

>  {

>      GICv3State *s = ARM_GICV3_COMMON(dev);

> -    int i;

> +    int i, rdist_capacity;

>  

>      /* revision property is actually reserved and currently used only in order

>       * to keep the interface compatible with GICv2 code, avoiding extra

> @@ -350,6 +339,17 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)

>          return;

>      }

>  

> +    rdist_capacity = 0;

> +    for (i = 0; i < s->nb_redist_regions; i++) {

> +        rdist_capacity += s->redist_region_count[i];

> +    }

> +    if (rdist_capacity < s->num_cpu) {

> +        error_setg(errp, "Capacity of the redist regions(%d) "

> +                   "is less than number of vcpus(%d)",

> +                   rdist_capacity, s->num_cpu);

> +        return;

> +    }

> +

>      s->cpu = g_new0(GICv3CPUState, s->num_cpu);

>  

>      for (i = 0; i < s->num_cpu; i++) {

> diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c

> index 5c09f00dec2..ab58c73306d 100644

> --- a/hw/intc/arm_gicv3_kvm.c

> +++ b/hw/intc/arm_gicv3_kvm.c

> @@ -787,11 +787,7 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)

>          return;

>      }

>  

> -    gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL, &local_err);

> -    if (local_err) {

> -        error_propagate(errp, local_err);

> -        return;

> -    }

> +    gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL);

>  

>      for (i = 0; i < s->num_cpu; i++) {

>          ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));

> 


The pattern make me think gicv3_init_irqs_and_mmio() should be
refactored as a ARMGICv3CommonClass::init_irqs_and_mmio handler,
called in arm_gicv3_common_realize().

Or maybe even have ARMGICv3CommonClass::irq_handler and
ARMGICv3CommonClass::ops set in each child class_init().
Peter Maydell Oct. 1, 2021, 9:18 a.m. UTC | #2
On Thu, 30 Sept 2021 at 22:54, Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
> The pattern make me think gicv3_init_irqs_and_mmio() should be

> refactored as a ARMGICv3CommonClass::init_irqs_and_mmio handler,

> called in arm_gicv3_common_realize().


That won't work because the two subclasses want to call it
with different arguments.

More generally, I find QEMU's class method infrastructure
sufficiently clunky that it is better avoided except in
the case where it's actually needed, ie where you have one
callsite that might have to deal with an object whose
exact type may vary such that you don't know which of the
methods you want and you need the dynamic-dispatch.
In this case that doesn't apply: both of the callsites of
gicv3_init_irqs_and_mmio() know exactly what function they
want to be calling (there is only one implementation), and
moreover both callsites are part of the GICv3 implementation
themselves, so this isn't about presenting a nice (or "nice")
external interface to other parts of QEMU.

-- PMM
Richard Henderson Oct. 1, 2021, 4:24 p.m. UTC | #3
On 9/30/21 11:08 AM, Peter Maydell wrote:
> The GICv3 devices have an array property redist-region-count.

> Currently we check this for errors (bad values) in

> gicv3_init_irqs_and_mmio(), just before we use it.  Move this error

> checking to the arm_gicv3_common_realize() function, where we

> sanity-check all of the other base-class properties. (This will

> always be before gicv3_init_irqs_and_mmio() is called, because

> that function is called in the subclass realize methods, after

> they have called the parent-class realize.)

> 

> The motivation for this refactor is:

>   * we would like to use the redist_region_count[] values in

>     arm_gicv3_common_realize() in a subsequent patch, so we need

>     to have already done the sanity-checking first

>   * this removes the only use of the Error** argument to

>     gicv3_init_irqs_and_mmio(), so we can remove some error-handling

>     boilerplate

> 

> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>

> ---


Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~
diff mbox series

Patch

diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
index aa4f0d67703..cb2b0d0ad45 100644
--- a/include/hw/intc/arm_gicv3_common.h
+++ b/include/hw/intc/arm_gicv3_common.h
@@ -306,6 +306,6 @@  struct ARMGICv3CommonClass {
 };
 
 void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
-                              const MemoryRegionOps *ops, Error **errp);
+                              const MemoryRegionOps *ops);
 
 #endif
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
index 3f24707838c..bcf54a5f0a5 100644
--- a/hw/intc/arm_gicv3.c
+++ b/hw/intc/arm_gicv3.c
@@ -393,11 +393,7 @@  static void arm_gic_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
+    gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops);
 
     gicv3_init_cpuif(s);
 }
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
index 223db16feca..8e47809398b 100644
--- a/hw/intc/arm_gicv3_common.c
+++ b/hw/intc/arm_gicv3_common.c
@@ -250,22 +250,11 @@  static const VMStateDescription vmstate_gicv3 = {
 };
 
 void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
-                              const MemoryRegionOps *ops, Error **errp)
+                              const MemoryRegionOps *ops)
 {
     SysBusDevice *sbd = SYS_BUS_DEVICE(s);
-    int rdist_capacity = 0;
     int i;
 
-    for (i = 0; i < s->nb_redist_regions; i++) {
-        rdist_capacity += s->redist_region_count[i];
-    }
-    if (rdist_capacity < s->num_cpu) {
-        error_setg(errp, "Capacity of the redist regions(%d) "
-                   "is less than number of vcpus(%d)",
-                   rdist_capacity, s->num_cpu);
-        return;
-    }
-
     /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
      * GPIO array layout is thus:
      *  [0..N-1] spi
@@ -308,7 +297,7 @@  void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
 static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
 {
     GICv3State *s = ARM_GICV3_COMMON(dev);
-    int i;
+    int i, rdist_capacity;
 
     /* revision property is actually reserved and currently used only in order
      * to keep the interface compatible with GICv2 code, avoiding extra
@@ -350,6 +339,17 @@  static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
         return;
     }
 
+    rdist_capacity = 0;
+    for (i = 0; i < s->nb_redist_regions; i++) {
+        rdist_capacity += s->redist_region_count[i];
+    }
+    if (rdist_capacity < s->num_cpu) {
+        error_setg(errp, "Capacity of the redist regions(%d) "
+                   "is less than number of vcpus(%d)",
+                   rdist_capacity, s->num_cpu);
+        return;
+    }
+
     s->cpu = g_new0(GICv3CPUState, s->num_cpu);
 
     for (i = 0; i < s->num_cpu; i++) {
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
index 5c09f00dec2..ab58c73306d 100644
--- a/hw/intc/arm_gicv3_kvm.c
+++ b/hw/intc/arm_gicv3_kvm.c
@@ -787,11 +787,7 @@  static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
+    gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL);
 
     for (i = 0; i < s->num_cpu; i++) {
         ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));