概述¶
Linux 核心包含各種程式碼,用於在 Microsoft 的 Hyper-V 虛擬機器監控程式上作為完全啟用的來賓執行。Hyper-V 主要由裸機虛擬機器監控程式以及在父分割槽中執行的虛擬機器管理服務組成(大致相當於 KVM 和 QEMU 等)。來賓 VM 在子分割槽中執行。 在本文件中,對 Hyper-V 的引用通常包括虛擬機器監控程式和 VMM 服務,而不區分哪些功能由哪個元件提供。
Hyper-V 在 x86/x64 和 arm64 架構上執行,並且兩種架構都支援 Linux 來賓。除非另有說明,否則 Hyper-V 的功能和行為在兩種架構上通常是相同的。
Linux 來賓與 Hyper-V 的通訊¶
Linux 來賓透過四種不同的方式與 Hyper-V 通訊
隱式陷阱:按照 x86/x64 或 arm64 架構的定義,某些來賓操作會陷阱到 Hyper-V。Hyper-V 模擬該操作並將控制權返回給來賓。這種行為通常對 Linux 核心不可見。
顯式超呼叫:Linux 對 Hyper-V 進行顯式函式呼叫,傳遞引數。Hyper-V 執行請求的操作並將控制權返回給呼叫者。引數在處理器暫存器中或 Linux 來賓和 Hyper-V 之間共享的記憶體中傳遞。在 x86/x64 上,超呼叫使用 Hyper-V 特定的呼叫序列。在 arm64 上,超呼叫使用 ARM 標準 SMCCC 呼叫序列。
合成暫存器訪問:Hyper-V 實現了各種合成暫存器。在 x86/x64 上,這些暫存器以 MSR 的形式出現在來賓中,並且 Linux 核心可以使用 x86/x64 架構定義的正常機制來讀取或寫入這些 MSR。在 arm64 上,必須使用顯式超呼叫來訪問這些合成暫存器。
VMBus:VMBus 是一個更高層次的軟體構造,它建立在其他 3 個機制之上。它是 Hyper-V 主機和 Linux 來賓之間的訊息傳遞介面。它使用 Hyper-V 和來賓之間共享的記憶體,以及各種信令機制。
前三種通訊機制記錄在 Hyper-V 頂層功能規範 (TLFS) 中。TLFS 描述了 Hyper-V 的一般功能,並提供了有關超呼叫和合成暫存器的詳細資訊。TLFS 目前僅針對 x86/x64 架構編寫。
VMBus 沒有記錄。本文件提供了 VMBus 的高階概述及其工作方式,但詳細資訊只能從程式碼中辨別出來。
CPU 管理¶
Hyper-V 無法從正在執行的 VM 熱新增或熱刪除 CPU。 但是,Windows Server 2019 Hyper-V 及更早版本可能會為來賓提供 ACPI 表,指示的 CPU 數量多於 VM 中實際存在的 CPU 數量。 像往常一樣,Linux 將這些額外的 CPU 視為潛在的熱新增 CPU,並將其報告為這樣,即使 Hyper-V 永遠不會實際熱新增它們。 從 Windows Server 2022 Hyper-V 開始,ACPI 表僅反映 VM 中實際存在的 CPU,因此 Linux 不會報告任何熱新增 CPU。
可以使用正常的 Linux 機制將 Linux 來賓 CPU 離線,前提是沒有 VMBus 通道中斷分配給該 CPU。 有關如何重新分配 VMBus 通道中斷以允許將 CPU 離線的更多詳細資訊,請參閱有關 VMBus 中斷的部分。
32 位和 64 位¶
在 x86/x64 上,Hyper-V 支援 32 位和 64 位來賓,並且 Linux 將構建並以任一版本執行。 雖然 32 位版本預計可以工作,但很少使用,並且可能遭受未檢測到的迴歸。
在 arm64 上,Hyper-V 僅支援 64 位來賓。
位元組順序¶
Hyper-V 和來賓 VM 之間的所有通訊都使用小端格式,無論是在 x86/x64 還是 arm64 上。 Hyper-V 不支援 arm64 上的大端格式,並且 Linux 程式碼在訪問與 Hyper-V 共享的資料時不使用位元組順序宏。
版本控制¶
當前的 Linux 核心可以與 Windows Server 2012 Hyper-V 的舊版 Hyper-V 正常執行。 對在 Windows Server 2008/2008 R2 的原始 Hyper-V 版本上執行的支援已被刪除。
Hyper-V 上的 Linux 來賓會在 dmesg 中輸出其執行的 Hyper-V 版本。 此版本採用 Windows 內部版本號的形式,僅用於顯示目的。 Linux 程式碼不會在執行時測試此版本號,以確定可用的特性和功能。 Hyper-V 透過 Hyper-V 提供給來賓的合成 MSR 中的標誌指示特性/功能可用性,並且來賓程式碼會測試這些標誌。
VMBus 有其自己的協議版本,該版本在來賓到 Hyper-V 的初始 VMBus 連線期間協商。 此版本號也在啟動期間輸出到 dmesg。 程式碼中的一些位置會檢查此版本號,以確定是否存在特定功能。
此外,VMBus 上的每個合成裝置也有一個協議版本,該版本與 VMBus 協議版本分開。 這些合成裝置的裝置驅動程式通常會協商裝置協議版本,並且可能會測試該協議版本以確定是否存在特定裝置功能。
程式碼打包¶
與 Hyper-V 相關的程式碼出現在 Linux 核心程式碼樹中的三個主要區域
drivers/hv
arch/x86/hyperv 和 arch/arm64/hyperv
各個裝置驅動程式區域,例如 drivers/scsi、drivers/net、drivers/clocksource 等。
一些雜項檔案出現在其他位置。 請參閱 MAINTAINERS 檔案中“Hyper-V/Azure 核心和驅動程式”和“適用於 HyperV 合成影片裝置的 DRM 驅動程式”下的完整列表。
只有在設定了 CONFIG_HYPERV 時,才會構建 #1 和 #2 中的程式碼。 同樣,只有在設定了 CONFIG_HYPERV 時,才會構建大多數與 Hyper-V 相關的驅動程式的程式碼。
#1 和 #3 中的大多數與 Hyper-V 相關的程式碼都可以構建為模組。 #2 中的特定於架構的程式碼必須內建。 此外,drivers/hv/hv_common.c 是跨架構的通用底層程式碼,必須內建。