Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 /*
0004  * Architecture neutral utility routines for interacting with
0005  * Hyper-V. This file is specifically for code that must be
0006  * built-in to the kernel image when CONFIG_HYPERV is set
0007  * (vs. being in a module) because it is called from architecture
0008  * specific code under arch/.
0009  *
0010  * Copyright (C) 2021, Microsoft, Inc.
0011  *
0012  * Author : Michael Kelley <mikelley@microsoft.com>
0013  */
0014 
0015 #include <linux/types.h>
0016 #include <linux/acpi.h>
0017 #include <linux/export.h>
0018 #include <linux/bitfield.h>
0019 #include <linux/cpumask.h>
0020 #include <linux/panic_notifier.h>
0021 #include <linux/ptrace.h>
0022 #include <linux/slab.h>
0023 #include <linux/dma-map-ops.h>
0024 #include <asm/hyperv-tlfs.h>
0025 #include <asm/mshyperv.h>
0026 
0027 /*
0028  * hv_root_partition and ms_hyperv are defined here with other Hyper-V
0029  * specific globals so they are shared across all architectures and are
0030  * built only when CONFIG_HYPERV is defined.  But on x86,
0031  * ms_hyperv_init_platform() is built even when CONFIG_HYPERV is not
0032  * defined, and it uses these two variables.  So mark them as __weak
0033  * here, allowing for an overriding definition in the module containing
0034  * ms_hyperv_init_platform().
0035  */
0036 bool __weak hv_root_partition;
0037 EXPORT_SYMBOL_GPL(hv_root_partition);
0038 
0039 struct ms_hyperv_info __weak ms_hyperv;
0040 EXPORT_SYMBOL_GPL(ms_hyperv);
0041 
0042 u32 *hv_vp_index;
0043 EXPORT_SYMBOL_GPL(hv_vp_index);
0044 
0045 u32 hv_max_vp_index;
0046 EXPORT_SYMBOL_GPL(hv_max_vp_index);
0047 
0048 void * __percpu *hyperv_pcpu_input_arg;
0049 EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg);
0050 
0051 void * __percpu *hyperv_pcpu_output_arg;
0052 EXPORT_SYMBOL_GPL(hyperv_pcpu_output_arg);
0053 
0054 /*
0055  * Hyper-V specific initialization and shutdown code that is
0056  * common across all architectures.  Called from architecture
0057  * specific initialization functions.
0058  */
0059 
0060 void __init hv_common_free(void)
0061 {
0062     kfree(hv_vp_index);
0063     hv_vp_index = NULL;
0064 
0065     free_percpu(hyperv_pcpu_output_arg);
0066     hyperv_pcpu_output_arg = NULL;
0067 
0068     free_percpu(hyperv_pcpu_input_arg);
0069     hyperv_pcpu_input_arg = NULL;
0070 }
0071 
0072 int __init hv_common_init(void)
0073 {
0074     int i;
0075 
0076     /*
0077      * Hyper-V expects to get crash register data or kmsg when
0078      * crash enlightment is available and system crashes. Set
0079      * crash_kexec_post_notifiers to be true to make sure that
0080      * calling crash enlightment interface before running kdump
0081      * kernel.
0082      */
0083     if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
0084         crash_kexec_post_notifiers = true;
0085         pr_info("Hyper-V: enabling crash_kexec_post_notifiers\n");
0086     }
0087 
0088     /*
0089      * Allocate the per-CPU state for the hypercall input arg.
0090      * If this allocation fails, we will not be able to setup
0091      * (per-CPU) hypercall input page and thus this failure is
0092      * fatal on Hyper-V.
0093      */
0094     hyperv_pcpu_input_arg = alloc_percpu(void  *);
0095     BUG_ON(!hyperv_pcpu_input_arg);
0096 
0097     /* Allocate the per-CPU state for output arg for root */
0098     if (hv_root_partition) {
0099         hyperv_pcpu_output_arg = alloc_percpu(void *);
0100         BUG_ON(!hyperv_pcpu_output_arg);
0101     }
0102 
0103     hv_vp_index = kmalloc_array(num_possible_cpus(), sizeof(*hv_vp_index),
0104                     GFP_KERNEL);
0105     if (!hv_vp_index) {
0106         hv_common_free();
0107         return -ENOMEM;
0108     }
0109 
0110     for (i = 0; i < num_possible_cpus(); i++)
0111         hv_vp_index[i] = VP_INVAL;
0112 
0113     return 0;
0114 }
0115 
0116 /*
0117  * Hyper-V specific initialization and die code for
0118  * individual CPUs that is common across all architectures.
0119  * Called by the CPU hotplug mechanism.
0120  */
0121 
0122 int hv_common_cpu_init(unsigned int cpu)
0123 {
0124     void **inputarg, **outputarg;
0125     u64 msr_vp_index;
0126     gfp_t flags;
0127     int pgcount = hv_root_partition ? 2 : 1;
0128 
0129     /* hv_cpu_init() can be called with IRQs disabled from hv_resume() */
0130     flags = irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL;
0131 
0132     inputarg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg);
0133     *inputarg = kmalloc(pgcount * HV_HYP_PAGE_SIZE, flags);
0134     if (!(*inputarg))
0135         return -ENOMEM;
0136 
0137     if (hv_root_partition) {
0138         outputarg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg);
0139         *outputarg = (char *)(*inputarg) + HV_HYP_PAGE_SIZE;
0140     }
0141 
0142     msr_vp_index = hv_get_register(HV_REGISTER_VP_INDEX);
0143 
0144     hv_vp_index[cpu] = msr_vp_index;
0145 
0146     if (msr_vp_index > hv_max_vp_index)
0147         hv_max_vp_index = msr_vp_index;
0148 
0149     return 0;
0150 }
0151 
0152 int hv_common_cpu_die(unsigned int cpu)
0153 {
0154     unsigned long flags;
0155     void **inputarg, **outputarg;
0156     void *mem;
0157 
0158     local_irq_save(flags);
0159 
0160     inputarg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg);
0161     mem = *inputarg;
0162     *inputarg = NULL;
0163 
0164     if (hv_root_partition) {
0165         outputarg = (void **)this_cpu_ptr(hyperv_pcpu_output_arg);
0166         *outputarg = NULL;
0167     }
0168 
0169     local_irq_restore(flags);
0170 
0171     kfree(mem);
0172 
0173     return 0;
0174 }
0175 
0176 /* Bit mask of the extended capability to query: see HV_EXT_CAPABILITY_xxx */
0177 bool hv_query_ext_cap(u64 cap_query)
0178 {
0179     /*
0180      * The address of the 'hv_extended_cap' variable will be used as an
0181      * output parameter to the hypercall below and so it should be
0182      * compatible with 'virt_to_phys'. Which means, it's address should be
0183      * directly mapped. Use 'static' to keep it compatible; stack variables
0184      * can be virtually mapped, making them incompatible with
0185      * 'virt_to_phys'.
0186      * Hypercall input/output addresses should also be 8-byte aligned.
0187      */
0188     static u64 hv_extended_cap __aligned(8);
0189     static bool hv_extended_cap_queried;
0190     u64 status;
0191 
0192     /*
0193      * Querying extended capabilities is an extended hypercall. Check if the
0194      * partition supports extended hypercall, first.
0195      */
0196     if (!(ms_hyperv.priv_high & HV_ENABLE_EXTENDED_HYPERCALLS))
0197         return false;
0198 
0199     /* Extended capabilities do not change at runtime. */
0200     if (hv_extended_cap_queried)
0201         return hv_extended_cap & cap_query;
0202 
0203     status = hv_do_hypercall(HV_EXT_CALL_QUERY_CAPABILITIES, NULL,
0204                  &hv_extended_cap);
0205 
0206     /*
0207      * The query extended capabilities hypercall should not fail under
0208      * any normal circumstances. Avoid repeatedly making the hypercall, on
0209      * error.
0210      */
0211     hv_extended_cap_queried = true;
0212     if (!hv_result_success(status)) {
0213         pr_err("Hyper-V: Extended query capabilities hypercall failed 0x%llx\n",
0214                status);
0215         return false;
0216     }
0217 
0218     return hv_extended_cap & cap_query;
0219 }
0220 EXPORT_SYMBOL_GPL(hv_query_ext_cap);
0221 
0222 void hv_setup_dma_ops(struct device *dev, bool coherent)
0223 {
0224     /*
0225      * Hyper-V does not offer a vIOMMU in the guest
0226      * VM, so pass 0/NULL for the IOMMU settings
0227      */
0228     arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
0229 }
0230 EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
0231 
0232 bool hv_is_hibernation_supported(void)
0233 {
0234     return !hv_root_partition && acpi_sleep_state_supported(ACPI_STATE_S4);
0235 }
0236 EXPORT_SYMBOL_GPL(hv_is_hibernation_supported);
0237 
0238 /*
0239  * Default function to read the Hyper-V reference counter, independent
0240  * of whether Hyper-V enlightened clocks/timers are being used. But on
0241  * architectures where it is used, Hyper-V enlightenment code in
0242  * hyperv_timer.c may override this function.
0243  */
0244 static u64 __hv_read_ref_counter(void)
0245 {
0246     return hv_get_register(HV_REGISTER_TIME_REF_COUNT);
0247 }
0248 
0249 u64 (*hv_read_reference_counter)(void) = __hv_read_ref_counter;
0250 EXPORT_SYMBOL_GPL(hv_read_reference_counter);
0251 
0252 /* These __weak functions provide default "no-op" behavior and
0253  * may be overridden by architecture specific versions. Architectures
0254  * for which the default "no-op" behavior is sufficient can leave
0255  * them unimplemented and not be cluttered with a bunch of stub
0256  * functions in arch-specific code.
0257  */
0258 
0259 bool __weak hv_is_isolation_supported(void)
0260 {
0261     return false;
0262 }
0263 EXPORT_SYMBOL_GPL(hv_is_isolation_supported);
0264 
0265 bool __weak hv_isolation_type_snp(void)
0266 {
0267     return false;
0268 }
0269 EXPORT_SYMBOL_GPL(hv_isolation_type_snp);
0270 
0271 void __weak hv_setup_vmbus_handler(void (*handler)(void))
0272 {
0273 }
0274 EXPORT_SYMBOL_GPL(hv_setup_vmbus_handler);
0275 
0276 void __weak hv_remove_vmbus_handler(void)
0277 {
0278 }
0279 EXPORT_SYMBOL_GPL(hv_remove_vmbus_handler);
0280 
0281 void __weak hv_setup_kexec_handler(void (*handler)(void))
0282 {
0283 }
0284 EXPORT_SYMBOL_GPL(hv_setup_kexec_handler);
0285 
0286 void __weak hv_remove_kexec_handler(void)
0287 {
0288 }
0289 EXPORT_SYMBOL_GPL(hv_remove_kexec_handler);
0290 
0291 void __weak hv_setup_crash_handler(void (*handler)(struct pt_regs *regs))
0292 {
0293 }
0294 EXPORT_SYMBOL_GPL(hv_setup_crash_handler);
0295 
0296 void __weak hv_remove_crash_handler(void)
0297 {
0298 }
0299 EXPORT_SYMBOL_GPL(hv_remove_crash_handler);
0300 
0301 void __weak hyperv_cleanup(void)
0302 {
0303 }
0304 EXPORT_SYMBOL_GPL(hyperv_cleanup);
0305 
0306 u64 __weak hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size)
0307 {
0308     return HV_STATUS_INVALID_PARAMETER;
0309 }
0310 EXPORT_SYMBOL_GPL(hv_ghcb_hypercall);
0311 
0312 void __weak *hv_map_memory(void *addr, unsigned long size)
0313 {
0314     return NULL;
0315 }
0316 EXPORT_SYMBOL_GPL(hv_map_memory);
0317 
0318 void __weak hv_unmap_memory(void *addr)
0319 {
0320 }
0321 EXPORT_SYMBOL_GPL(hv_unmap_memory);