util: pull CPUID helper function out of CPU driver

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>
This commit is contained in:
Daniel P. Berrangé 2021-12-10 16:14:49 +00:00
parent 0ac34b614b
commit 2150c7c9f7
4 changed files with 72 additions and 28 deletions

View File

@ -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);
}

View File

@ -2416,6 +2416,7 @@ virHostCPUGetThreadsPerSubcore;
virHostCPUHasBitmap;
virHostCPUReadSignature;
virHostCPUStatsAssign;
virHostCPUX86GetCPUID;
# util/virhostmem.h

View File

@ -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
}

View File

@ -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);