hyper-v: avoid tsc calibration
Subsystems (2)
cover hyper-v: avoid tsc calibration
TSC calibration on virtual machines is always error prone. It was found that in nested environments Gen2 instances may get stuck on boot. As Hyper-V hosts provide us with all the required information we can easily avoid calibration. This is already done for other hypervisors (KVM, Vmware).
Vitaly Kuznetsov (2):
hyper-v: check frequency MSRs presence according to the specification
hyper-v: read TSC frequency from a synthetic MSR
arch/x86/include/uapi/asm/hyperv.h | 15 ++++++--------- arch/x86/kernel/cpu/mshyperv.c | 18 +++++++++++++++++- 2 files changed, 23 insertions(+), 10 deletions(-)
Signature · 1 line
2.9.4
PATCH 1/2 hyper-v: check frequency MSRs presence according to the specification
Hyper-V TLFS specifies two bits which should be checked before accessing frequency MSRs:
- AccessFrequencyMsrs (BIT(11) in EAX) which indicates if we have access to frequency MSRs.
- FrequencyMsrsAvailable (BIT(8) in EDX) which indicates is these MSRs are present.
Rename and specify these bits accordingly.
--- arch/x86/include/uapi/asm/hyperv.h | 15 ++++++--------- arch/x86/kernel/cpu/mshyperv.c | 3 ++- 2 files changed, 8 insertions(+), 10 deletions(-)
arch/x86/include/uapi/asm/hyperv.h +6 -9
@@ -34,16 +34,10 @@#define HV_X64_MSR_REFERENCE_TSC 0x40000021/* -* There is a single feature flag that signifies the presence of the MSR -* that can be used to retrieve both the local APIC Timer frequency as -* well as the TSC frequency. +* There is a single feature flag that signifies if the partition has access +* to MSRs with local APIC and TSC frequencies. */ - -/* Local APIC timer frequency MSR (HV_X64_MSR_APIC_FREQUENCY) is available */ -#define HV_X64_MSR_APIC_FREQUENCY_AVAILABLE (1 << 11) - -/* TSC frequency MSR (HV_X64_MSR_TSC_FREQUENCY) is available */ -#define HV_X64_MSR_TSC_FREQUENCY_AVAILABLE (1 << 11) +#define HV_X64_ACCESS_FREQUENCY_MSRS (1 << 11)/* * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM
@@ -73,6 +67,9 @@*/ #define HV_X64_MSR_STAT_PAGES_AVAILABLE (1 << 8) +/* Frequency MSRs available */ +#define HV_FEATURE_FREQUENCY_MSRS_AVAILABELE (1 << 8) +/* Crash MSR available */ #define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10)
arch/x86/kernel/cpu/mshyperv.c +2 -1
@@ -194,7 +194,8 @@ static void __init ms_hyperv_init_platform(void) }#ifdef CONFIG_X86_LOCAL_APIC -if (ms_hyperv.features &HV_X64_MSR_APIC_FREQUENCY_AVAILABLE ) { +if (ms_hyperv.features &HV_X64_ACCESS_FREQUENCY_MSRS && + ms_hyperv.misc_features &HV_FEATURE_FREQUENCY_MSRS_AVAILABELE ) {/* * Get the APIC frequency. */
Signature · 1 line
2.9.4
Re: [PATCH 1/2] hyper-v: check frequency MSRs presence according to the specification
arch/x86/include/uapi/asm/hyperv.h line 71
Quoted 10 lines · Vitaly Kuznetsov
arch/x86/include/uapi/asm/hyperv.h +3
-0+#define HV_X64_ACCESS_FREQUENCY_MSRS (1 << 11)/* * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM @@ -73,6 +67,9 @@*/ #define HV_X64_MSR_STAT_PAGES_AVAILABLE (1 << 8) +/* Frequency MSRs available */ +#define HV_FEATURE_FREQUENCY_MSRS_AVAILABELE (1 << 8)
s/AVAILABELE/AVAILABLE/ please
Quoted 22 lines
arch/x86/include/uapi/asm/hyperv.h +1
-0+/* Crash MSR available */ #define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10)arch/x86/kernel/cpu/mshyperv.c +2
-1@@ -194,7 +194,8 @@ static void __init ms_hyperv_init_platform(void) }#ifdef CONFIG_X86_LOCAL_APIC -if (ms_hyperv.features &HV_X64_MSR_APIC_FREQUENCY_AVAILABLE ) { +if (ms_hyperv.features &HV_X64_ACCESS_FREQUENCY_MSRS && + ms_hyperv.misc_features &HV_FEATURE_FREQUENCY_MSRS_AVAILABELE ) {/* * Get the APIC frequency. */ Signature · 1 line
2.9.4
PATCH 2/2 hyper-v: read TSC frequency from a synthetic MSR
In reply to Vitaly KuznetsovIt was found that SMI_TRESHOLD of 50000 is not enough for Hyper-V guests in nested environment and falling back to counting jiffies is not an option for Gen2 guests as they don't have PIT. As Hyper-V provides TSC frequency in a synthetic MSR we can just use this information instead of doing a error prone calibration.
--- arch/x86/kernel/cpu/mshyperv.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
arch/x86/kernel/cpu/mshyperv.c +15 -0
@@ -161,6 +161,15 @@ static int hv_nmi_unknown(unsigned int val, struct pt_regs *regs) }#endif +static unsigned long hv_get_tsc_khz (void ) +{ +unsigned long freq; + +rdmsrl (HV_X64_MSR_TSC_FREQUENCY , freq); + +return freq/1000 ; +} +static void __init ms_hyperv_init_platform (void ) {int hv_host_info_eax;
@@ -193,6 +202,12 @@ static void __init ms_hyperv_init_platform(void) hv_host_info_edx >> 24, hv_host_info_edx & 0xFFFFFF); } +if (ms_hyperv.features &HV_X64_ACCESS_FREQUENCY_MSRS && + ms_hyperv.misc_features &HV_FEATURE_FREQUENCY_MSRS_AVAILABELE ) { + x86_platform.calibrate_tsc = hv_get_tsc_khz; + x86_platform.calibrate_cpu = hv_get_tsc_khz; + } +#ifdef CONFIG_X86_LOCAL_APIC if (ms_hyperv.features &HV_X64_ACCESS_FREQUENCY_MSRS && ms_hyperv.misc_features &HV_FEATURE_FREQUENCY_MSRS_AVAILABELE ) {
Signature · 1 line
2.9.4