From 7d83abb4a586cc862965197b6db41b3ef45c81ec Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 14 Aug 2018 10:41:21 +0800 Subject: [PATCH] HV: Add the emulation of CPUID with 0x16 leaf The CPUID with 0x16 leaf can report the CPU hz and it is faster. And this mechanism is widely used in Linux kernel.(native_calibrate_cpu). As this is not supported on APL, currently sos adds the cpu_khz callback in pv_cpu_ops to read the cpu frequency. This is quite hack. (In fact HV leverages the cpuid with 0x40000010 leaf). If it is emulated, the sos and guest os can use the cpuid to obtain the corresponding cpu_khz. Then the cpu_khz in pv_cpu_ops can be removed. V2: Simple the logic of adding unsupported cpuid level entry after the CPUID 0x16 is emulated. Initialize the vcpuid_entry explicitly with zero for the unsupported cpuid. Signed-off-by: Zhao Yakui Acked-by: Eddie Dong --- hypervisor/arch/x86/cpuid.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/hypervisor/arch/x86/cpuid.c b/hypervisor/arch/x86/cpuid.c index 50be98a52..f968477d6 100644 --- a/hypervisor/arch/x86/cpuid.c +++ b/hypervisor/arch/x86/cpuid.c @@ -119,6 +119,21 @@ static void init_vcpuid_entry(__unused struct vm *vm, entry->ecx = 0U; entry->edx = 0U; break; + case 0x16U: + if (boot_cpu_data.cpuid_level >= 0x16U) { + /* call the cpuid when 0x16 is supported */ + cpuid_subleaf(leaf, subleaf, + &entry->eax, &entry->ebx, + &entry->ecx, &entry->edx); + } else { + /* Use the tsc to derive the emulated 0x16U cpuid. */ + entry->eax = (uint32_t) (tsc_khz / 1000U); + entry->ebx = entry->eax; + /* Bus frequency: hard coded to 100M */ + entry->ecx = 100U; + entry->edx = 0U; + } + break; /* * Leaf 0x40000000 @@ -173,6 +188,11 @@ int set_vcpuid_entries(struct vm *vm) uint32_t i, j; init_vcpuid_entry(vm, 0U, 0U, 0U, &entry); + if (boot_cpu_data.cpuid_level < 0x16U) { + /* The cpuid with zero leaf returns the max level. + * Emulate that the 0x16U is supported */ + entry.eax = 0x16U; + } result = set_vcpuid_entry(vm, &entry); if (result != 0) { return result;