linux/drivers/hv/hv_common.c

// SPDX-License-Identifier: GPL-2.0

/*
 * Architecture neutral utility routines for interacting with
 * Hyper-V. This file is specifically for code that must be
 * built-in to the kernel image when CONFIG_HYPERV is set
 * (vs. being in a module) because it is called from architecture
 * specific code under arch/.
 *
 * Copyright (C) 2021, Microsoft, Inc.
 *
 * Author : Michael Kelley <[email protected]>
 */

#include <linux/types.h>
#include <linux/acpi.h>
#include <linux/export.h>
#include <linux/bitfield.h>
#include <linux/cpumask.h>
#include <linux/sched/task_stack.h>
#include <linux/panic_notifier.h>
#include <linux/ptrace.h>
#include <linux/random.h>
#include <linux/efi.h>
#include <linux/kdebug.h>
#include <linux/kmsg_dump.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/dma-map-ops.h>
#include <linux/set_memory.h>
#include <asm/hyperv-tlfs.h>
#include <asm/mshyperv.h>

/*
 * hv_root_partition, ms_hyperv and hv_nested are defined here with other
 * Hyper-V specific globals so they are shared across all architectures and are
 * built only when CONFIG_HYPERV is defined.  But on x86,
 * ms_hyperv_init_platform() is built even when CONFIG_HYPERV is not
 * defined, and it uses these three variables.  So mark them as __weak
 * here, allowing for an overriding definition in the module containing
 * ms_hyperv_init_platform().
 */
bool __weak hv_root_partition;
EXPORT_SYMBOL_GPL();

bool __weak hv_nested;
EXPORT_SYMBOL_GPL();

struct ms_hyperv_info __weak ms_hyperv;
EXPORT_SYMBOL_GPL();

u32 *hv_vp_index;
EXPORT_SYMBOL_GPL();

u32 hv_max_vp_index;
EXPORT_SYMBOL_GPL();

void * __percpu *hyperv_pcpu_input_arg;
EXPORT_SYMBOL_GPL();

void * __percpu *hyperv_pcpu_output_arg;
EXPORT_SYMBOL_GPL();

static void hv_kmsg_dump_unregister(void);

static struct ctl_table_header *hv_ctl_table_hdr;

/*
 * Hyper-V specific initialization and shutdown code that is
 * common across all architectures.  Called from architecture
 * specific initialization functions.
 */

void __init hv_common_free(void)
{}

/*
 * Functions for allocating and freeing memory with size and
 * alignment HV_HYP_PAGE_SIZE. These functions are needed because
 * the guest page size may not be the same as the Hyper-V page
 * size. We depend upon kmalloc() aligning power-of-two size
 * allocations to the allocation size boundary, so that the
 * allocated memory appears to Hyper-V as a page of the size
 * it expects.
 */

void *hv_alloc_hyperv_page(void)
{}
EXPORT_SYMBOL_GPL();

void *hv_alloc_hyperv_zeroed_page(void)
{}
EXPORT_SYMBOL_GPL();

void hv_free_hyperv_page(void *addr)
{}
EXPORT_SYMBOL_GPL();

static void *hv_panic_page;

/*
 * Boolean to control whether to report panic messages over Hyper-V.
 *
 * It can be set via /proc/sys/kernel/hyperv_record_panic_msg
 */
static int sysctl_record_panic_msg =;

/*
 * sysctl option to allow the user to control whether kmsg data should be
 * reported to Hyper-V on panic.
 */
static struct ctl_table hv_ctl_table[] =;

static int hv_die_panic_notify_crash(struct notifier_block *self,
				     unsigned long val, void *args);

static struct notifier_block hyperv_die_report_block =;

static struct notifier_block hyperv_panic_report_block =;

/*
 * The following callback works both as die and panic notifier; its
 * goal is to provide panic information to the hypervisor unless the
 * kmsg dumper is used [see hv_kmsg_dump()], which provides more
 * information but isn't always available.
 *
 * Notice that both the panic/die report notifiers are registered only
 * if we have the capability HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE set.
 */
static int hv_die_panic_notify_crash(struct notifier_block *self,
				     unsigned long val, void *args)
{}

/*
 * Callback from kmsg_dump. Grab as much as possible from the end of the kmsg
 * buffer and call into Hyper-V to transfer the data.
 */
static void hv_kmsg_dump(struct kmsg_dumper *dumper,
			 struct kmsg_dump_detail *detail)
{}

static struct kmsg_dumper hv_kmsg_dumper =;

static void hv_kmsg_dump_unregister(void)
{}

static void hv_kmsg_dump_register(void)
{}

int __init hv_common_init(void)
{}

void __init ms_hyperv_late_init(void)
{}

/*
 * Hyper-V specific initialization and die code for
 * individual CPUs that is common across all architectures.
 * Called by the CPU hotplug mechanism.
 */

int hv_common_cpu_init(unsigned int cpu)
{}

int hv_common_cpu_die(unsigned int cpu)
{}

/* Bit mask of the extended capability to query: see HV_EXT_CAPABILITY_xxx */
bool hv_query_ext_cap(u64 cap_query)
{}
EXPORT_SYMBOL_GPL();

void hv_setup_dma_ops(struct device *dev, bool coherent)
{}
EXPORT_SYMBOL_GPL();

bool hv_is_hibernation_supported(void)
{}
EXPORT_SYMBOL_GPL();

/*
 * Default function to read the Hyper-V reference counter, independent
 * of whether Hyper-V enlightened clocks/timers are being used. But on
 * architectures where it is used, Hyper-V enlightenment code in
 * hyperv_timer.c may override this function.
 */
static u64 __hv_read_ref_counter(void)
{}

u64 (*hv_read_reference_counter)(void) =;
EXPORT_SYMBOL_GPL();

/* These __weak functions provide default "no-op" behavior and
 * may be overridden by architecture specific versions. Architectures
 * for which the default "no-op" behavior is sufficient can leave
 * them unimplemented and not be cluttered with a bunch of stub
 * functions in arch-specific code.
 */

bool __weak hv_is_isolation_supported(void)
{}
EXPORT_SYMBOL_GPL();

bool __weak hv_isolation_type_snp(void)
{}
EXPORT_SYMBOL_GPL();

bool __weak hv_isolation_type_tdx(void)
{}
EXPORT_SYMBOL_GPL();

void __weak hv_setup_vmbus_handler(void (*handler)(void))
{}
EXPORT_SYMBOL_GPL();

void __weak hv_remove_vmbus_handler(void)
{}
EXPORT_SYMBOL_GPL();

void __weak hv_setup_kexec_handler(void (*handler)(void))
{}
EXPORT_SYMBOL_GPL();

void __weak hv_remove_kexec_handler(void)
{}
EXPORT_SYMBOL_GPL();

void __weak hv_setup_crash_handler(void (*handler)(struct pt_regs *regs))
{}
EXPORT_SYMBOL_GPL();

void __weak hv_remove_crash_handler(void)
{}
EXPORT_SYMBOL_GPL();

void __weak hyperv_cleanup(void)
{}
EXPORT_SYMBOL_GPL();

u64 __weak hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size)
{}
EXPORT_SYMBOL_GPL();

u64 __weak hv_tdx_hypercall(u64 control, u64 param1, u64 param2)
{}
EXPORT_SYMBOL_GPL();