hv:cpuid:refine cpuid_subleaf interface

There's a corner case:
When want to get CPUID.01H:EDX value,
may have the following code snippet:

uint32_t unused,edx;
cpuid_subleaf(0x1U, 0x0U, &unused, &unused, &unused, &edx);

while in cpuid_subleaf:
*eax = leaf;
*ecx = subleaf;
eax and ecx point to the same location,
When deep into asm_cpuid, it's input value will be 0x0U and 0x0U.
but the expected input value is 0x1U and 0x0U.

This case will return CPUID.00H:EDX, which is the wrong answer.

Tracked-On: #4526

Signed-off-by: Junming Liu <junming.liu@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Junming Liu 2020-08-14 00:55:23 +08:00 committed by wenlingz
parent 5e07e99dcc
commit 23d9c13c41
1 changed files with 3 additions and 13 deletions

View File

@ -131,25 +131,15 @@
#define CPUID_EXTEND_INVA_TSC 0x80000007U
#define CPUID_EXTEND_ADDRESS_SIZE 0x80000008U
static inline void asm_cpuid(uint32_t *eax, uint32_t *ebx,
static inline void cpuid_subleaf(uint32_t leaf, uint32_t subleaf,
uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
{
/* Execute CPUID instruction and save results */
asm volatile("cpuid":"=a"(*eax), "=b"(*ebx),
"=c"(*ecx), "=d"(*edx)
: "0" (*eax), "2" (*ecx)
: "a" (leaf), "c" (subleaf)
: "memory");
}
static inline void cpuid_subleaf(uint32_t leaf, uint32_t subleaf,
uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
{
*eax = leaf;
*ecx = subleaf;
asm_cpuid(eax, ebx, ecx, edx);
}
#endif /* CPUID_H_ */