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