162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci
362306a36Sopenharmony_ciOverview
462306a36Sopenharmony_ci========
562306a36Sopenharmony_ciThe Linux kernel contains a variety of code for running as a fully
662306a36Sopenharmony_cienlightened guest on Microsoft's Hyper-V hypervisor.  Hyper-V
762306a36Sopenharmony_ciconsists primarily of a bare-metal hypervisor plus a virtual machine
862306a36Sopenharmony_cimanagement service running in the parent partition (roughly
962306a36Sopenharmony_ciequivalent to KVM and QEMU, for example).  Guest VMs run in child
1062306a36Sopenharmony_cipartitions.  In this documentation, references to Hyper-V usually
1162306a36Sopenharmony_ciencompass both the hypervisor and the VMM service without making a
1262306a36Sopenharmony_cidistinction about which functionality is provided by which
1362306a36Sopenharmony_cicomponent.
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ciHyper-V runs on x86/x64 and arm64 architectures, and Linux guests
1662306a36Sopenharmony_ciare supported on both.  The functionality and behavior of Hyper-V is
1762306a36Sopenharmony_cigenerally the same on both architectures unless noted otherwise.
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ciLinux Guest Communication with Hyper-V
2062306a36Sopenharmony_ci--------------------------------------
2162306a36Sopenharmony_ciLinux guests communicate with Hyper-V in four different ways:
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci* Implicit traps: As defined by the x86/x64 or arm64 architecture,
2462306a36Sopenharmony_ci  some guest actions trap to Hyper-V.  Hyper-V emulates the action and
2562306a36Sopenharmony_ci  returns control to the guest.  This behavior is generally invisible
2662306a36Sopenharmony_ci  to the Linux kernel.
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci* Explicit hypercalls: Linux makes an explicit function call to
2962306a36Sopenharmony_ci  Hyper-V, passing parameters.  Hyper-V performs the requested action
3062306a36Sopenharmony_ci  and returns control to the caller.  Parameters are passed in
3162306a36Sopenharmony_ci  processor registers or in memory shared between the Linux guest and
3262306a36Sopenharmony_ci  Hyper-V.   On x86/x64, hypercalls use a Hyper-V specific calling
3362306a36Sopenharmony_ci  sequence.  On arm64, hypercalls use the ARM standard SMCCC calling
3462306a36Sopenharmony_ci  sequence.
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci* Synthetic register access: Hyper-V implements a variety of
3762306a36Sopenharmony_ci  synthetic registers.  On x86/x64 these registers appear as MSRs in
3862306a36Sopenharmony_ci  the guest, and the Linux kernel can read or write these MSRs using
3962306a36Sopenharmony_ci  the normal mechanisms defined by the x86/x64 architecture.  On
4062306a36Sopenharmony_ci  arm64, these synthetic registers must be accessed using explicit
4162306a36Sopenharmony_ci  hypercalls.
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci* VMbus: VMbus is a higher-level software construct that is built on
4462306a36Sopenharmony_ci  the other 3 mechanisms.  It is a message passing interface between
4562306a36Sopenharmony_ci  the Hyper-V host and the Linux guest.  It uses memory that is shared
4662306a36Sopenharmony_ci  between Hyper-V and the guest, along with various signaling
4762306a36Sopenharmony_ci  mechanisms.
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ciThe first three communication mechanisms are documented in the
5062306a36Sopenharmony_ci`Hyper-V Top Level Functional Spec (TLFS)`_.  The TLFS describes
5162306a36Sopenharmony_cigeneral Hyper-V functionality and provides details on the hypercalls
5262306a36Sopenharmony_ciand synthetic registers.  The TLFS is currently written for the
5362306a36Sopenharmony_cix86/x64 architecture only.
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci.. _Hyper-V Top Level Functional Spec (TLFS): https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ciVMbus is not documented.  This documentation provides a high-level
5862306a36Sopenharmony_cioverview of VMbus and how it works, but the details can be discerned
5962306a36Sopenharmony_cionly from the code.
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ciSharing Memory
6262306a36Sopenharmony_ci--------------
6362306a36Sopenharmony_ciMany aspects are communication between Hyper-V and Linux are based
6462306a36Sopenharmony_cion sharing memory.  Such sharing is generally accomplished as
6562306a36Sopenharmony_cifollows:
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci* Linux allocates memory from its physical address space using
6862306a36Sopenharmony_ci  standard Linux mechanisms.
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci* Linux tells Hyper-V the guest physical address (GPA) of the
7162306a36Sopenharmony_ci  allocated memory.  Many shared areas are kept to 1 page so that a
7262306a36Sopenharmony_ci  single GPA is sufficient.   Larger shared areas require a list of
7362306a36Sopenharmony_ci  GPAs, which usually do not need to be contiguous in the guest
7462306a36Sopenharmony_ci  physical address space.  How Hyper-V is told about the GPA or list
7562306a36Sopenharmony_ci  of GPAs varies.  In some cases, a single GPA is written to a
7662306a36Sopenharmony_ci  synthetic register.  In other cases, a GPA or list of GPAs is sent
7762306a36Sopenharmony_ci  in a VMbus message.
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci* Hyper-V translates the GPAs into "real" physical memory addresses,
8062306a36Sopenharmony_ci  and creates a virtual mapping that it can use to access the memory.
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci* Linux can later revoke sharing it has previously established by
8362306a36Sopenharmony_ci  telling Hyper-V to set the shared GPA to zero.
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ciHyper-V operates with a page size of 4 Kbytes. GPAs communicated to
8662306a36Sopenharmony_ciHyper-V may be in the form of page numbers, and always describe a
8762306a36Sopenharmony_cirange of 4 Kbytes.  Since the Linux guest page size on x86/x64 is
8862306a36Sopenharmony_cialso 4 Kbytes, the mapping from guest page to Hyper-V page is 1-to-1.
8962306a36Sopenharmony_ciOn arm64, Hyper-V supports guests with 4/16/64 Kbyte pages as
9062306a36Sopenharmony_cidefined by the arm64 architecture.   If Linux is using 16 or 64
9162306a36Sopenharmony_ciKbyte pages, Linux code must be careful to communicate with Hyper-V
9262306a36Sopenharmony_cionly in terms of 4 Kbyte pages.  HV_HYP_PAGE_SIZE and related macros
9362306a36Sopenharmony_ciare used in code that communicates with Hyper-V so that it works
9462306a36Sopenharmony_cicorrectly in all configurations.
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ciAs described in the TLFS, a few memory pages shared between Hyper-V
9762306a36Sopenharmony_ciand the Linux guest are "overlay" pages.  With overlay pages, Linux
9862306a36Sopenharmony_ciuses the usual approach of allocating guest memory and telling
9962306a36Sopenharmony_ciHyper-V the GPA of the allocated memory.  But Hyper-V then replaces
10062306a36Sopenharmony_cithat physical memory page with a page it has allocated, and the
10162306a36Sopenharmony_cioriginal physical memory page is no longer accessible in the guest
10262306a36Sopenharmony_ciVM.  Linux may access the memory normally as if it were the memory
10362306a36Sopenharmony_cithat it originally allocated.  The "overlay" behavior is visible
10462306a36Sopenharmony_cionly because the contents of the page (as seen by Linux) change at
10562306a36Sopenharmony_cithe time that Linux originally establishes the sharing and the
10662306a36Sopenharmony_cioverlay page is inserted.  Similarly, the contents change if Linux
10762306a36Sopenharmony_cirevokes the sharing, in which case Hyper-V removes the overlay page,
10862306a36Sopenharmony_ciand the guest page originally allocated by Linux becomes visible
10962306a36Sopenharmony_ciagain.
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ciBefore Linux does a kexec to a kdump kernel or any other kernel,
11262306a36Sopenharmony_cimemory shared with Hyper-V should be revoked.  Hyper-V could modify
11362306a36Sopenharmony_cia shared page or remove an overlay page after the new kernel is
11462306a36Sopenharmony_ciusing the page for a different purpose, corrupting the new kernel.
11562306a36Sopenharmony_ciHyper-V does not provide a single "set everything" operation to
11662306a36Sopenharmony_ciguest VMs, so Linux code must individually revoke all sharing before
11762306a36Sopenharmony_cidoing kexec.   See hv_kexec_handler() and hv_crash_handler().  But
11862306a36Sopenharmony_cithe crash/panic path still has holes in cleanup because some shared
11962306a36Sopenharmony_cipages are set using per-CPU synthetic registers and there's no
12062306a36Sopenharmony_cimechanism to revoke the shared pages for CPUs other than the CPU
12162306a36Sopenharmony_cirunning the panic path.
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ciCPU Management
12462306a36Sopenharmony_ci--------------
12562306a36Sopenharmony_ciHyper-V does not have a ability to hot-add or hot-remove a CPU
12662306a36Sopenharmony_cifrom a running VM.  However, Windows Server 2019 Hyper-V and
12762306a36Sopenharmony_ciearlier versions may provide guests with ACPI tables that indicate
12862306a36Sopenharmony_cimore CPUs than are actually present in the VM.  As is normal, Linux
12962306a36Sopenharmony_citreats these additional CPUs as potential hot-add CPUs, and reports
13062306a36Sopenharmony_cithem as such even though Hyper-V will never actually hot-add them.
13162306a36Sopenharmony_ciStarting in Windows Server 2022 Hyper-V, the ACPI tables reflect
13262306a36Sopenharmony_cionly the CPUs actually present in the VM, so Linux does not report
13362306a36Sopenharmony_ciany hot-add CPUs.
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ciA Linux guest CPU may be taken offline using the normal Linux
13662306a36Sopenharmony_cimechanisms, provided no VMbus channel interrupts are assigned to
13762306a36Sopenharmony_cithe CPU.  See the section on VMbus Interrupts for more details
13862306a36Sopenharmony_cion how VMbus channel interrupts can be re-assigned to permit
13962306a36Sopenharmony_citaking a CPU offline.
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci32-bit and 64-bit
14262306a36Sopenharmony_ci-----------------
14362306a36Sopenharmony_ciOn x86/x64, Hyper-V supports 32-bit and 64-bit guests, and Linux
14462306a36Sopenharmony_ciwill build and run in either version. While the 32-bit version is
14562306a36Sopenharmony_ciexpected to work, it is used rarely and may suffer from undetected
14662306a36Sopenharmony_ciregressions.
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ciOn arm64, Hyper-V supports only 64-bit guests.
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ciEndian-ness
15162306a36Sopenharmony_ci-----------
15262306a36Sopenharmony_ciAll communication between Hyper-V and guest VMs uses Little-Endian
15362306a36Sopenharmony_ciformat on both x86/x64 and arm64.  Big-endian format on arm64 is not
15462306a36Sopenharmony_cisupported by Hyper-V, and Linux code does not use endian-ness macros
15562306a36Sopenharmony_ciwhen accessing data shared with Hyper-V.
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ciVersioning
15862306a36Sopenharmony_ci----------
15962306a36Sopenharmony_ciCurrent Linux kernels operate correctly with older versions of
16062306a36Sopenharmony_ciHyper-V back to Windows Server 2012 Hyper-V. Support for running
16162306a36Sopenharmony_cion the original Hyper-V release in Windows Server 2008/2008 R2
16262306a36Sopenharmony_cihas been removed.
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ciA Linux guest on Hyper-V outputs in dmesg the version of Hyper-V
16562306a36Sopenharmony_ciit is running on.  This version is in the form of a Windows build
16662306a36Sopenharmony_cinumber and is for display purposes only. Linux code does not
16762306a36Sopenharmony_citest this version number at runtime to determine available features
16862306a36Sopenharmony_ciand functionality. Hyper-V indicates feature/function availability
16962306a36Sopenharmony_civia flags in synthetic MSRs that Hyper-V provides to the guest,
17062306a36Sopenharmony_ciand the guest code tests these flags.
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ciVMbus has its own protocol version that is negotiated during the
17362306a36Sopenharmony_ciinitial VMbus connection from the guest to Hyper-V. This version
17462306a36Sopenharmony_cinumber is also output to dmesg during boot.  This version number
17562306a36Sopenharmony_ciis checked in a few places in the code to determine if specific
17662306a36Sopenharmony_cifunctionality is present.
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ciFurthermore, each synthetic device on VMbus also has a protocol
17962306a36Sopenharmony_civersion that is separate from the VMbus protocol version. Device
18062306a36Sopenharmony_cidrivers for these synthetic devices typically negotiate the device
18162306a36Sopenharmony_ciprotocol version, and may test that protocol version to determine
18262306a36Sopenharmony_ciif specific device functionality is present.
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ciCode Packaging
18562306a36Sopenharmony_ci--------------
18662306a36Sopenharmony_ciHyper-V related code appears in the Linux kernel code tree in three
18762306a36Sopenharmony_cimain areas:
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci1. drivers/hv
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci2. arch/x86/hyperv and arch/arm64/hyperv
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci3. individual device driver areas such as drivers/scsi, drivers/net,
19462306a36Sopenharmony_ci   drivers/clocksource, etc.
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ciA few miscellaneous files appear elsewhere. See the full list under
19762306a36Sopenharmony_ci"Hyper-V/Azure CORE AND DRIVERS" and "DRM DRIVER FOR HYPERV
19862306a36Sopenharmony_ciSYNTHETIC VIDEO DEVICE" in the MAINTAINERS file.
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ciThe code in #1 and #2 is built only when CONFIG_HYPERV is set.
20162306a36Sopenharmony_ciSimilarly, the code for most Hyper-V related drivers is built only
20262306a36Sopenharmony_ciwhen CONFIG_HYPERV is set.
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ciMost Hyper-V related code in #1 and #3 can be built as a module.
20562306a36Sopenharmony_ciThe architecture specific code in #2 must be built-in.  Also,
20662306a36Sopenharmony_cidrivers/hv/hv_common.c is low-level code that is common across
20762306a36Sopenharmony_ciarchitectures and must be built-in.
208