hyperv-tlfs.h defines Hyper-V interfaces from the Hyper-V Top Level Functional Spec (TLFS), and #includes the architecture-independent part of hyperv-tlfs.h in include/asm-generic. The published TLFS is distinctly oriented to x86/x64, so the ARM64-specific hyperv-tlfs.h includes information for ARM64 that is not yet formally published. The TLFS is available here: docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs mshyperv.h defines Linux-specific structures and routines for interacting with Hyper-V on ARM64, and #includes the architecture- independent part of mshyperv.h in include/asm-generic. Signed-off-by: Michael Kelley <mikelley@xxxxxxxxxxxxx> --- MAINTAINERS | 2 + arch/arm64/include/asm/hyperv-tlfs.h | 94 ++++++++++++++++++++++++++++++++++++ arch/arm64/include/asm/mshyperv.h | 76 +++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 arch/arm64/include/asm/hyperv-tlfs.h create mode 100644 arch/arm64/include/asm/mshyperv.h diff --git a/MAINTAINERS b/MAINTAINERS index 4179dfa..803bade 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8054,6 +8054,8 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git F: Documentation/ABI/stable/sysfs-bus-vmbus F: Documentation/ABI/testing/debugfs-hyperv F: Documentation/networking/device_drivers/ethernet/microsoft/netvsc.rst +F: arch/arm64/include/asm/hyperv-tlfs.h +F: arch/arm64/include/asm/mshyperv.h F: arch/x86/hyperv F: arch/x86/include/asm/hyperv-tlfs.h F: arch/x86/include/asm/mshyperv.h diff --git a/arch/arm64/include/asm/hyperv-tlfs.h b/arch/arm64/include/asm/hyperv-tlfs.h new file mode 100644 index 0000000..09f5228 --- /dev/null +++ b/arch/arm64/include/asm/hyperv-tlfs.h @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * This file contains definitions from the Hyper-V Hypervisor Top-Level + * Functional Specification (TLFS): + * https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs + * + * Copyright (C) 2019, Microsoft, Inc. + * + * Author : Michael Kelley <mikelley@xxxxxxxxxxxxx> + */ + +#ifndef _ASM_HYPERV_TLFS_H +#define _ASM_HYPERV_TLFS_H + +#include <linux/types.h> + +/* + * All data structures defined in the TLFS that are shared between Hyper-V + * and a guest VM use Little Endian byte ordering. This matches the default + * byte ordering of Linux running on ARM64, so no special handling is required. + */ + +/* + * These Hyper-V registers provide information equivalent to the CPUID + * instruction on x86/x64. + */ +#define HV_REGISTER_HYPERVISOR_VERSION 0x00000100 /*CPUID 0x40000002 */ +#define HV_REGISTER_FEATURES 0x00000200 /*CPUID 0x40000003 */ +#define HV_REGISTER_ENLIGHTENMENTS 0x00000201 /*CPUID 0x40000004 */ + +/* + * Group C Features. See the asm-generic version of hyperv-tlfs.h + * for a description of Feature Groups. + */ + +/* Crash MSRs available */ +#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE BIT(8) + +/* STIMER direct mode is available */ +#define HV_STIMER_DIRECT_MODE_AVAILABLE BIT(13) + +/* + * Synthetic register definitions equivalent to MSRs on x86/x64 + */ +#define HV_REGISTER_CRASH_P0 0x00000210 +#define HV_REGISTER_CRASH_P1 0x00000211 +#define HV_REGISTER_CRASH_P2 0x00000212 +#define HV_REGISTER_CRASH_P3 0x00000213 +#define HV_REGISTER_CRASH_P4 0x00000214 +#define HV_REGISTER_CRASH_CTL 0x00000215 + +#define HV_REGISTER_GUEST_OSID 0x00090002 +#define HV_REGISTER_VPINDEX 0x00090003 +#define HV_REGISTER_TIME_REFCOUNT 0x00090004 +#define HV_REGISTER_REFERENCE_TSC 0x00090017 + +#define HV_REGISTER_SINT0 0x000A0000 +#define HV_REGISTER_SCONTROL 0x000A0010 +#define HV_REGISTER_SIFP 0x000A0012 +#define HV_REGISTER_SIPP 0x000A0013 +#define HV_REGISTER_EOM 0x000A0014 + +#define HV_REGISTER_STIMER0_CONFIG 0x000B0000 +#define HV_REGISTER_STIMER0_COUNT 0x000B0001 + +/* + * Define hypervisor message types. These must be + * included in the architecture specific hyperv-tlfs.h + * because there are processor specific values on the + * x86 side. + */ +enum hv_message_type { + HVMSG_NONE = 0x00000000, + + /* Memory access messages. */ + HVMSG_UNMAPPED_GPA = 0x80000000, + HVMSG_GPA_INTERCEPT = 0x80000001, + + /* Timer notification messages. */ + HVMSG_TIMER_EXPIRED = 0x80000010, + + /* Error messages. */ + HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020, + HVMSG_UNRECOVERABLE_EXCEPTION = 0x80000021, + HVMSG_UNSUPPORTED_FEATURE = 0x80000022, + + /* Trace buffer complete messages. */ + HVMSG_EVENTLOG_BUFFERCOMPLETE = 0x80000040, +}; + +#include <asm-generic/hyperv-tlfs.h> + +#endif diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h new file mode 100644 index 0000000..6b1f26c --- /dev/null +++ b/arch/arm64/include/asm/mshyperv.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * Linux-specific definitions for managing interactions with Microsoft's + * Hyper-V hypervisor. The definitions in this file are specific to + * the ARM64 architecture. See include/asm-generic/mshyperv.h for + * definitions are that architecture independent. + * + * Definitions that are specified in the Hyper-V Top Level Functional + * Spec (TLFS) should not go in this file, but should instead go in + * hyperv-tlfs.h. + * + * Copyright (C) 2019, Microsoft, Inc. + * + * Author : Michael Kelley <mikelley@xxxxxxxxxxxxx> + */ + +#ifndef _ASM_MSHYPERV_H +#define _ASM_MSHYPERV_H + +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/clocksource.h> +#include <linux/irq.h> +#include <linux/irqdesc.h> +#include <linux/arm-smccc.h> +#include <asm/hyperv-tlfs.h> + +/* Access various Hyper-V synthetic registers */ +static inline void hv_set_simp(u64 val) +{ + hv_set_vpreg(HV_REGISTER_SIPP, val); +} + +#define hv_get_simp(val) (val = hv_get_vpreg(HV_REGISTER_SIPP)) + +static inline void hv_set_siefp(u64 val) +{ + hv_set_vpreg(HV_REGISTER_SIFP, val); +} + +#define hv_get_siefp(val) (val = hv_get_vpreg(HV_REGISTER_SIFP)) + +static inline void hv_set_synic_state(u64 val) +{ + hv_set_vpreg(HV_REGISTER_SCONTROL, val); +} + +#define hv_get_synic_state(val) (val = hv_get_vpreg(HV_REGISTER_SCONTROL)) + +static inline bool hv_recommend_using_aeoi(void) +{ + return false; +} + +static inline void hv_signal_eom(void) +{ + hv_set_vpreg(HV_REGISTER_EOM, 0); +} + +/* + * Hyper-V SINT registers are numbered sequentially, so we can just + * add the SINT number to the register number of SINT0 + */ + +static inline void hv_set_synint_state(u32 sint_num, u64 val) +{ + hv_set_vpreg(HV_REGISTER_SINT0 + sint_num, val); +} + +#define hv_get_synint_state(sint_num, val) \ + (val = hv_get_vpreg(HV_REGISTER_SINT0 + sint_num)) + +#include <asm-generic/mshyperv.h> + +#endif -- 1.8.3.1