> From: Qemu-arm [mailto:qemu-arm-bounces+salil.mehta=huawei....@nongnu.org] > On Behalf Of Yanan Wang > Sent: Sunday, May 16, 2021 11:29 AM > To: Peter Maydell <peter.mayd...@linaro.org>; Andrew Jones > <drjo...@redhat.com>; Michael S . Tsirkin <m...@redhat.com>; Igor Mammedov > <imamm...@redhat.com>; Shannon Zhao <shannon.zha...@gmail.com>; Alistair > Francis <alistair.fran...@wdc.com>; David Gibson > <da...@gibson.dropbear.id.au>; qemu-devel@nongnu.org; qemu-...@nongnu.org > Cc: Song Bao Hua (Barry Song) <song.bao....@hisilicon.com>; zhukeqian > <zhukeqi...@huawei.com>; yangyicong <yangyic...@huawei.com>; Zengtao (B) > <prime.z...@hisilicon.com>; Wanghaibin (D) <wanghaibin.w...@huawei.com>; > yuzenghui <yuzeng...@huawei.com>; Paolo Bonzini <pbonz...@redhat.com>; > Philippe Mathieu-Daudé <phi...@redhat.com> > Subject: [RFC PATCH v3 6/9] hw/arm/virt-acpi-build: Use possible cpus in > generation of MADT > > When building ACPI tables regarding CPUs we should always build > them for the number of possible CPUs, not the number of present > CPUs. So we create gicc nodes in MADT for possible cpus and then > ensure only the present CPUs are marked ENABLED. Furthermore, it > also needed if we are going to support CPU hotplug in the future.
Hi Yanan, Yes, these changes are part of the QEMU patch-set I floated last year. Link: https://www.mail-archive.com/qemu-devel@nongnu.org/msg712018.html Perhaps I am missing something, but how this patch is related to the vcpu topology support? Thanks > > Co-developed-by: Andrew Jones <drjo...@redhat.com> > Signed-off-by: Andrew Jones <drjo...@redhat.com> > Co-developed-by: Ying Fang <fangyi...@huawei.com> > Signed-off-by: Ying Fang <fangyi...@huawei.com> > Co-developed-by: Yanan Wang <wangyana...@huawei.com> > Signed-off-by: Yanan Wang <wangyana...@huawei.com> > --- > hw/arm/virt-acpi-build.c | 29 +++++++++++++++++++++++++---- > 1 file changed, 25 insertions(+), 4 deletions(-) > > diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c > index a2d8e87616..4d64aeb865 100644 > --- a/hw/arm/virt-acpi-build.c > +++ b/hw/arm/virt-acpi-build.c > @@ -481,6 +481,9 @@ build_madt(GArray *table_data, BIOSLinker *linker, > VirtMachineState *vms) > const int *irqmap = vms->irqmap; > AcpiMadtGenericDistributor *gicd; > AcpiMadtGenericMsiFrame *gic_msi; > + MachineClass *mc = MACHINE_GET_CLASS(vms); > + const CPUArchIdList *possible_cpus = > mc->possible_cpu_arch_ids(MACHINE(vms)); > + bool pmu; > int i; > > acpi_data_push(table_data, sizeof(AcpiMultipleApicTable)); > @@ -491,11 +494,21 @@ build_madt(GArray *table_data, BIOSLinker *linker, > VirtMachineState *vms) > gicd->base_address = cpu_to_le64(memmap[VIRT_GIC_DIST].base); > gicd->version = vms->gic_version; > > - for (i = 0; i < MACHINE(vms)->smp.cpus; i++) { > + for (i = 0; i < possible_cpus->len; i++) { > AcpiMadtGenericCpuInterface *gicc = acpi_data_push(table_data, > sizeof(*gicc)); > ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i)); > > + /* > + * PMU should have been either implemented for all CPUs or not, > + * so we only get information from the first CPU, which could > + * represent the others. > + */ > + if (i == 0) { > + pmu = arm_feature(&armcpu->env, ARM_FEATURE_PMU); > + } > + assert(!armcpu || arm_feature(&armcpu->env, ARM_FEATURE_PMU) == pmu); > + > gicc->type = ACPI_APIC_GENERIC_CPU_INTERFACE; > gicc->length = sizeof(*gicc); > if (vms->gic_version == 2) { > @@ -504,11 +517,19 @@ build_madt(GArray *table_data, BIOSLinker *linker, > VirtMachineState *vms) > gicc->gicv_base_address = > cpu_to_le64(memmap[VIRT_GIC_VCPU].base); > } > gicc->cpu_interface_number = cpu_to_le32(i); > - gicc->arm_mpidr = cpu_to_le64(armcpu->mp_affinity); > + gicc->arm_mpidr = cpu_to_le64(possible_cpus->cpus[i].arch_id); > gicc->uid = cpu_to_le32(i); > - gicc->flags = cpu_to_le32(ACPI_MADT_GICC_ENABLED); > > - if (arm_feature(&armcpu->env, ARM_FEATURE_PMU)) { > + /* > + * ACPI spec says that LAPIC entry for non present CPU may be > + * omitted from MADT or it must be marked as disabled. Here we > + * choose to also keep the disabled ones in MADT. > + */ > + if (possible_cpus->cpus[i].cpu != NULL) { > + gicc->flags = cpu_to_le32(ACPI_MADT_GICC_ENABLED); > + } > + > + if (pmu) { > gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ)); > } > if (vms->virt) { > -- > 2.19.1 >