diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h index dff49fce11..48b43edc5a 100644 --- a/include/hw/i386/topology.h +++ b/include/hw/i386/topology.h @@ -62,6 +62,8 @@ typedef struct X86CPUTopoInfo { unsigned threads_per_core; } X86CPUTopoInfo; +#define CPU_TOPO_LEVEL_INVALID CPU_TOPO_LEVEL_MAX + /* * CPUTopoLevel is the general i386 topology hierarchical representation, * ordered by increasing hierarchical relationship. @@ -69,7 +71,6 @@ typedef struct X86CPUTopoInfo { * or AMD (CPUID[0x80000026]). */ enum CPUTopoLevel { - CPU_TOPO_LEVEL_INVALID, CPU_TOPO_LEVEL_SMT, CPU_TOPO_LEVEL_CORE, CPU_TOPO_LEVEL_MODULE, diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 3baa95481f..ca13cf66a7 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -370,20 +370,21 @@ static void encode_topo_cpuid1f(CPUX86State *env, uint32_t count, uint32_t *ecx, uint32_t *edx) { X86CPU *cpu = env_archcpu(env); - unsigned long level, next_level; + unsigned long level, base_level, next_level; uint32_t num_threads_next_level, offset_next_level; - assert(count + 1 < CPU_TOPO_LEVEL_MAX); + assert(count <= CPU_TOPO_LEVEL_PACKAGE); /* * Find the No.(count + 1) topology level in avail_cpu_topo bitmap. - * The search starts from bit 1 (CPU_TOPO_LEVEL_INVALID + 1). + * The search starts from bit 0 (CPU_TOPO_LEVEL_SMT). */ - level = CPU_TOPO_LEVEL_INVALID; + level = CPU_TOPO_LEVEL_SMT; + base_level = level; for (int i = 0; i <= count; i++) { level = find_next_bit(env->avail_cpu_topo, CPU_TOPO_LEVEL_PACKAGE, - level + 1); + base_level); /* * CPUID[0x1f] doesn't explicitly encode the package level, @@ -394,6 +395,8 @@ static void encode_topo_cpuid1f(CPUX86State *env, uint32_t count, level = CPU_TOPO_LEVEL_INVALID; break; } + /* Search the next level. */ + base_level = level + 1; } if (level == CPU_TOPO_LEVEL_INVALID) {