This keeps compatibility on machine-types pc-1.1 and lower, and prints a warning in case the requested configuration won't get the correct topology.
Changes v1 -> v2: - Move code to cpu.c - keep using cpu_index on *-user - Use SMP.contiguous_apic_ids global property - Prints warning in case the compatibility mode will expose incorrect topology Signed-off-by: Eduardo Habkost <ehabk...@redhat.com> --- hw/pc_piix.c | 4 ++++ target-i386/cpu.c | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 0c0096f..f073916 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -375,6 +375,10 @@ static QEMUMachine pc_machine_v1_2 = { .driver = "qxl",\ .property = "vgamem_mb",\ .value = stringify(8),\ + },{\ + .driver = "SMP",\ + .property = "contiguous_apic_ids",\ + .value = "true",\ } static QEMUMachine pc_machine_v1_1 = { diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 1703373..ea6c7a7 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -23,9 +23,11 @@ #include "cpu.h" #include "kvm.h" +#include "topology.h" #ifndef CONFIG_USER_ONLY -#include "sysemu.h" +#include "hw/qdev.h" +#include "cpus.h" #endif #include "qemu-option.h" @@ -492,13 +494,37 @@ static x86_def_t builtin_x86_defs[] = { }, }; +#ifdef CONFIG_USER_ONLY unsigned int apic_id_for_cpu(int cpu_index) { - /* right now APIC ID == CPU index. this will eventually change to use - * the CPU topology configuration properly - */ + /* *-user doesn't have any CPU topology settings, just use the CPU index */ return cpu_index; } +#else +unsigned int apic_id_for_cpu(int cpu_index) +{ + const char *contig; + bool is_contiguous; + unsigned int correct_id; + static bool warned = false; + + /* Global property SMP.contiguous_apic_ids=true will keep compatibility + * with the old (broken) behavior when calculating APIC IDs + */ + contig = qemu_global_get("SMP", "contiguous_apic_ids"); + is_contiguous = contig && !strcmp(contig, "true"); + correct_id = topo_apicid_for_cpu(smp_cores, smp_threads, cpu_index); + if (is_contiguous) { + if (cpu_index != correct_id && !warned) { + fprintf(stderr, "warning: CPU topology in compatibility mode, it will not match the requested topology\n"); + warned = true; + } + return cpu_index; + } else { + return correct_id; + } +} +#endif static int cpu_x86_fill_model_id(char *str) { -- 1.7.11.2