Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) };