mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-09 14:35: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
|
static inline void
|
||||||
cpuidCall(virCPUx86CPUID *cpuid)
|
cpuidCall(virCPUx86CPUID *cpuid)
|
||||||
{
|
{
|
||||||
# if __x86_64__
|
virHostCPUX86GetCPUID(cpuid->eax_in,
|
||||||
asm("xor %%ebx, %%ebx;" /* clear the other registers as some cpuid */
|
cpuid->ecx_in,
|
||||||
"xor %%edx, %%edx;" /* functions may use them as additional arguments */
|
&cpuid->eax,
|
||||||
"cpuid;"
|
&cpuid->ebx,
|
||||||
: "=a" (cpuid->eax),
|
&cpuid->ecx,
|
||||||
"=b" (cpuid->ebx),
|
&cpuid->edx);
|
||||||
"=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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2416,6 +2416,7 @@ virHostCPUGetThreadsPerSubcore;
|
|||||||
virHostCPUHasBitmap;
|
virHostCPUHasBitmap;
|
||||||
virHostCPUReadSignature;
|
virHostCPUReadSignature;
|
||||||
virHostCPUStatsAssign;
|
virHostCPUStatsAssign;
|
||||||
|
virHostCPUX86GetCPUID;
|
||||||
|
|
||||||
|
|
||||||
# util/virhostmem.h
|
# util/virhostmem.h
|
||||||
|
@ -1583,3 +1583,61 @@ virHostCPUGetHaltPollTime(pid_t pid,
|
|||||||
|
|
||||||
return 0;
|
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,
|
int virHostCPUGetHaltPollTime(pid_t pid,
|
||||||
unsigned long long *haltPollSuccess,
|
unsigned long long *haltPollSuccess,
|
||||||
unsigned long long *haltPollFail);
|
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