Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'hyperv-next-signed-20210831' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux

Pull hyperv updates from Wei Liu:

- make Hyper-V code arch-agnostic (Michael Kelley)

- fix sched_clock behaviour on Hyper-V (Ani Sinha)

- fix a fault when Linux runs as the root partition on MSHV (Praveen
Kumar)

- fix VSS driver (Vitaly Kuznetsov)

- cleanup (Sonia Sharma)

* tag 'hyperv-next-signed-20210831' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
hv_utils: Set the maximum packet size for VSS driver to the length of the receive buffer
Drivers: hv: Enable Hyper-V code to be built on ARM64
arm64: efi: Export screen_info
arm64: hyperv: Initialize hypervisor on boot
arm64: hyperv: Add panic handler
arm64: hyperv: Add Hyper-V hypercall and register access utilities
x86/hyperv: fix root partition faults when writing to VP assist page MSR
hv: hyperv.h: Remove unused inline functions
drivers: hv: Decouple Hyper-V clock/timer code from VMbus drivers
x86/hyperv: add comment describing TSC_INVARIANT_CONTROL MSR setting bit 0
Drivers: hv: Move Hyper-V misc functionality to arch-neutral code
Drivers: hv: Add arch independent default functions for some Hyper-V handlers
Drivers: hv: Make portions of Hyper-V init code be arch neutral
x86/hyperv: fix for unwanted manipulation of sched_clock when TSC marked unstable
asm-generic/hyperv: Add missing #include of nmi.h

