[libvirt PATCH v3 09/13] util: pull CPUID helper function out of CPU driver

Daniel P. Berrangé berrange at redhat.com
Fri Dec 10 16:47:09 UTC 2021


This will be needed directly in the QEMU driver in a later patch.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/cpu/cpu_x86.c        | 34 +++++------------------
 src/libvirt_private.syms |  1 +
 src/util/virhostcpu.c    | 58 ++++++++++++++++++++++++++++++++++++++++
 src/util/virhostcpu.h    |  7 +++++
 4 files changed, 72 insertions(+), 28 deletions(-)

diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 0b2ff82d40..5cb9caef8a 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2377,34 +2377,12 @@ virCPUx86DataCheckFeature(const virCPUData *data,
 static inline void
 cpuidCall(virCPUx86CPUID *cpuid)
 {
-# if __x86_64__
-    asm("xor %%ebx, %%ebx;" /* clear the other registers as some cpuid */
-        "xor %%edx, %%edx;" /* functions may use them as additional arguments */
-        "cpuid;"
-        : "=a" (cpuid->eax),
-          "=b" (cpuid->ebx),
-          "=c" (cpuid->ecx),
-          "=d" (cpuid->edx)
-        : "a" (cpuid->eax_in),
-          "c" (cpuid->ecx_in));
-# else
-    /* we need to avoid direct use of ebx for CPUID output as it is used
-     * for global offset table on i386 with -fPIC
-     */
-    asm("push %%ebx;"
-        "xor %%ebx, %%ebx;" /* clear the other registers as some cpuid */
-        "xor %%edx, %%edx;" /* functions may use them as additional arguments */
-        "cpuid;"
-        "mov %%ebx, %1;"
-        "pop %%ebx;"
-        : "=a" (cpuid->eax),
-          "=r" (cpuid->ebx),
-          "=c" (cpuid->ecx),
-          "=d" (cpuid->edx)
-        : "a" (cpuid->eax_in),
-          "c" (cpuid->ecx_in)
-        : "cc");
-# endif
+    virHostCPUX86GetCPUID(cpuid->eax_in,
+                          cpuid->ecx_in,
+                          &cpuid->eax,
+                          &cpuid->ebx,
+                          &cpuid->ecx,
+                          &cpuid->edx);
 }
 
 
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index da27ee7b53..53262e25b7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2417,6 +2417,7 @@ virHostCPUGetThreadsPerSubcore;
 virHostCPUHasBitmap;
 virHostCPUReadSignature;
 virHostCPUStatsAssign;
+virHostCPUX86GetCPUID;
 
 
 # util/virhostmem.h
diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
index 54e2462a95..a07c00a0e9 100644
--- a/src/util/virhostcpu.c
+++ b/src/util/virhostcpu.c
@@ -1583,3 +1583,61 @@ virHostCPUGetHaltPollTime(pid_t pid,
 
     return 0;
 }
+
+void
+virHostCPUX86GetCPUID(uint32_t leaf G_GNUC_UNUSED,
+                      uint32_t extended G_GNUC_UNUSED,
+                      uint32_t *eax,
+                      uint32_t *ebx,
+                      uint32_t *ecx,
+                      uint32_t *edx)
+{
+#if defined(__i386__) || defined(__x86_64__)
+    uint32_t out[4];
+# if __x86_64__
+    asm("xor %%ebx, %%ebx;" /* clear the other registers as some cpuid */
+        "xor %%edx, %%edx;" /* functions may use them as additional arguments */
+        "cpuid;"
+        : "=a" (out[0]),
+          "=b" (out[1]),
+          "=c" (out[2]),
+          "=d" (out[3])
+        : "a" (leaf),
+          "c" (extended));
+# else
+    /* we need to avoid direct use of ebx for CPUID output as it is used
+     * for global offset table on i386 with -fPIC
+     */
+    asm("push %%ebx;"
+        "xor %%ebx, %%ebx;" /* clear the other registers as some cpuid */
+        "xor %%edx, %%edx;" /* functions may use them as additional arguments */
+        "cpuid;"
+        "mov %%ebx, %1;"
+        "pop %%ebx;"
+        : "=a" (out[0]),
+          "=r" (out[1]),
+          "=c" (out[2]),
+          "=d" (out[3])
+        : "a" (leaf),
+          "c" (extended)
+        : "cc");
+# endif
+    if (eax)
+        *eax = out[0];
+    if (ebx)
+        *ebx = out[1];
+    if (ecx)
+        *ecx = out[2];
+    if (edx)
+        *edx = out[3];
+#else
+    if (eax)
+        *eax = 0;
+    if (ebx)
+        *ebx = 0;
+    if (ecx)
+        *ecx = 0;
+    if (edx)
+        *edx = 0;
+#endif
+}
diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h
index a96dd5afba..86a231daa2 100644
--- a/src/util/virhostcpu.h
+++ b/src/util/virhostcpu.h
@@ -89,3 +89,10 @@ int virHostCPUGetSignature(char **signature);
 int virHostCPUGetHaltPollTime(pid_t pid,
                               unsigned long long *haltPollSuccess,
                               unsigned long long *haltPollFail);
+
+void virHostCPUX86GetCPUID(uint32_t leaf,
+                           uint32_t extended,
+                           uint32_t *eax,
+                           uint32_t *ebx,
+                           uint32_t *ecx,
+                           uint32_t *edx);
-- 
2.33.1




More information about the libvir-list mailing list