This will be needed directly in the QEMU driver in a later patch.
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
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);
}
virHostCPUHasBitmap;
virHostCPUReadSignature;
virHostCPUStatsAssign;
+virHostCPUX86GetCPUID;
# util/virhostmem.h
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
+}
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);