^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * HyperV Detection code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2010, Novell, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/clocksource.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/hardirq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/kexec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/i8253.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/hypervisor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/hyperv-tlfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/mshyperv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/desc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/idtentry.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/irq_regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/i8259.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <asm/apic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <asm/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <asm/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <asm/nmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <clocksource/hyperv_timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct ms_hyperv_info ms_hyperv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) EXPORT_SYMBOL_GPL(ms_hyperv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #if IS_ENABLED(CONFIG_HYPERV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static void (*vmbus_handler)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static void (*hv_stimer0_handler)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static void (*hv_kexec_handler)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static void (*hv_crash_handler)(struct pt_regs *regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct pt_regs *old_regs = set_irq_regs(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) inc_irq_stat(irq_hv_callback_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (vmbus_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) vmbus_handler();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ack_APIC_irq();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) set_irq_regs(old_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int hv_setup_vmbus_irq(int irq, void (*handler)(void))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * The 'irq' argument is ignored on x86/x64 because a hard-coded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * interrupt vector is used for Hyper-V interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) vmbus_handler = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) void hv_remove_vmbus_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* We have no way to deallocate the interrupt gate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) vmbus_handler = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) EXPORT_SYMBOL_GPL(hv_setup_vmbus_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * Routines to do per-architecture handling of stimer0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * interrupts when in Direct Mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_stimer0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct pt_regs *old_regs = set_irq_regs(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) inc_irq_stat(hyperv_stimer0_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (hv_stimer0_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) hv_stimer0_handler();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) add_interrupt_randomness(HYPERV_STIMER0_VECTOR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ack_APIC_irq();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) set_irq_regs(old_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int hv_setup_stimer0_irq(int *irq, int *vector, void (*handler)(void))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) *vector = HYPERV_STIMER0_VECTOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) *irq = -1; /* Unused on x86/x64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) hv_stimer0_handler = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) EXPORT_SYMBOL_GPL(hv_setup_stimer0_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) void hv_remove_stimer0_irq(int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* We have no way to deallocate the interrupt gate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) hv_stimer0_handler = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) EXPORT_SYMBOL_GPL(hv_remove_stimer0_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) void hv_setup_kexec_handler(void (*handler)(void))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) hv_kexec_handler = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) EXPORT_SYMBOL_GPL(hv_setup_kexec_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) void hv_remove_kexec_handler(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) hv_kexec_handler = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) EXPORT_SYMBOL_GPL(hv_remove_kexec_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) hv_crash_handler = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) EXPORT_SYMBOL_GPL(hv_setup_crash_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) void hv_remove_crash_handler(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) hv_crash_handler = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) EXPORT_SYMBOL_GPL(hv_remove_crash_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #ifdef CONFIG_KEXEC_CORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static void hv_machine_shutdown(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (kexec_in_progress && hv_kexec_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) hv_kexec_handler();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Call hv_cpu_die() on all the CPUs, otherwise later the hypervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * corrupts the old VP Assist Pages and can crash the kexec kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (kexec_in_progress && hyperv_init_cpuhp > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) cpuhp_remove_state(hyperv_init_cpuhp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* The function calls stop_other_cpus(). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) native_machine_shutdown();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* Disable the hypercall page when there is only 1 active CPU. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (kexec_in_progress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) hyperv_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static void hv_machine_crash_shutdown(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (hv_crash_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) hv_crash_handler(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* The function calls crash_smp_send_stop(). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) native_machine_crash_shutdown(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* Disable the hypercall page when there is only 1 active CPU. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) hyperv_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #endif /* CONFIG_KEXEC_CORE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #endif /* CONFIG_HYPERV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static uint32_t __init ms_hyperv_platform(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) u32 eax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u32 hyp_signature[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (eax >= HYPERV_CPUID_MIN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) eax <= HYPERV_CPUID_MAX &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) !memcmp("Microsoft Hv", hyp_signature, 12))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static unsigned char hv_get_nmi_reason(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #ifdef CONFIG_X86_LOCAL_APIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * Prior to WS2016 Debug-VM sends NMIs to all CPUs which makes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * it dificult to process CHANNELMSG_UNLOAD in case of crash. Handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * unknown NMI on the first CPU which gets it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static int hv_nmi_unknown(unsigned int val, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static atomic_t nmi_cpu = ATOMIC_INIT(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (!unknown_nmi_panic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return NMI_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (atomic_cmpxchg(&nmi_cpu, -1, raw_smp_processor_id()) != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return NMI_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return NMI_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static unsigned long hv_get_tsc_khz(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) unsigned long freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) rdmsrl(HV_X64_MSR_TSC_FREQUENCY, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return freq / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #if defined(CONFIG_SMP) && IS_ENABLED(CONFIG_HYPERV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static void __init hv_smp_prepare_boot_cpu(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) native_smp_prepare_boot_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #if defined(CONFIG_X86_64) && defined(CONFIG_PARAVIRT_SPINLOCKS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) hv_init_spinlocks();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static void __init ms_hyperv_init_platform(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int hv_host_info_eax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int hv_host_info_ebx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int hv_host_info_ecx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) int hv_host_info_edx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #ifdef CONFIG_PARAVIRT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) pv_info.name = "Hyper-V";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * Extract the features and hints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ms_hyperv.features = cpuid_eax(HYPERV_CPUID_FEATURES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) pr_info("Hyper-V: features 0x%x, hints 0x%x, misc 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) ms_hyperv.features, ms_hyperv.hints, ms_hyperv.misc_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ms_hyperv.max_vp_index = cpuid_eax(HYPERV_CPUID_IMPLEMENT_LIMITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ms_hyperv.max_lp_index = cpuid_ebx(HYPERV_CPUID_IMPLEMENT_LIMITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) pr_debug("Hyper-V: max %u virtual processors, %u logical processors\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ms_hyperv.max_vp_index, ms_hyperv.max_lp_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * Extract host information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (cpuid_eax(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS) >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) HYPERV_CPUID_VERSION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) hv_host_info_eax = cpuid_eax(HYPERV_CPUID_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) hv_host_info_ebx = cpuid_ebx(HYPERV_CPUID_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) hv_host_info_ecx = cpuid_ecx(HYPERV_CPUID_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) hv_host_info_edx = cpuid_edx(HYPERV_CPUID_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) pr_info("Hyper-V Host Build:%d-%d.%d-%d-%d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) hv_host_info_eax, hv_host_info_ebx >> 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) hv_host_info_ebx & 0xFFFF, hv_host_info_ecx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) hv_host_info_edx >> 24, hv_host_info_edx & 0xFFFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) x86_platform.calibrate_tsc = hv_get_tsc_khz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) x86_platform.calibrate_cpu = hv_get_tsc_khz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) ms_hyperv.nested_features =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) cpuid_eax(HYPERV_CPUID_NESTED_FEATURES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * Hyper-V expects to get crash register data or kmsg when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * crash enlightment is available and system crashes. Set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * crash_kexec_post_notifiers to be true to make sure that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * calling crash enlightment interface before running kdump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) crash_kexec_post_notifiers = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) #ifdef CONFIG_X86_LOCAL_APIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * Get the APIC frequency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) u64 hv_lapic_frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) rdmsrl(HV_X64_MSR_APIC_FREQUENCY, hv_lapic_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) hv_lapic_frequency = div_u64(hv_lapic_frequency, HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) lapic_timer_period = hv_lapic_frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) pr_info("Hyper-V: LAPIC Timer Frequency: %#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) lapic_timer_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) register_nmi_handler(NMI_UNKNOWN, hv_nmi_unknown, NMI_FLAG_FIRST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) "hv_nmi_unknown");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) #ifdef CONFIG_X86_IO_APIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) no_timer_check = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) #if IS_ENABLED(CONFIG_HYPERV) && defined(CONFIG_KEXEC_CORE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) machine_ops.shutdown = hv_machine_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) machine_ops.crash_shutdown = hv_machine_crash_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) wrmsrl(HV_X64_MSR_TSC_INVARIANT_CONTROL, 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * Generation 2 instances don't support reading the NMI status from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * 0x61 port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (efi_enabled(EFI_BOOT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) x86_platform.get_nmi_reason = hv_get_nmi_reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * Hyper-V VMs have a PIT emulation quirk such that zeroing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * counter register during PIT shutdown restarts the PIT. So it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * continues to interrupt @18.2 HZ. Setting i8253_clear_counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * to false tells pit_shutdown() not to zero the counter so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * the PIT really is shutdown. Generation 2 VMs don't have a PIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * and setting this value has no effect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) i8253_clear_counter_on_shutdown = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) #if IS_ENABLED(CONFIG_HYPERV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * Setup the hook to get control post apic initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) x86_platform.apic_post_init = hyperv_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) hyperv_setup_mmu_ops();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* Setup the IDT for hypervisor callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_hyperv_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /* Setup the IDT for reenlightenment notifications */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (ms_hyperv.features & HV_ACCESS_REENLIGHTENMENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) alloc_intr_gate(HYPERV_REENLIGHTENMENT_VECTOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) asm_sysvec_hyperv_reenlightenment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* Setup the IDT for stimer0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) alloc_intr_gate(HYPERV_STIMER0_VECTOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) asm_sysvec_hyperv_stimer0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) # ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) smp_ops.smp_prepare_boot_cpu = hv_smp_prepare_boot_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) # endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * Hyper-V doesn't provide irq remapping for IO-APIC. To enable x2apic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * set x2apic destination mode to physcial mode when x2apic is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * and Hyper-V IOMMU driver makes sure cpus assigned with IO-APIC irqs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * have 8-bit APIC id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) # ifdef CONFIG_X86_X2APIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (x2apic_supported())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) x2apic_phys = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) # endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* Register Hyper-V specific clocksource */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) hv_init_clocksource();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * TSC should be marked as unstable only after Hyper-V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * clocksource has been initialized. This ensures that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * stability of the sched_clock is not altered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!(ms_hyperv.features & HV_ACCESS_TSC_INVARIANT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) mark_tsc_unstable("running on Hyper-V");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) const __initconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .name = "Microsoft Hyper-V",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .detect = ms_hyperv_platform,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .type = X86_HYPER_MS_HYPERV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) .init.init_platform = ms_hyperv_init_platform,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) };