mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
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:
parent
0ac34b614b
commit
2150c7c9f7
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2416,6 +2416,7 @@ virHostCPUGetThreadsPerSubcore;
|
||||
virHostCPUHasBitmap;
|
||||
virHostCPUReadSignature;
|
||||
virHostCPUStatsAssign;
|
||||
virHostCPUX86GetCPUID;
|
||||
|
||||
|
||||
# util/virhostmem.h
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user