Add the Processor Properties Topology Table (PPTT) to present CPU topology information to the guest. A three-level cpu topology is built in accord with the linux kernel currently does.
Tested-by: Jiajie Li <lijiaji...@huawei.com> Signed-off-by: Ying Fang <fangyi...@huawei.com> --- hw/arm/virt-acpi-build.c | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index bb91152fe2..38d50ce66c 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -436,6 +436,50 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) vms->oem_table_id); } +static void +build_pptt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) +{ + int pptt_start = table_data->len; + int uid = 0, cpus = 0, socket = 0; + MachineState *ms = MACHINE(vms); + unsigned int smp_cores = ms->smp.cores; + unsigned int smp_threads = ms->smp.threads; + + acpi_data_push(table_data, sizeof(AcpiTableHeader)); + + for (socket = 0; cpus < ms->possible_cpus->len; socket++) { + uint32_t socket_offset = table_data->len - pptt_start; + int core; + + build_socket_hierarchy(table_data, 0, socket); + + for (core = 0; core < smp_cores; core++) { + uint32_t core_offset = table_data->len - pptt_start; + int thread; + + if (smp_threads <= 1) { + build_processor_hierarchy(table_data, + ACPI_PPTT_ACPI_PROCESSOR_ID_VALID | + ACPI_PPTT_ACPI_LEAF_NODE, + socket_offset, uid++); + } else { + build_processor_hierarchy(table_data, + ACPI_PPTT_ACPI_PROCESSOR_ID_VALID, + socket_offset, core); + for (thread = 0; thread < smp_threads; thread++) { + build_thread_hierarchy(table_data, core_offset, uid++); + } + } + } + cpus += smp_cores * smp_threads; + } + + build_header(linker, table_data, + (void *)(table_data->data + pptt_start), "PPTT", + table_data->len - pptt_start, 2, + vms->oem_id, vms->oem_table_id); +} + /* GTDT */ static void build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) @@ -688,6 +732,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) unsigned dsdt, xsdt; GArray *tables_blob = tables->table_data; MachineState *ms = MACHINE(vms); + bool cpu_topology_enabled = !vmc->no_cpu_topology; table_offsets = g_array_new(false, true /* clear */, sizeof(uint32_t)); @@ -707,6 +752,11 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) acpi_add_table(table_offsets, tables_blob); build_madt(tables_blob, tables->linker, vms); + if (ms->smp.cpus > 1 && cpu_topology_enabled) { + acpi_add_table(table_offsets, tables_blob); + build_pptt(tables_blob, tables->linker, vms); + } + acpi_add_table(table_offsets, tables_blob); build_gtdt(tables_blob, tables->linker, vms); -- 2.23.0