On Wed, Jun 13, 2018 at 10:48:41AM +0200, Eric Auger wrote: > With a VGICv3 KVM device, if the number of vcpus exceeds the > capacity of the legacy redistributor region (123 redistributors), > we now attempt to register a second redistributor region. Up to > 512 redistributors can fit in this latter on top of the 123 allowed > by the legacy redistributor region. > > Registering this second redistributor region is possible if the > host kernel supports the following VGICv3 KVM device group/attribute: > KVM_DEV_ARM_VGIC_GRP_ADDR/KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION. > > In case the host kernel does not support the registration of several > redistributor regions and the requested number of vcpus exceeds the > capacity of the legacy redistributor region, the GICv3 device > initialization fails with a proper error message and qemu exits. > > At the moment the max number of vcpus still is capped by the > virt machine class max_cpus. > > Signed-off-by: Eric Auger <eric.au...@redhat.com> > > --- > > v2 -> v3: > - remove spare space > --- > hw/arm/virt.c | 18 +++++++++++++++++- > 1 file changed, 17 insertions(+), 1 deletion(-) > > diff --git a/hw/arm/virt.c b/hw/arm/virt.c > index 5c02cc5..2a1c0fb 100644 > --- a/hw/arm/virt.c > +++ b/hw/arm/virt.c > @@ -528,6 +528,7 @@ static void create_gic(VirtMachineState *vms, qemu_irq > *pic) > SysBusDevice *gicbusdev; > const char *gictype; > int type = vms->gic_version, i; > + uint32_t nb_redist_regions = 0; > > gictype = (type == 3) ? gicv3_class_name() : gic_class_name(); > > @@ -547,14 +548,28 @@ static void create_gic(VirtMachineState *vms, qemu_irq > *pic) > vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE; > uint32_t redist0_count = MIN(smp_cpus, redist0_capacity); > > - qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1); > + nb_redist_regions = virt_gicv3_redist_region_count(vms); > + > + qdev_prop_set_uint32(gicdev, "len-redist-region-count", > + nb_redist_regions); > qdev_prop_set_uint32(gicdev, "redist-region-count[0]", > redist0_count); > + > + if (nb_redist_regions == 2) { > + uint32_t redist1_capacity = > + vms->memmap[VIRT_GIC_REDIST2].size / > GICV3_REDIST_SIZE; > + > + qdev_prop_set_uint32(gicdev, "redist-region-count[1]", > + MIN(smp_cpus - redist0_count, redist1_capacity)); > + } > } > qdev_init_nofail(gicdev); > gicbusdev = SYS_BUS_DEVICE(gicdev); > sysbus_mmio_map(gicbusdev, 0, vms->memmap[VIRT_GIC_DIST].base); > if (type == 3) { > sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_REDIST].base); > + if (nb_redist_regions == 2) { > + sysbus_mmio_map(gicbusdev, 2, > vms->memmap[VIRT_GIC_REDIST2].base); > + } > } else { > sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_CPU].base); > } > @@ -1350,6 +1365,7 @@ static void machvirt_init(MachineState *machine) > */ > if (vms->gic_version == 3) { > virt_max_cpus = vms->memmap[VIRT_GIC_REDIST].size / > GICV3_REDIST_SIZE; > + virt_max_cpus += vms->memmap[VIRT_GIC_REDIST2].size / > GICV3_REDIST_SIZE; > } else { > virt_max_cpus = GIC_NCPU; > } > -- > 2.5.5 > >
Reviewed-by: Andrew Jones <drjo...@redhat.com>