x86/hyperv changes for v4.13
Subsystems (2)
Linus,
Please pull the latest x86-hyperv-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-hyperv-for-linus
# HEAD: 71c2a2d0a81f096a2932fccb39a500116fece554 x86/hyperv: Read TSC frequency from a synthetic MSR
Avoid boot time TSC calibration on Hyper-V hosts, to improve calibration robustness. (Vitaly Kuznetsov)
Thanks,
Ingo
------------------>
Vitaly Kuznetsov (2):
x86/hyperv: Check frequency MSRs presence according to the specification x86/hyperv: 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(-)
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_AVAILABLE (1 << 8) +/* Crash MSR available */ #define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10)
arch/x86/kernel/cpu/mshyperv.c +17 -1
@@ -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,8 +202,15 @@ 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_AVAILABLE ) { + 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_MSR_APIC_FREQUENCY_AVAILABLE ) { +if (ms_hyperv.features &HV_X64_ACCESS_FREQUENCY_MSRS && + ms_hyperv.misc_features &HV_FEATURE_FREQUENCY_MSRS_AVAILABLE ) {/* * Get the APIC frequency. */