diff mbox series

[RFC,31/52] i386/cpu: Use CPUState.topo to replace X86CPUTopoInfo to get topology info

Message ID 20230213095035.158240-32-zhao1.liu@linux.intel.com
State New
Headers show
Series Introduce hybrid CPU topology | expand

Commit Message

Zhao Liu Feb. 13, 2023, 9:50 a.m. UTC
From: Zhao Liu <zhao1.liu@intel.com>

X86CPUTopoInfo is associated with the APIC ID, and strictly speaking, it
represents the topology levels and topology information of the APIC ID.

While CPUState.topo (TopologyState) represents the specific topology
information of the current CPU.

For smp topology, the topology information in X86CPUTopoInfo is same as
CPUState.topo, but it may be different for hybrid topology.

Therefore, X86CPUTopoInfo should be used for APIC ID related work, and
CPUState.topo should be preferred in general CPU topology related use
cases.

Co-Developed-by: Zhuocheng Ding <zhuocheng.ding@intel.com>
Signed-off-by: Zhuocheng Ding <zhuocheng.ding@intel.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 target/i386/cpu.c | 33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)
diff mbox series

Patch

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 2188097c3ee1..f626d74639ed 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -387,6 +387,7 @@  static void encode_topo_cpuid8000001e(X86CPU *cpu, X86CPUTopoInfo *topo_info,
                                       uint32_t *eax, uint32_t *ebx,
                                       uint32_t *ecx, uint32_t *edx)
 {
+    CPUState *cs = CPU(cpu);
     X86CPUTopoIDs topo_ids;
 
     x86_topo_ids_from_apicid(cpu->apic_id, topo_info, &topo_ids);
@@ -407,7 +408,7 @@  static void encode_topo_cpuid8000001e(X86CPU *cpu, X86CPUTopoInfo *topo_info,
      *  NOTE: CoreId is already part of apic_id. Just use it. We can
      *  use all the 8 bits to represent the core_id here.
      */
-    *ebx = ((topo_info->threads_per_core - 1) << 8) | (topo_ids.core_id & 0xFF);
+    *ebx = ((cs->topo.threads_per_core - 1) << 8) | (topo_ids.core_id & 0xFF);
 
     /*
      * CPUID_Fn8000001E_ECX [Node Identifiers] (NodeId)
@@ -431,7 +432,7 @@  static void encode_topo_cpuid8000001e(X86CPU *cpu, X86CPUTopoInfo *topo_info,
      * NodeId is combination of node and socket_id which is already decoded
      * in apic_id. Just use it by shifting.
      */
-    *ecx = ((topo_info->dies_per_pkg - 1) << 8) |
+    *ecx = ((cs->topo.dies_per_socket - 1) << 8) |
            ((cpu->apic_id >> apicid_die_offset(topo_info)) & 0xFF);
 
     *edx = 0;
@@ -5257,15 +5258,12 @@  void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
     uint32_t limit;
     uint32_t signature[3];
     X86CPUTopoInfo topo_info;
-    uint32_t cpus_per_pkg;
 
     topo_info.dies_per_pkg = cs->topo.dies_per_socket;
     topo_info.modules_per_die = cs->topo.clusters_per_die;
     topo_info.cores_per_module = cs->topo.cores_per_cluster;
     topo_info.threads_per_core = cs->topo.threads_per_core;
 
-    cpus_per_pkg = cs->topo.threads_per_socket;
-
     /* Calculate & apply limits for different index ranges */
     if (index >= 0xC0000000) {
         limit = env->cpuid_xlevel2;
@@ -5301,8 +5299,8 @@  void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
             *ecx |= CPUID_EXT_OSXSAVE;
         }
         *edx = env->features[FEAT_1_EDX];
-        if (cpus_per_pkg > 1) {
-            *ebx |= cpus_per_pkg << 16;
+        if (cs->topo.threads_per_socket > 1) {
+            *ebx |= cs->topo.threads_per_socket << 16;
             *edx |= CPUID_HT;
         }
         if (!cpu->enable_pmu) {
@@ -5339,9 +5337,8 @@  void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
              */
             if (*eax & 31) {
                 int host_vcpus_per_cache = 1 + ((*eax & 0x3FFC000) >> 14);
-                int vcpus_per_socket = cpus_per_pkg;
-                int cores_per_socket = cpus_per_pkg /
-                                       topo_info.threads_per_core;
+                int vcpus_per_socket = cs->topo.threads_per_socket;
+                int cores_per_socket = cs->topo.cores_per_socket;
                 if (cores_per_socket > 1) {
                     *eax &= ~0xFC000000;
                     *eax |= (pow2ceil(cores_per_socket) - 1) << 26;
@@ -5473,12 +5470,12 @@  void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         switch (count) {
         case 0:
             *eax = apicid_core_offset(&topo_info);
-            *ebx = topo_info.threads_per_core;
+            *ebx = cs->topo.threads_per_core;
             *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
             break;
         case 1:
             *eax = apicid_pkg_offset(&topo_info);
-            *ebx = cpus_per_pkg;
+            *ebx = cs->topo.threads_per_socket;
             *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
             break;
         default:
@@ -5509,17 +5506,17 @@  void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         switch (count) {
         case 0:
             *eax = apicid_core_offset(&topo_info);
-            *ebx = topo_info.threads_per_core;
+            *ebx = cs->topo.threads_per_core;
             *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
             break;
         case 1:
             *eax = apicid_die_offset(&topo_info);
-            *ebx = cpus_per_pkg / topo_info.dies_per_pkg;
+            *ebx = cs->topo.threads_per_socket / cs->topo.dies_per_socket;
             *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
             break;
         case 2:
             *eax = apicid_pkg_offset(&topo_info);
-            *ebx = cpus_per_pkg;
+            *ebx = cs->topo.threads_per_socket;
             *ecx |= CPUID_TOPOLOGY_LEVEL_DIE;
             break;
         default:
@@ -5744,7 +5741,7 @@  void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
          * discards multiple thread information if it is set.
          * So don't set it here for Intel to make Linux guests happy.
          */
-        if (cpus_per_pkg > 1) {
+        if (cs->topo.threads_per_socket > 1) {
             if (env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1 ||
                 env->cpuid_vendor2 != CPUID_VENDOR_INTEL_2 ||
                 env->cpuid_vendor3 != CPUID_VENDOR_INTEL_3) {
@@ -5806,7 +5803,7 @@  void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
              *eax |= (cpu_x86_virtual_addr_width(env) << 8);
         }
         *ebx = env->features[FEAT_8000_0008_EBX];
-        if (cpus_per_pkg > 1) {
+        if (cs->topo.threads_per_socket > 1) {
             /*
              * Bits 15:12 is "The number of bits in the initial
              * Core::X86::Apic::ApicId[ApicId] value that indicate
@@ -5814,7 +5811,7 @@  void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
              * Bits 7:0 is "The number of threads in the package is NC+1"
              */
             *ecx = (apicid_pkg_offset(&topo_info) << 12) |
-                   (cpus_per_pkg - 1);
+                   (cs->topo.threads_per_socket - 1);
         } else {
             *ecx = 0;
         }