mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
tools/hvmloader: Fix non-deterministic cpuid()
hvmloader's cpuid() implementation deviates from Xen's in that the value
passed on ecx is unspecified. This means that when used on leaves that
implement subleaves it's unspecified which one you get; though it's more
than likely an invalid one.
Import Xen's implementation so there are no surprises.
Fixes: 318ac791f9 ("Add utilities needed for SMBIOS generation to hvmloader")
Signed-off-by: Alejandro Vallejo <alejandro.vallejo@cloud.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
b2e8c8f420
commit
cc47813c4a
2 files changed
+24
-12
No files matched your search
@@ -267,15 +267,6 @@ memcmp(const void *s1, const void *s2, unsigned n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
|
||||
{
|
||||
asm volatile (
|
||||
"cpuid"
|
||||
: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
|
||||
: "0" (idx) );
|
||||
}
|
||||
|
||||
static const char hex_digits[] = "0123456789abcdef";
|
||||
|
||||
/* Write a two-character hex representation of 'byte' to digits[].
|
||||
|
||||
@@ -184,9 +184,30 @@ int uart_exists(uint16_t uart_base);
|
||||
int lpt_exists(uint16_t lpt_base);
|
||||
int hpet_exists(unsigned long hpet_base);
|
||||
|
||||
/* Do cpuid instruction, with operation 'idx' */
|
||||
void cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx,
|
||||
uint32_t *ecx, uint32_t *edx);
|
||||
/* Some CPUID calls want 'count' to be placed in ecx */
|
||||
static inline void cpuid_count(
|
||||
uint32_t leaf,
|
||||
uint32_t subleaf,
|
||||
uint32_t *eax,
|
||||
uint32_t *ebx,
|
||||
uint32_t *ecx,
|
||||
uint32_t *edx)
|
||||
{
|
||||
asm volatile ( "cpuid"
|
||||
: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
|
||||
: "a" (leaf), "c" (subleaf) );
|
||||
}
|
||||
|
||||
/* Generic CPUID function (subleaf 0) */
|
||||
static inline void cpuid(
|
||||
uint32_t leaf,
|
||||
uint32_t *eax,
|
||||
uint32_t *ebx,
|
||||
uint32_t *ecx,
|
||||
uint32_t *edx)
|
||||
{
|
||||
cpuid_count(leaf, 0, eax, ebx, ecx, edx);
|
||||
}
|
||||
|
||||
/* Read the TSC register. */
|
||||
static inline uint64_t rdtsc(void)
|
||||
|
||||