+723 -164
+3
MAINTAINERS
··· 8647 8647 F: Documentation/ABI/stable/sysfs-bus-vmbus 8648 8648 F: Documentation/ABI/testing/debugfs-hyperv 8649 8649 F: Documentation/networking/device_drivers/ethernet/microsoft/netvsc.rst 8650 + F: arch/arm64/hyperv 8651 + F: arch/arm64/include/asm/hyperv-tlfs.h 8652 + F: arch/arm64/include/asm/mshyperv.h 8650 8653 F: arch/x86/hyperv 8651 8654 F: arch/x86/include/asm/hyperv-tlfs.h 8652 8655 F: arch/x86/include/asm/mshyperv.h
+1
arch/arm64/Kbuild
··· 2 2 obj-y += kernel/ mm/ net/ 3 3 obj-$(CONFIG_KVM) += kvm/ 4 4 obj-$(CONFIG_XEN) += xen/ 5 + obj-$(subst m,y,$(CONFIG_HYPERV)) += hyperv/ 5 6 obj-$(CONFIG_CRYPTO) += crypto/
+2
arch/arm64/hyperv/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + obj-y := hv_core.o mshyperv.o
+181
arch/arm64/hyperv/hv_core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + /* 4 + * Low level utility routines for interacting with Hyper-V. 5 + * 6 + * Copyright (C) 2021, Microsoft, Inc. 7 + * 8 + * Author : Michael Kelley <mikelley@microsoft.com> 9 + */ 10 + 11 + #include <linux/types.h> 12 + #include <linux/export.h> 13 + #include <linux/mm.h> 14 + #include <linux/hyperv.h> 15 + #include <linux/arm-smccc.h> 16 + #include <linux/module.h> 17 + #include <asm-generic/bug.h> 18 + #include <asm/hyperv-tlfs.h> 19 + #include <asm/mshyperv.h> 20 + 21 + /* 22 + * hv_do_hypercall- Invoke the specified hypercall 23 + */ 24 + u64 hv_do_hypercall(u64 control, void *input, void *output) 25 + { 26 + struct arm_smccc_res res; 27 + u64 input_address; 28 + u64 output_address; 29 + 30 + input_address = input ? virt_to_phys(input) : 0; 31 + output_address = output ? virt_to_phys(output) : 0; 32 + 33 + arm_smccc_1_1_hvc(HV_FUNC_ID, control, 34 + input_address, output_address, &res); 35 + return res.a0; 36 + } 37 + EXPORT_SYMBOL_GPL(hv_do_hypercall); 38 + 39 + /* 40 + * hv_do_fast_hypercall8 -- Invoke the specified hypercall 41 + * with arguments in registers instead of physical memory. 42 + * Avoids the overhead of virt_to_phys for simple hypercalls. 43 + */ 44 + 45 + u64 hv_do_fast_hypercall8(u16 code, u64 input) 46 + { 47 + struct arm_smccc_res res; 48 + u64 control; 49 + 50 + control = (u64)code | HV_HYPERCALL_FAST_BIT; 51 + 52 + arm_smccc_1_1_hvc(HV_FUNC_ID, control, input, &res); 53 + return res.a0; 54 + } 55 + EXPORT_SYMBOL_GPL(hv_do_fast_hypercall8); 56 + 57 + /* 58 + * Set a single VP register to a 64-bit value. 59 + */ 60 + void hv_set_vpreg(u32 msr, u64 value) 61 + { 62 + struct arm_smccc_res res; 63 + 64 + arm_smccc_1_1_hvc(HV_FUNC_ID, 65 + HVCALL_SET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT | 66 + HV_HYPERCALL_REP_COMP_1, 67 + HV_PARTITION_ID_SELF, 68 + HV_VP_INDEX_SELF, 69 + msr, 70 + 0, 71 + value, 72 + 0, 73 + &res); 74 + 75 + /* 76 + * Something is fundamentally broken in the hypervisor if 77 + * setting a VP register fails. There's really no way to 78 + * continue as a guest VM, so panic. 79 + */ 80 + BUG_ON(!hv_result_success(res.a0)); 81 + } 82 + EXPORT_SYMBOL_GPL(hv_set_vpreg); 83 + 84 + /* 85 + * Get the value of a single VP register. One version 86 + * returns just 64 bits and another returns the full 128 bits. 87 + * The two versions are separate to avoid complicating the 88 + * calling sequence for the more frequently used 64 bit version. 89 + */ 90 + 91 + void hv_get_vpreg_128(u32 msr, struct hv_get_vp_registers_output *result) 92 + { 93 + struct arm_smccc_1_2_regs args; 94 + struct arm_smccc_1_2_regs res; 95 + 96 + args.a0 = HV_FUNC_ID; 97 + args.a1 = HVCALL_GET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT | 98 + HV_HYPERCALL_REP_COMP_1; 99 + args.a2 = HV_PARTITION_ID_SELF; 100 + args.a3 = HV_VP_INDEX_SELF; 101 + args.a4 = msr; 102 + 103 + /* 104 + * Use the SMCCC 1.2 interface because the results are in registers 105 + * beyond X0-X3. 106 + */ 107 + arm_smccc_1_2_hvc(&args, &res); 108 + 109 + /* 110 + * Something is fundamentally broken in the hypervisor if 111 + * getting a VP register fails. There's really no way to 112 + * continue as a guest VM, so panic. 113 + */ 114 + BUG_ON(!hv_result_success(res.a0)); 115 + 116 + result->as64.low = res.a6; 117 + result->as64.high = res.a7; 118 + } 119 + EXPORT_SYMBOL_GPL(hv_get_vpreg_128); 120 + 121 + u64 hv_get_vpreg(u32 msr) 122 + { 123 + struct hv_get_vp_registers_output output; 124 + 125 + hv_get_vpreg_128(msr, &output); 126 + 127 + return output.as64.low; 128 + } 129 + EXPORT_SYMBOL_GPL(hv_get_vpreg); 130 + 131 + /* 132 + * hyperv_report_panic - report a panic to Hyper-V. This function uses 133 + * the older version of the Hyper-V interface that admittedly doesn't 134 + * pass enough information to be useful beyond just recording the 135 + * occurrence of a panic. The parallel hv_kmsg_dump() uses the 136 + * new interface that allows reporting 4 Kbytes of data, which is much 137 + * more useful. Hyper-V on ARM64 always supports the newer interface, but 138 + * we retain support for the older version because the sysadmin is allowed 139 + * to disable the newer version via sysctl in case of information security 140 + * concerns about the more verbose version. 141 + */ 142 + void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die) 143 + { 144 + static bool panic_reported; 145 + u64 guest_id; 146 + 147 + /* Don't report a panic to Hyper-V if we're not going to panic */ 148 + if (in_die && !panic_on_oops) 149 + return; 150 + 151 + /* 152 + * We prefer to report panic on 'die' chain as we have proper 153 + * registers to report, but if we miss it (e.g. on BUG()) we need 154 + * to report it on 'panic'. 155 + * 156 + * Calling code in the 'die' and 'panic' paths ensures that only 157 + * one CPU is running this code, so no atomicity is needed. 158 + */ 159 + if (panic_reported) 160 + return; 161 + panic_reported = true; 162 + 163 + guest_id = hv_get_vpreg(HV_REGISTER_GUEST_OSID); 164 + 165 + /* 166 + * Hyper-V provides the ability to store only 5 values. 167 + * Pick the passed in error value, the guest_id, the PC, 168 + * and the SP. 169 + */ 170 + hv_set_vpreg(HV_REGISTER_CRASH_P0, err); 171 + hv_set_vpreg(HV_REGISTER_CRASH_P1, guest_id); 172 + hv_set_vpreg(HV_REGISTER_CRASH_P2, regs->pc); 173 + hv_set_vpreg(HV_REGISTER_CRASH_P3, regs->sp); 174 + hv_set_vpreg(HV_REGISTER_CRASH_P4, 0); 175 + 176 + /* 177 + * Let Hyper-V know there is crash data available 178 + */ 179 + hv_set_vpreg(HV_REGISTER_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY); 180 + } 181 + EXPORT_SYMBOL_GPL(hyperv_report_panic);
+87
arch/arm64/hyperv/mshyperv.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + /* 4 + * Core routines for interacting with Microsoft's Hyper-V hypervisor, 5 + * including hypervisor initialization. 6 + * 7 + * Copyright (C) 2021, Microsoft, Inc. 8 + * 9 + * Author : Michael Kelley <mikelley@microsoft.com> 10 + */ 11 + 12 + #include <linux/types.h> 13 + #include <linux/acpi.h> 14 + #include <linux/export.h> 15 + #include <linux/errno.h> 16 + #include <linux/version.h> 17 + #include <linux/cpuhotplug.h> 18 + #include <asm/mshyperv.h> 19 + 20 + static bool hyperv_initialized; 21 + 22 + static int __init hyperv_init(void) 23 + { 24 + struct hv_get_vp_registers_output result; 25 + u32 a, b, c, d; 26 + u64 guest_id; 27 + int ret; 28 + 29 + /* 30 + * Allow for a kernel built with CONFIG_HYPERV to be running in 31 + * a non-Hyper-V environment, including on DT instead of ACPI. 32 + * In such cases, do nothing and return success. 33 + */ 34 + if (acpi_disabled) 35 + return 0; 36 + 37 + if (strncmp((char *)&acpi_gbl_FADT.hypervisor_id, "MsHyperV", 8)) 38 + return 0; 39 + 40 + /* Setup the guest ID */ 41 + guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0); 42 + hv_set_vpreg(HV_REGISTER_GUEST_OSID, guest_id); 43 + 44 + /* Get the features and hints from Hyper-V */ 45 + hv_get_vpreg_128(HV_REGISTER_FEATURES, &result); 46 + ms_hyperv.features = result.as32.a; 47 + ms_hyperv.priv_high = result.as32.b; 48 + ms_hyperv.misc_features = result.as32.c; 49 + 50 + hv_get_vpreg_128(HV_REGISTER_ENLIGHTENMENTS, &result); 51 + ms_hyperv.hints = result.as32.a; 52 + 53 + pr_info("Hyper-V: privilege flags low 0x%x, high 0x%x, hints 0x%x, misc 0x%x\n", 54 + ms_hyperv.features, ms_hyperv.priv_high, ms_hyperv.hints, 55 + ms_hyperv.misc_features); 56 + 57 + /* Get information about the Hyper-V host version */ 58 + hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result); 59 + a = result.as32.a; 60 + b = result.as32.b; 61 + c = result.as32.c; 62 + d = result.as32.d; 63 + pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n", 64 + b >> 16, b & 0xFFFF, a, d & 0xFFFFFF, c, d >> 24); 65 + 66 + ret = hv_common_init(); 67 + if (ret) 68 + return ret; 69 + 70 + ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm64/hyperv_init:online", 71 + hv_common_cpu_init, hv_common_cpu_die); 72 + if (ret < 0) { 73 + hv_common_free(); 74 + return ret; 75 + } 76 + 77 + hyperv_initialized = true; 78 + return 0; 79 + } 80 + 81 + early_initcall(hyperv_init); 82 + 83 + bool hv_is_hyperv_initialized(void) 84 + { 85 + return hyperv_initialized; 86 + } 87 + EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);
+69
arch/arm64/include/asm/hyperv-tlfs.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + /* 4 + * This file contains definitions from the Hyper-V Hypervisor Top-Level 5 + * Functional Specification (TLFS): 6 + * https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs 7 + * 8 + * Copyright (C) 2021, Microsoft, Inc. 9 + * 10 + * Author : Michael Kelley <mikelley@microsoft.com> 11 + */ 12 + 13 + #ifndef _ASM_HYPERV_TLFS_H 14 + #define _ASM_HYPERV_TLFS_H 15 + 16 + #include <linux/types.h> 17 + 18 + /* 19 + * All data structures defined in the TLFS that are shared between Hyper-V 20 + * and a guest VM use Little Endian byte ordering. This matches the default 21 + * byte ordering of Linux running on ARM64, so no special handling is required. 22 + */ 23 + 24 + /* 25 + * These Hyper-V registers provide information equivalent to the CPUID 26 + * instruction on x86/x64. 27 + */ 28 + #define HV_REGISTER_HYPERVISOR_VERSION 0x00000100 /*CPUID 0x40000002 */ 29 + #define HV_REGISTER_FEATURES 0x00000200 /*CPUID 0x40000003 */ 30 + #define HV_REGISTER_ENLIGHTENMENTS 0x00000201 /*CPUID 0x40000004 */ 31 + 32 + /* 33 + * Group C Features. See the asm-generic version of hyperv-tlfs.h 34 + * for a description of Feature Groups. 35 + */ 36 + 37 + /* Crash MSRs available */ 38 + #define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE BIT(8) 39 + 40 + /* STIMER direct mode is available */ 41 + #define HV_STIMER_DIRECT_MODE_AVAILABLE BIT(13) 42 + 43 + /* 44 + * Synthetic register definitions equivalent to MSRs on x86/x64 45 + */ 46 + #define HV_REGISTER_CRASH_P0 0x00000210 47 + #define HV_REGISTER_CRASH_P1 0x00000211 48 + #define HV_REGISTER_CRASH_P2 0x00000212 49 + #define HV_REGISTER_CRASH_P3 0x00000213 50 + #define HV_REGISTER_CRASH_P4 0x00000214 51 + #define HV_REGISTER_CRASH_CTL 0x00000215 52 + 53 + #define HV_REGISTER_GUEST_OSID 0x00090002 54 + #define HV_REGISTER_VP_INDEX 0x00090003 55 + #define HV_REGISTER_TIME_REF_COUNT 0x00090004 56 + #define HV_REGISTER_REFERENCE_TSC 0x00090017 57 + 58 + #define HV_REGISTER_SINT0 0x000A0000 59 + #define HV_REGISTER_SCONTROL 0x000A0010 60 + #define HV_REGISTER_SIEFP 0x000A0012 61 + #define HV_REGISTER_SIMP 0x000A0013 62 + #define HV_REGISTER_EOM 0x000A0014 63 + 64 + #define HV_REGISTER_STIMER0_CONFIG 0x000B0000 65 + #define HV_REGISTER_STIMER0_COUNT 0x000B0001 66 + 67 + #include <asm-generic/hyperv-tlfs.h> 68 + 69 + #endif
+54
arch/arm64/include/asm/mshyperv.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + /* 4 + * Linux-specific definitions for managing interactions with Microsoft's 5 + * Hyper-V hypervisor. The definitions in this file are specific to 6 + * the ARM64 architecture. See include/asm-generic/mshyperv.h for 7 + * definitions are that architecture independent. 8 + * 9 + * Definitions that are specified in the Hyper-V Top Level Functional 10 + * Spec (TLFS) should not go in this file, but should instead go in 11 + * hyperv-tlfs.h. 12 + * 13 + * Copyright (C) 2021, Microsoft, Inc. 14 + * 15 + * Author : Michael Kelley <mikelley@microsoft.com> 16 + */ 17 + 18 + #ifndef _ASM_MSHYPERV_H 19 + #define _ASM_MSHYPERV_H 20 + 21 + #include <linux/types.h> 22 + #include <linux/arm-smccc.h> 23 + #include <asm/hyperv-tlfs.h> 24 + 25 + /* 26 + * Declare calls to get and set Hyper-V VP register values on ARM64, which 27 + * requires a hypercall. 28 + */ 29 + 30 + void hv_set_vpreg(u32 reg, u64 value); 31 + u64 hv_get_vpreg(u32 reg); 32 + void hv_get_vpreg_128(u32 reg, struct hv_get_vp_registers_output *result); 33 + 34 + static inline void hv_set_register(unsigned int reg, u64 value) 35 + { 36 + hv_set_vpreg(reg, value); 37 + } 38 + 39 + static inline u64 hv_get_register(unsigned int reg) 40 + { 41 + return hv_get_vpreg(reg); 42 + } 43 + 44 + /* SMCCC hypercall parameters */ 45 + #define HV_SMCCC_FUNC_NUMBER 1 46 + #define HV_FUNC_ID ARM_SMCCC_CALL_VAL( \ 47 + ARM_SMCCC_STD_CALL, \ 48 + ARM_SMCCC_SMC_64, \ 49 + ARM_SMCCC_OWNER_VENDOR_HYP, \ 50 + HV_SMCCC_FUNC_NUMBER) 51 + 52 + #include <asm-generic/mshyperv.h> 53 + 54 + #endif
+1
arch/arm64/kernel/efi.c
··· 55 55 56 56 /* we will fill this structure from the stub, so don't put it in .bss */ 57 57 struct screen_info screen_info __section(".data"); 58 + EXPORT_SYMBOL(screen_info); 58 59 59 60 int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) 60 61 {
+54 -109
arch/x86/hyperv/hv_init.c
··· 7 7 * Author : K. Y. Srinivasan <kys@microsoft.com> 8 8 */ 9 9 10 - #include <linux/acpi.h> 11 10 #include <linux/efi.h> 12 11 #include <linux/types.h> 13 12 #include <linux/bitfield.h> 13 + #include <linux/io.h> 14 14 #include <asm/apic.h> 15 15 #include <asm/desc.h> 16 16 #include <asm/hypervisor.h> ··· 39 39 /* Storage to save the hypercall page temporarily for hibernation */ 40 40 static void *hv_hypercall_pg_saved; 41 41 42 - u32 *hv_vp_index; 43 - EXPORT_SYMBOL_GPL(hv_vp_index); 44 - 45 42 struct hv_vp_assist_page **hv_vp_assist_page; 46 43 EXPORT_SYMBOL_GPL(hv_vp_assist_page); 47 44 48 - void __percpu **hyperv_pcpu_input_arg; 49 - EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg); 50 - 51 - void __percpu **hyperv_pcpu_output_arg; 52 - EXPORT_SYMBOL_GPL(hyperv_pcpu_output_arg); 53 - 54 - u32 hv_max_vp_index; 55 - EXPORT_SYMBOL_GPL(hv_max_vp_index); 56 - 57 45 static int hv_cpu_init(unsigned int cpu) 58 46 { 59 - u64 msr_vp_index; 47 + union hv_vp_assist_msr_contents msr = { 0 }; 60 48 struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()]; 61 - void **input_arg; 62 - struct page *pg; 49 + int ret; 63 50 64 - /* hv_cpu_init() can be called with IRQs disabled from hv_resume() */ 65 - pg = alloc_pages(irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL, hv_root_partition ? 1 : 0); 66 - if (unlikely(!pg)) 67 - return -ENOMEM; 68 - 69 - input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg); 70 - *input_arg = page_address(pg); 71 - if (hv_root_partition) { 72 - void **output_arg; 73 - 74 - output_arg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg); 75 - *output_arg = page_address(pg + 1); 76 - } 77 - 78 - msr_vp_index = hv_get_register(HV_REGISTER_VP_INDEX); 79 - 80 - hv_vp_index[smp_processor_id()] = msr_vp_index; 81 - 82 - if (msr_vp_index > hv_max_vp_index) 83 - hv_max_vp_index = msr_vp_index; 51 + ret = hv_common_cpu_init(cpu); 52 + if (ret) 53 + return ret; 84 54 85 55 if (!hv_vp_assist_page) 86 56 return 0; 87 57 88 - /* 89 - * The VP ASSIST PAGE is an "overlay" page (see Hyper-V TLFS's Section 90 - * 5.2.1 "GPA Overlay Pages"). Here it must be zeroed out to make sure 91 - * we always write the EOI MSR in hv_apic_eoi_write() *after* the 92 - * EOI optimization is disabled in hv_cpu_die(), otherwise a CPU may 93 - * not be stopped in the case of CPU offlining and the VM will hang. 94 - */ 95 58 if (!*hvp) { 96 - *hvp = __vmalloc(PAGE_SIZE, GFP_KERNEL | __GFP_ZERO); 97 - } 98 - 99 - if (*hvp) { 100 - u64 val; 101 - 102 - val = vmalloc_to_pfn(*hvp); 103 - val = (val << HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT) | 104 - HV_X64_MSR_VP_ASSIST_PAGE_ENABLE; 105 - 106 - wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, val); 59 + if (hv_root_partition) { 60 + /* 61 + * For root partition we get the hypervisor provided VP assist 62 + * page, instead of allocating a new page. 63 + */ 64 + rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); 65 + *hvp = memremap(msr.pfn << 66 + HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT, 67 + PAGE_SIZE, MEMREMAP_WB); 68 + } else { 69 + /* 70 + * The VP assist page is an "overlay" page (see Hyper-V TLFS's 71 + * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed 72 + * out to make sure we always write the EOI MSR in 73 + * hv_apic_eoi_write() *after* the EOI optimization is disabled 74 + * in hv_cpu_die(), otherwise a CPU may not be stopped in the 75 + * case of CPU offlining and the VM will hang. 76 + */ 77 + *hvp = __vmalloc(PAGE_SIZE, GFP_KERNEL | __GFP_ZERO); 78 + if (*hvp) 79 + msr.pfn = vmalloc_to_pfn(*hvp); 80 + } 81 + WARN_ON(!(*hvp)); 82 + if (*hvp) { 83 + msr.enable = 1; 84 + wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); 85 + } 107 86 } 108 87 109 88 return 0; ··· 177 198 { 178 199 struct hv_reenlightenment_control re_ctrl; 179 200 unsigned int new_cpu; 180 - unsigned long flags; 181 - void **input_arg; 182 - void *pg; 183 201 184 - local_irq_save(flags); 185 - input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg); 186 - pg = *input_arg; 187 - *input_arg = NULL; 202 + hv_common_cpu_die(cpu); 188 203 189 - if (hv_root_partition) { 190 - void **output_arg; 191 - 192 - output_arg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg); 193 - *output_arg = NULL; 204 + if (hv_vp_assist_page && hv_vp_assist_page[cpu]) { 205 + union hv_vp_assist_msr_contents msr = { 0 }; 206 + if (hv_root_partition) { 207 + /* 208 + * For root partition the VP assist page is mapped to 209 + * hypervisor provided page, and thus we unmap the 210 + * page here and nullify it, so that in future we have 211 + * correct page address mapped in hv_cpu_init. 212 + */ 213 + memunmap(hv_vp_assist_page[cpu]); 214 + hv_vp_assist_page[cpu] = NULL; 215 + rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); 216 + msr.enable = 0; 217 + } 218 + wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); 194 219 } 195 - 196 - local_irq_restore(flags); 197 - 198 - free_pages((unsigned long)pg, hv_root_partition ? 1 : 0); 199 - 200 - if (hv_vp_assist_page && hv_vp_assist_page[cpu]) 201 - wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, 0); 202 220 203 221 if (hv_reenlightenment_cb == NULL) 204 222 return 0; ··· 344 368 { 345 369 u64 guest_id, required_msrs; 346 370 union hv_x64_msr_hypercall_contents hypercall_msr; 347 - int cpuhp, i; 371 + int cpuhp; 348 372 349 373 if (x86_hyper_type != X86_HYPER_MS_HYPERV) 350 374 return; ··· 356 380 if ((ms_hyperv.features & required_msrs) != required_msrs) 357 381 return; 358 382 359 - /* 360 - * Allocate the per-CPU state for the hypercall input arg. 361 - * If this allocation fails, we will not be able to setup 362 - * (per-CPU) hypercall input page and thus this failure is 363 - * fatal on Hyper-V. 364 - */ 365 - hyperv_pcpu_input_arg = alloc_percpu(void *); 366 - 367 - BUG_ON(hyperv_pcpu_input_arg == NULL); 368 - 369 - /* Allocate the per-CPU state for output arg for root */ 370 - if (hv_root_partition) { 371 - hyperv_pcpu_output_arg = alloc_percpu(void *); 372 - BUG_ON(hyperv_pcpu_output_arg == NULL); 373 - } 374 - 375 - /* Allocate percpu VP index */ 376 - hv_vp_index = kmalloc_array(num_possible_cpus(), sizeof(*hv_vp_index), 377 - GFP_KERNEL); 378 - if (!hv_vp_index) 383 + if (hv_common_init()) 379 384 return; 380 - 381 - for (i = 0; i < num_possible_cpus(); i++) 382 - hv_vp_index[i] = VP_INVAL; 383 385 384 386 hv_vp_assist_page = kcalloc(num_possible_cpus(), 385 387 sizeof(*hv_vp_assist_page), GFP_KERNEL); 386 388 if (!hv_vp_assist_page) { 387 389 ms_hyperv.hints &= ~HV_X64_ENLIGHTENED_VMCS_RECOMMENDED; 388 - goto free_vp_index; 390 + goto common_free; 389 391 } 390 392 391 393 cpuhp = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/hyperv_init:online", ··· 461 507 free_vp_assist_page: 462 508 kfree(hv_vp_assist_page); 463 509 hv_vp_assist_page = NULL; 464 - free_vp_index: 465 - kfree(hv_vp_index); 466 - hv_vp_index = NULL; 510 + common_free: 511 + hv_common_free(); 467 512 } 468 513 469 514 /* ··· 492 539 hypercall_msr.as_uint64 = 0; 493 540 wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64); 494 541 } 495 - EXPORT_SYMBOL_GPL(hyperv_cleanup); 496 542 497 543 void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die) 498 544 { ··· 547 595 } 548 596 EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized); 549 597 550 - bool hv_is_hibernation_supported(void) 551 - { 552 - return !hv_root_partition && acpi_sleep_state_supported(ACPI_STATE_S4); 553 - } 554 - EXPORT_SYMBOL_GPL(hv_is_hibernation_supported); 555 - 556 598 enum hv_isolation_type hv_get_isolation_type(void) 557 599 { 558 600 if (!(ms_hyperv.priv_high & HV_ISOLATION)) ··· 559 613 { 560 614 return hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE; 561 615 } 562 - EXPORT_SYMBOL_GPL(hv_is_isolation_supported);
+9
arch/x86/include/asm/hyperv-tlfs.h
··· 288 288 } __packed; 289 289 }; 290 290 291 + union hv_vp_assist_msr_contents { 292 + u64 as_uint64; 293 + struct { 294 + u64 enable:1; 295 + u64 reserved:11; 296 + u64 pfn:52; 297 + } __packed; 298 + }; 299 + 291 300 struct hv_reenlightenment_control { 292 301 __u64 vector:8; 293 302 __u64 reserved1:8;
-4
arch/x86/include/asm/mshyperv.h
··· 36 36 extern int hyperv_init_cpuhp; 37 37 38 38 extern void *hv_hypercall_pg; 39 - extern void __percpu **hyperv_pcpu_input_arg; 40 - extern void __percpu **hyperv_pcpu_output_arg; 41 39 42 40 extern u64 hv_current_partition_id; 43 41 ··· 167 169 int hyperv_fill_flush_guest_mapping_list( 168 170 struct hv_guest_mapping_flush_list *flush, 169 171 u64 start_gfn, u64 end_gfn); 170 - 171 - extern bool hv_root_partition; 172 172 173 173 #ifdef CONFIG_X86_64 174 174 void hv_apic_init(void);
+16 -22
arch/x86/kernel/cpu/mshyperv.c
··· 17 17 #include <linux/irq.h> 18 18 #include <linux/kexec.h> 19 19 #include <linux/i8253.h> 20 - #include <linux/panic_notifier.h> 21 20 #include <linux/random.h> 22 21 #include <asm/processor.h> 23 22 #include <asm/hypervisor.h> ··· 35 36 36 37 /* Is Linux running as the root partition? */ 37 38 bool hv_root_partition; 38 - EXPORT_SYMBOL_GPL(hv_root_partition); 39 - 40 39 struct ms_hyperv_info ms_hyperv; 41 - EXPORT_SYMBOL_GPL(ms_hyperv); 42 40 43 41 #if IS_ENABLED(CONFIG_HYPERV) 44 42 static void (*vmbus_handler)(void); ··· 61 65 { 62 66 vmbus_handler = handler; 63 67 } 64 - EXPORT_SYMBOL_GPL(hv_setup_vmbus_handler); 65 68 66 69 void hv_remove_vmbus_handler(void) 67 70 { 68 71 /* We have no way to deallocate the interrupt gate */ 69 72 vmbus_handler = NULL; 70 73 } 71 - EXPORT_SYMBOL_GPL(hv_remove_vmbus_handler); 72 74 73 75 /* 74 76 * Routines to do per-architecture handling of stimer0 ··· 101 107 { 102 108 hv_kexec_handler = handler; 103 109 } 104 - EXPORT_SYMBOL_GPL(hv_setup_kexec_handler); 105 110 106 111 void hv_remove_kexec_handler(void) 107 112 { 108 113 hv_kexec_handler = NULL; 109 114 } 110 - EXPORT_SYMBOL_GPL(hv_remove_kexec_handler); 111 115 112 116 void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs)) 113 117 { 114 118 hv_crash_handler = handler; 115 119 } 116 - EXPORT_SYMBOL_GPL(hv_setup_crash_handler); 117 120 118 121 void hv_remove_crash_handler(void) 119 122 { 120 123 hv_crash_handler = NULL; 121 124 } 122 - EXPORT_SYMBOL_GPL(hv_remove_crash_handler); 123 125 124 126 #ifdef CONFIG_KEXEC_CORE 125 127 static void hv_machine_shutdown(void) ··· 325 335 ms_hyperv.nested_features); 326 336 } 327 337 328 - /* 329 - * Hyper-V expects to get crash register data or kmsg when 330 - * crash enlightment is available and system crashes. Set 331 - * crash_kexec_post_notifiers to be true to make sure that 332 - * calling crash enlightment interface before running kdump 333 - * kernel. 334 - */ 335 - if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) 336 - crash_kexec_post_notifiers = true; 337 - 338 338 #ifdef CONFIG_X86_LOCAL_APIC 339 339 if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS && 340 340 ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) { ··· 353 373 machine_ops.crash_shutdown = hv_machine_crash_shutdown; 354 374 #endif 355 375 if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) { 376 + /* 377 + * Writing to synthetic MSR 0x40000118 updates/changes the 378 + * guest visible CPUIDs. Setting bit 0 of this MSR enables 379 + * guests to report invariant TSC feature through CPUID 380 + * instruction, CPUID 0x800000007/EDX, bit 8. See code in 381 + * early_init_intel() where this bit is examined. The 382 + * setting of this MSR bit should happen before init_intel() 383 + * is called. 384 + */ 356 385 wrmsrl(HV_X64_MSR_TSC_INVARIANT_CONTROL, 0x1); 357 386 setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE); 358 - } else { 359 - mark_tsc_unstable("running on Hyper-V"); 360 387 } 361 388 362 389 /* ··· 424 437 /* Register Hyper-V specific clocksource */ 425 438 hv_init_clocksource(); 426 439 #endif 440 + /* 441 + * TSC should be marked as unstable only after Hyper-V 442 + * clocksource has been initialized. This ensures that the 443 + * stability of the sched_clock is not altered. 444 + */ 445 + if (!(ms_hyperv.features & HV_ACCESS_TSC_INVARIANT)) 446 + mark_tsc_unstable("running on Hyper-V"); 427 447 } 428 448 429 449 static bool __init ms_hyperv_x2apic_available(void)
-3
drivers/clocksource/hyperv_timer.c
··· 361 361 * Hyper-V and 32-bit x86. The TSC reference page version is preferred. 362 362 */ 363 363 364 - u64 (*hv_read_reference_counter)(void); 365 - EXPORT_SYMBOL_GPL(hv_read_reference_counter); 366 - 367 364 static union { 368 365 struct ms_hyperv_tsc_page page; 369 366 u8 reserved[PAGE_SIZE];
+4 -3
drivers/hv/Kconfig
··· 4 4 5 5 config HYPERV 6 6 tristate "Microsoft Hyper-V client drivers" 7 - depends on X86 && ACPI && X86_LOCAL_APIC && HYPERVISOR_GUEST 7 + depends on ACPI && ((X86 && X86_LOCAL_APIC && HYPERVISOR_GUEST) \ 8 + || (ARM64 && !CPU_BIG_ENDIAN)) 8 9 select PARAVIRT 9 - select X86_HV_CALLBACK_VECTOR 10 + select X86_HV_CALLBACK_VECTOR if X86 10 11 help 11 12 Select this option to run Linux as a Hyper-V client operating 12 13 system. 13 14 14 15 config HYPERV_TIMER 15 - def_bool HYPERV 16 + def_bool HYPERV && X86 16 17 17 18 config HYPERV_UTILS 18 19 tristate "Microsoft Hyper-V Utilities driver"
+219
drivers/hv/hv_common.c
··· 13 13 */ 14 14 15 15 #include <linux/types.h> 16 + #include <linux/acpi.h> 16 17 #include <linux/export.h> 17 18 #include <linux/bitfield.h> 19 + #include <linux/cpumask.h> 20 + #include <linux/panic_notifier.h> 21 + #include <linux/ptrace.h> 22 + #include <linux/slab.h> 18 23 #include <asm/hyperv-tlfs.h> 19 24 #include <asm/mshyperv.h> 20 25 26 + /* 27 + * hv_root_partition and ms_hyperv are defined here with other Hyper-V 28 + * specific globals so they are shared across all architectures and are 29 + * built only when CONFIG_HYPERV is defined. But on x86, 30 + * ms_hyperv_init_platform() is built even when CONFIG_HYPERV is not 31 + * defined, and it uses these two variables. So mark them as __weak 32 + * here, allowing for an overriding definition in the module containing 33 + * ms_hyperv_init_platform(). 34 + */ 35 + bool __weak hv_root_partition; 36 + EXPORT_SYMBOL_GPL(hv_root_partition); 37 + 38 + struct ms_hyperv_info __weak ms_hyperv; 39 + EXPORT_SYMBOL_GPL(ms_hyperv); 40 + 41 + u32 *hv_vp_index; 42 + EXPORT_SYMBOL_GPL(hv_vp_index); 43 + 44 + u32 hv_max_vp_index; 45 + EXPORT_SYMBOL_GPL(hv_max_vp_index); 46 + 47 + void __percpu **hyperv_pcpu_input_arg; 48 + EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg); 49 + 50 + void __percpu **hyperv_pcpu_output_arg; 51 + EXPORT_SYMBOL_GPL(hyperv_pcpu_output_arg); 52 + 53 + /* 54 + * Hyper-V specific initialization and shutdown code that is 55 + * common across all architectures. Called from architecture 56 + * specific initialization functions. 57 + */ 58 + 59 + void __init hv_common_free(void) 60 + { 61 + kfree(hv_vp_index); 62 + hv_vp_index = NULL; 63 + 64 + free_percpu(hyperv_pcpu_output_arg); 65 + hyperv_pcpu_output_arg = NULL; 66 + 67 + free_percpu(hyperv_pcpu_input_arg); 68 + hyperv_pcpu_input_arg = NULL; 69 + } 70 + 71 + int __init hv_common_init(void) 72 + { 73 + int i; 74 + 75 + /* 76 + * Hyper-V expects to get crash register data or kmsg when 77 + * crash enlightment is available and system crashes. Set 78 + * crash_kexec_post_notifiers to be true to make sure that 79 + * calling crash enlightment interface before running kdump 80 + * kernel. 81 + */ 82 + if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) 83 + crash_kexec_post_notifiers = true; 84 + 85 + /* 86 + * Allocate the per-CPU state for the hypercall input arg. 87 + * If this allocation fails, we will not be able to setup 88 + * (per-CPU) hypercall input page and thus this failure is 89 + * fatal on Hyper-V. 90 + */ 91 + hyperv_pcpu_input_arg = alloc_percpu(void *); 92 + BUG_ON(!hyperv_pcpu_input_arg); 93 + 94 + /* Allocate the per-CPU state for output arg for root */ 95 + if (hv_root_partition) { 96 + hyperv_pcpu_output_arg = alloc_percpu(void *); 97 + BUG_ON(!hyperv_pcpu_output_arg); 98 + } 99 + 100 + hv_vp_index = kmalloc_array(num_possible_cpus(), sizeof(*hv_vp_index), 101 + GFP_KERNEL); 102 + if (!hv_vp_index) { 103 + hv_common_free(); 104 + return -ENOMEM; 105 + } 106 + 107 + for (i = 0; i < num_possible_cpus(); i++) 108 + hv_vp_index[i] = VP_INVAL; 109 + 110 + return 0; 111 + } 112 + 113 + /* 114 + * Hyper-V specific initialization and die code for 115 + * individual CPUs that is common across all architectures. 116 + * Called by the CPU hotplug mechanism. 117 + */ 118 + 119 + int hv_common_cpu_init(unsigned int cpu) 120 + { 121 + void **inputarg, **outputarg; 122 + u64 msr_vp_index; 123 + gfp_t flags; 124 + int pgcount = hv_root_partition ? 2 : 1; 125 + 126 + /* hv_cpu_init() can be called with IRQs disabled from hv_resume() */ 127 + flags = irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL; 128 + 129 + inputarg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg); 130 + *inputarg = kmalloc(pgcount * HV_HYP_PAGE_SIZE, flags); 131 + if (!(*inputarg)) 132 + return -ENOMEM; 133 + 134 + if (hv_root_partition) { 135 + outputarg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg); 136 + *outputarg = (char *)(*inputarg) + HV_HYP_PAGE_SIZE; 137 + } 138 + 139 + msr_vp_index = hv_get_register(HV_REGISTER_VP_INDEX); 140 + 141 + hv_vp_index[cpu] = msr_vp_index; 142 + 143 + if (msr_vp_index > hv_max_vp_index) 144 + hv_max_vp_index = msr_vp_index; 145 + 146 + return 0; 147 + } 148 + 149 + int hv_common_cpu_die(unsigned int cpu) 150 + { 151 + unsigned long flags; 152 + void **inputarg, **outputarg; 153 + void *mem; 154 + 155 + local_irq_save(flags); 156 + 157 + inputarg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg); 158 + mem = *inputarg; 159 + *inputarg = NULL; 160 + 161 + if (hv_root_partition) { 162 + outputarg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg); 163 + *outputarg = NULL; 164 + } 165 + 166 + local_irq_restore(flags); 167 + 168 + kfree(mem); 169 + 170 + return 0; 171 + } 21 172 22 173 /* Bit mask of the extended capability to query: see HV_EXT_CAPABILITY_xxx */ 23 174 bool hv_query_ext_cap(u64 cap_query) ··· 215 64 return hv_extended_cap & cap_query; 216 65 } 217 66 EXPORT_SYMBOL_GPL(hv_query_ext_cap); 67 + 68 + bool hv_is_hibernation_supported(void) 69 + { 70 + return !hv_root_partition && acpi_sleep_state_supported(ACPI_STATE_S4); 71 + } 72 + EXPORT_SYMBOL_GPL(hv_is_hibernation_supported); 73 + 74 + /* 75 + * Default function to read the Hyper-V reference counter, independent 76 + * of whether Hyper-V enlightened clocks/timers are being used. But on 77 + * architectures where it is used, Hyper-V enlightenment code in 78 + * hyperv_timer.c may override this function. 79 + */ 80 + static u64 __hv_read_ref_counter(void) 81 + { 82 + return hv_get_register(HV_REGISTER_TIME_REF_COUNT); 83 + } 84 + 85 + u64 (*hv_read_reference_counter)(void) = __hv_read_ref_counter; 86 + EXPORT_SYMBOL_GPL(hv_read_reference_counter); 87 + 88 + /* These __weak functions provide default "no-op" behavior and 89 + * may be overridden by architecture specific versions. Architectures 90 + * for which the default "no-op" behavior is sufficient can leave 91 + * them unimplemented and not be cluttered with a bunch of stub 92 + * functions in arch-specific code. 93 + */ 94 + 95 + bool __weak hv_is_isolation_supported(void) 96 + { 97 + return false; 98 + } 99 + EXPORT_SYMBOL_GPL(hv_is_isolation_supported); 100 + 101 + void __weak hv_setup_vmbus_handler(void (*handler)(void)) 102 + { 103 + } 104 + EXPORT_SYMBOL_GPL(hv_setup_vmbus_handler); 105 + 106 + void __weak hv_remove_vmbus_handler(void) 107 + { 108 + } 109 + EXPORT_SYMBOL_GPL(hv_remove_vmbus_handler); 110 + 111 + void __weak hv_setup_kexec_handler(void (*handler)(void)) 112 + { 113 + } 114 + EXPORT_SYMBOL_GPL(hv_setup_kexec_handler); 115 + 116 + void __weak hv_remove_kexec_handler(void) 117 + { 118 + } 119 + EXPORT_SYMBOL_GPL(hv_remove_kexec_handler); 120 + 121 + void __weak hv_setup_crash_handler(void (*handler)(struct pt_regs *regs)) 122 + { 123 + } 124 + EXPORT_SYMBOL_GPL(hv_setup_crash_handler); 125 + 126 + void __weak hv_remove_crash_handler(void) 127 + { 128 + } 129 + EXPORT_SYMBOL_GPL(hv_remove_crash_handler); 130 + 131 + void __weak hyperv_cleanup(void) 132 + { 133 + } 134 + EXPORT_SYMBOL_GPL(hyperv_cleanup);
+1
drivers/hv/hv_snapshot.c
··· 375 375 } 376 376 recv_buffer = srv->recv_buffer; 377 377 vss_transaction.recv_channel = srv->channel; 378 + vss_transaction.recv_channel->max_pkt_size = HV_HYP_PAGE_SIZE * 2; 378 379 379 380 /* 380 381 * When this driver loads, the user level daemon that
-5
drivers/hv/hv_util.c
··· 17 17 #include <linux/hyperv.h> 18 18 #include <linux/clockchips.h> 19 19 #include <linux/ptp_clock_kernel.h> 20 - #include <clocksource/hyperv_timer.h> 21 20 #include <asm/mshyperv.h> 22 21 23 22 #include "hyperv_vmbus.h" ··· 734 735 735 736 static int hv_timesync_init(struct hv_util_service *srv) 736 737 { 737 - /* TimeSync requires Hyper-V clocksource. */ 738 - if (!hv_read_reference_counter) 739 - return -ENODEV; 740 - 741 738 spin_lock_init(&host_ts.lock); 742 739 743 740 INIT_WORK(&adj_time_work, hv_set_host_time);
+13
include/asm-generic/mshyperv.h
··· 22 22 #include <linux/atomic.h> 23 23 #include <linux/bitops.h> 24 24 #include <linux/cpumask.h> 25 + #include <linux/nmi.h> 25 26 #include <asm/ptrace.h> 26 27 #include <asm/hyperv-tlfs.h> 27 28 ··· 38 37 u32 isolation_config_b; 39 38 }; 40 39 extern struct ms_hyperv_info ms_hyperv; 40 + 41 + extern void __percpu **hyperv_pcpu_input_arg; 42 + extern void __percpu **hyperv_pcpu_output_arg; 41 43 42 44 extern u64 hv_do_hypercall(u64 control, void *inputaddr, void *outputaddr); 43 45 extern u64 hv_do_fast_hypercall8(u16 control, u64 input8); ··· 155 151 extern int vmbus_interrupt; 156 152 extern int vmbus_irq; 157 153 154 + extern bool hv_root_partition; 155 + 158 156 #if IS_ENABLED(CONFIG_HYPERV) 159 157 /* 160 158 * Hypervisor's notion of virtual processor ID is different from ··· 167 161 extern u32 *hv_vp_index; 168 162 extern u32 hv_max_vp_index; 169 163 164 + extern u64 (*hv_read_reference_counter)(void); 165 + 170 166 /* Sentinel value for an uninitialized entry in hv_vp_index array */ 171 167 #define VP_INVAL U32_MAX 168 + 169 + int __init hv_common_init(void); 170 + void __init hv_common_free(void); 171 + int hv_common_cpu_init(unsigned int cpu); 172 + int hv_common_cpu_die(unsigned int cpu); 172 173 173 174 void *hv_alloc_hyperv_page(void); 174 175 void *hv_alloc_hyperv_zeroed_page(void);
+9 -2
include/clocksource/hyperv_timer.h
··· 20 20 #define HV_MAX_MAX_DELTA_TICKS 0xffffffff 21 21 #define HV_MIN_DELTA_TICKS 1 22 22 23 + #ifdef CONFIG_HYPERV_TIMER 24 + 23 25 /* Routines called by the VMbus driver */ 24 26 extern int hv_stimer_alloc(bool have_percpu_irqs); 25 27 extern int hv_stimer_cleanup(unsigned int cpu); ··· 30 28 extern void hv_stimer_global_cleanup(void); 31 29 extern void hv_stimer0_isr(void); 32 30 33 - #ifdef CONFIG_HYPERV_TIMER 34 - extern u64 (*hv_read_reference_counter)(void); 35 31 extern void hv_init_clocksource(void); 36 32 37 33 extern struct ms_hyperv_tsc_page *hv_get_tsc_page(void); ··· 100 100 { 101 101 return U64_MAX; 102 102 } 103 + 104 + static inline int hv_stimer_cleanup(unsigned int cpu) { return 0; } 105 + static inline void hv_stimer_legacy_init(unsigned int cpu, int sint) {} 106 + static inline void hv_stimer_legacy_cleanup(unsigned int cpu) {} 107 + static inline void hv_stimer_global_cleanup(void) {} 108 + static inline void hv_stimer0_isr(void) {} 109 + 103 110 #endif /* CONFIG_HYPERV_TIMER */ 104 111 105 112 #endif
-16
include/linux/hyperv.h
··· 538 538 u32 child_relid; 539 539 } __packed; 540 540 541 - static inline u32 542 - hv_ringbuffer_pending_size(const struct hv_ring_buffer_info *rbi) 543 - { 544 - return rbi->ring_buffer->pending_send_sz; 545 - } 546 - 547 541 /* 548 542 * Request Offer -- no parameters, SynIC message contains the partition ID 549 543 * Set Snoop -- no parameters, SynIC message contains the partition ID ··· 1084 1090 } 1085 1091 1086 1092 c->outbound.ring_buffer->pending_send_sz = size; 1087 - } 1088 - 1089 - static inline void set_low_latency_mode(struct vmbus_channel *c) 1090 - { 1091 - c->low_latency = true; 1092 - } 1093 - 1094 - static inline void clear_low_latency_mode(struct vmbus_channel *c) 1095 - { 1096 - c->low_latency = false; 1097 1093 } 1098 1094 1099 1095 void vmbus_onmessage(struct vmbus_channel_message_header *hdr);