共用方式為


Hypercall 介面

Hypervisor 提供來賓的呼叫機制。 這類呼叫稱為超calls。 每個超應用程式都會定義一組輸入和/或輸出參數。 這些參數是以記憶體為基礎的資料結構來指定。 輸入和輸出資料結構的所有元素都會填補到最多 8 個位元組的自然界限, (也就是說,雙位元組元素必須位於兩位元組界限上,依此類) 。

第二個超呼叫慣例可以選擇性地用於超calls 的子集,特別是具有兩個或更少輸入參數且沒有輸出參數的子集。 使用此呼叫慣例時,輸入參數會以一般用途暫存器傳遞。

第三個超呼叫慣例可以選擇性地用於超calls 子集,其中輸入參數區塊最多為 112 個位元組。 使用此呼叫慣例時,輸入參數會傳入暫存器,包括 volatile XMM 暫存器。

輸入和輸出資料結構必須放在記憶體中的 8 位元組界限上,並填補成大小為 8 個位元組的倍數。 Hypervisor 會忽略填補區域內的值。

針對輸出,Hypervisor 可以 (,但不保證) 覆寫填補區域。 如果覆寫填補區域,則會寫入零。

Hypercall 類別

超calls 有兩個類別:simple 和 rep (short for 「repeat」) 。 簡單的 Hypercall 會執行單一作業,並具有一組固定大小的輸入和輸出參數。 rep hypercall 的作用就像是一系列簡單的超calls。 除了固定大小的輸入和輸出參數集外,rep 超calls 還牽涉到固定大小的輸入及/或輸出元素清單。

當呼叫端一開始叫用 rep hypercall 時,它會指定代表輸入和/或輸出參數清單中的元素數目的 rep 計數。 呼叫端也會指定代表應該取用的下一個輸入及/或輸出元素的重新開始索引。 Hypervisor 會依清單連續處理 rep 參數,也就是藉由增加元素索引。

針對 rep hypercall 的後續叫用,rep start 索引會指出已完成多少個元素–以及與 rep count 值結合 – 剩餘多少個元素。 例如,如果呼叫端指定了 25 個 rep 計數,而且在時間限制內只有 20 個反復專案完成,Hypercall 會在將 rep start index 更新為 20 之後,將控制權傳回給呼叫虛擬處理器。 重新執行 Hypercall 時,Hypervisor 會在元素 20 繼續執行,並完成剩餘的 5 個元素。

如果在處理專案時發生錯誤,則會提供適當的狀態碼以及代表已完成的計數,指出在發生錯誤之前已成功處理的元素數目。 假設指定的 Hypercall 控制字有效, (看到下列) ,而且可存取輸入/輸出參數清單,Hypervisor 保證至少嘗試一個 rep,但不需要處理整個清單,再將控制權傳回給呼叫端。

Hypercall 接續

超安裝可視為需要許多週期的複雜指令。 Hypervisor 會先嘗試將 hypercall 執行限制為 50 個或更少,再將控制權傳回叫用 hypercall 的虛擬處理器。 某些超安裝作業已足夠複雜,50μs 保證難以進行。 因此,Hypervisor 會依賴某些超calls 的超安裝接續機制,包括所有 rep hypercall 表單。

超安裝接續機制對呼叫端而言大部分都是透明的。 如果 hypercall 無法在指定的時間限制內完成,則會將控制權傳回給呼叫端,但指令指標不會進階到叫用 hypercall 的指令。 這可讓擱置中斷處理,並排程其他虛擬處理器。 當原始呼叫執行緒繼續執行時,它會重新執行超安裝指令,並繼續進行完成作業的進度。

大部分簡單的超calls 保證會在指定的時間限制內完成。 不過,少量的簡單超calls 可能需要更多時間。 這些超calls 會以類似方式使用超標籤接續來代表超calls。 在這種情況下,作業牽涉到兩個以上的內部狀態。 第一個調用會將物件 (,例如,分割區或虛擬處理器) 成為一個狀態,然後在重複調用之後,狀態最後會轉換為終端狀態。 針對遵循此模式的每個超安裝,會描述中繼內部狀態的可見副作用。

超不可部分完成性和排序

除非另有說明,Hypercall 所執行的動作與所有其他客體作業 (有關,例如客體) 內執行的指令,以及系統上執行的所有其他超calls。 簡單的 Hypercall 會執行單一不可部分完成的動作;rep hypercall 會執行多個獨立不可部分完成的動作。

使用 hypercall 接續的簡單超calls 可能會牽涉到外部可見的多個內部狀態。 這類呼叫包含多個不可部分完成的作業。

每個超安裝動作都可以讀取輸入參數和/或寫入結果。 每個動作的輸入都可以在任何資料細微性上讀取,以及在執行動作之前,隨時讀取超安裝。 結果 (也就是說,與每個動作相關聯的輸出參數) 可能會以任何細微性寫入,而且在執行動作之後,以及超安裝傳回之前的任何時間。

來賓必須避免檢查和/或操作任何與執行超安裝相關的輸入或輸出參數。 雖然執行 Hypercall 的虛擬處理器無法執行這項操作, (因為其客體執行暫停,直到 hypercall 傳回) 為止,但沒有任何動作可防止其他虛擬處理器這麼做。 來賓以這種方式運作可能會當機,或造成其分割區內的損毀。

超calls 只能從最具特殊許可權的客體處理器模式叫用。 在 x64 平臺上,這表示具有目前許可權等級的受保護模式, (CPL) 為零。 雖然實際模式程式碼會以有效 CPL 零執行,但不允許在真真實模式中使用超calls。 嘗試在不合法的處理器模式內叫用超call,將會產生#UD (未定義的作業) 例外狀況。

所有超calls 都應該透過架構定義的超call 介面來叫用, (請參閱下面的) 。 例如,嘗試透過任何其他方式叫用 hypercall (,將程式碼從 hypercall 字碼頁複製到替代位置,並從該處執行,) 可能會導致未定義的作業 (#UD) 例外狀況。 Hypervisor 不保證會傳遞此例外狀況。

對齊需求

呼叫端必須指定輸入和/或輸出參數的 64 位客體實體位址 (GPA) 。 GPA 指標必須對齊 8 位元組。 如果 Hypercall 未涉及任何輸入或輸出參數,Hypervisor 會忽略對應的 GPA 指標。

輸入和輸出參數清單不能重迭或跨越頁面界限。 Hypercall 輸入和輸出頁面必須是 GPA 頁面,而不是「重迭」頁面。 如果虛擬處理器將輸入參數寫入重迭頁面,並在此頁面內指定 GPA,則未定義輸入參數清單的 Hypervisor 存取權。

Hypervisor 會先驗證呼叫的資料分割是否可以從輸入頁面讀取,然後再執行要求的 Hypercall。 此驗證封裝含兩項檢查:指定的 GPA 已對應,且 GPA 標示為可讀取。 如果其中一項測試失敗,Hypervisor 會產生記憶體攔截訊息。 對於具有輸出參數的超calls,Hypervisor 會驗證分割區是否可以寫入輸出頁面。 此驗證封裝含兩項檢查:指定的 GPA 已對應,且 GPA 會標示為可寫入。

Hypercall 輸入

呼叫端會以稱為 hypercall 輸入值的 64 位值來指定超值。 格式如下:

欄位 Bits 提供的資訊
呼叫程式碼 15-0 指定要求哪些超安裝
快速 16 指定 Hypercall 是否使用以暫存器為基礎的呼叫慣例:0 = 記憶體型,1 = 暫存器型
可變標頭大小 26-17 QWORDS 中變數標頭的大小。
RsvdZ 30-27 必須是零
為巢狀 31 指定巢狀環境中的 L0 Hypervisor 應該處理超安裝。
Rep 計數 43-32 代表通話的轉接 (總數必須為零,否則)
RsvdZ 47-44 必須是零
Rep Start Index 59-48 啟動代表呼叫的索引 (必須為零,否則為零)
RsvdZ 63-60 必須是零

針對 rep 超calls,[rep count] 欄位會指出代表代表總數。 rep start index 表示相對於清單開頭的特定重複, (零表示清單中第一個專案要處理) 。 因此,rep 計數值必須一律大於 rep 開始索引。

當 Fast 旗標為零時,註冊超安裝輸入的對應:

x64 x86 提供的資訊
RCX EDX:EAX Hypercall 輸入值
RDX EBX:ECX 輸入參數 GPA
R8 EDI:ESI 輸出參數 GPA

超預存輸入值會連同指向輸入和輸出參數的 GPA 一起傳入暫存器。

在 x64 上,暫存器對應取決於呼叫者是在 32 位 (x86) 或 64 位 (x64) 模式中執行。 Hypervisor 會根據 EFER 的值來判斷呼叫者的模式。LMA 和 CS.L。 如果同時設定這兩個旗標,則呼叫端會假設為 64 位呼叫端。

當 Fast 旗標為其中一個時,註冊超安裝輸入的對應:

x64 x86 提供的資訊
RCX EDX:EAX Hypercall 輸入值
RDX EBX:ECX 輸入參數
R8 EDI:ESI 輸出參數

超預存輸入值會連同輸入參數一起傳入暫存器。

可變大小的 Hypercall 輸入標頭

大部分超應用程式輸入標頭都有固定的大小。 因此,Hypercall 程式碼會隱含指定從客體傳遞至 Hypervisor 的標頭資料量,因此不需要個別指定。 不過,某些超calls 需要可變數量的標頭資料。 這些超calls 通常具有固定大小的輸入標頭,以及其他大小為可變大小的標頭輸入。

可變大小的標頭類似于固定超大量輸入 (對齊 8 個位元組,且大小為 8 個位元組的倍數) 。 呼叫端必須指定它提供多少資料做為輸入標頭。 此大小會作為超集合輸入值的一部分提供, (請參閱上方表格中的「變數標頭大小」) 。

由於固定標頭大小是隱含的,而不是提供總標頭大小,因此輸入控制項中只會提供變數部分:

Variable Header Bytes = {Total Header Bytes - sizeof(Fixed Header)} rounded up to nearest multiple of 8

Variable HeaderSize = Variable Header Bytes / 8

針對未明確記載為接受可變大小的輸入標頭標頭的 Hypercall 指定非零的變數標頭大小不合法。 在這種情況下,超安裝將會產生 的 HV_STATUS_INVALID_HYPERCALL_INPUT 傳回碼。

針對超call 的指定調用,可能會接受所有標頭輸入完全符合固定大小標頭的可變大小輸入標頭。 在這種情況下,可變大小的輸入標頭會是零大小,而且超安裝輸入中的對應位應該設定為零。

在所有其他方面,接受可變大小輸入標頭的超calls,與與呼叫慣例相關的固定大小輸入標頭超calls 類似。 也可以讓可變大小的標頭超call 額外支援 rep 語意。 在這種情況下,rep 元素會以一般方式在標頭後面,不同之處在于標頭的總大小同時包含固定和變數部分。 所有其他規則都保持不變,例如第一個 rep 元素必須對齊 8 個位元組。

XMM Fast Hypercall 輸入

在 x64 平臺上,Hypervisor 支援使用 XMM 快速超calls,這可讓某些超calls 利用快速超大型介面的改善效能,即使它們需要兩個以上的輸入參數也一樣。 XMM 快速超安裝介面會使用六個 XMM 暫存器,讓呼叫端傳遞輸入參數區塊,大小上限為 112 個位元組。

XMM 快速超安裝介面的可用性會透過「Hypervisor 功能識別」CPUID 分葉 (0x40000003) 來指出:

  • 位 4:支援透過 XMM 暫存器傳遞超安裝輸入。

請注意,有個別旗標可指出 XMM 快速輸出的支援。 當 Hypervisor 未指出可用性時,任何嘗試使用此介面都會造成#UD錯誤。

僅 (輸入) 暫存器對應

x64 x86 提供的資訊
RCX EDX:EAX Hypercall 輸入值
RDX EBX:ECX 輸入參數區塊
R8 EDI:ESI 輸入參數區塊
XMM0 XMM0 輸入參數區塊
XMM1 XMM1 輸入參數區塊
XMM2 XMM2 輸入參數區塊
XMM3 XMM3 輸入參數區塊
XMM4 XMM4 輸入參數區塊
XMM5 XMM5 輸入參數區塊

超預存輸入值會連同輸入參數一起傳入暫存器。 暫存器對應取決於呼叫端是在 32 位 (x86) 或 64 位 (x64) 模式中執行。 Hypervisor 會根據 EFER 的值來判斷呼叫者的模式。LMA 和 CS.L。 如果同時設定這兩個旗標,則呼叫端會假設為 64 位呼叫端。 如果輸入參數區塊小於 112 個位元組,則會忽略暫存器中的任何額外位元組。

Hypercall 輸出

所有超calls 都會傳回稱為 hypercall 結果值的 64 位值。 格式如下:

欄位 Bits 註解
結果 15-0 HV_STATUS 指出成功或失敗的程式碼
Rsvd 31-16 呼叫端應該忽略這些位中的值
代表已完成 43-32 已成功完成的代表數目
RsvdZ 63-40 呼叫端應該忽略這些位中的值

針對 rep 超calls,reps complete 欄位是代表完成的總數,而不是相對於 rep start 索引。 例如,如果呼叫端指定了 5 的 rep start 索引,而 rep 計數為 10,則 reps complete 欄位會在成功完成時指出 10。

超預存結果值會在暫存器中傳回。 暫存器對應取決於呼叫者是在 32 位 (x86) 或 64 位 (x64) 模式中執行, (請參閱上述) 。 超安裝輸出的暫存器對應如下所示:

x64 x86 提供的資訊
RAX EDX:EAX Hypercall 結果值

XMM Fast Hypercall 輸出

與 Hypervisor 支援 XMM 快速超安裝輸入的方式類似,可以共用相同的暫存器來傳回輸出。 這僅在 x64 平臺上受到支援。

透過 XMM 暫存器傳回輸出的能力會透過「Hypervisor 功能識別」CPUID 分葉 (0x40000003) 來指出:

  • 位 15:支援透過 XMM 暫存器傳回超安裝輸出。

請注意,有個別旗標可指出 XMM 快速輸入的支援。 當 Hypervisor 未指出可用性時,任何嘗試使用此介面都會造成#UD錯誤。

暫存器對應 (輸入和輸出)

未用來傳遞輸入參數的暫存器可用來傳回輸出。 換句話說,如果輸入參數區塊小於 112 個位元組, (四捨五入至最接近的 16 個位元組對齊區塊) ,其餘暫存器會傳回超集合輸出。

x64 提供的資訊
RDX 輸入或輸出區塊
R8 輸入或輸出區塊
XMM0 輸入或輸出區塊
XMM1 輸入或輸出區塊
XMM2 輸入或輸出區塊
XMM3 輸入或輸出區塊
XMM4 輸入或輸出區塊
XMM5 輸入或輸出區塊

例如,如果輸入參數區塊的大小為 20 個位元組,Hypervisor 會忽略下列 12 個位元組。 如果) 適用的話,剩餘的 80 個位元組會包含超 (輸出。

Volatile Registers

超calls 只會在下列情況下修改指定的暫存器值:

  1. 如果有的話,RAX (x64) 和 EDX:EAX (x86) 一律會覆寫超集合結果值和輸出參數。
  2. Rep 超calls 會修改 RCX (x64) 和 EDX:EAX (x86) 與新的 rep start index。
  3. HvCallSetVpRegisters 可以修改該 Hypercall 支援的任何暫存器。
  4. RDX、R8 和 XMM0 到 XMM5,用於快速超安裝輸入時,仍保持未修改狀態。 不過,可以修改用於快速超安裝輸出的暫存器,包括 RDX、R8 和 XMM0 到 XMM5。 Hyper-V 只會修改這些暫存器以進行快速超安裝輸出,限制為 x64。

Hypercall 限制

超calls 可能會有與其相關聯的限制,讓他們能夠執行其預定的函式。 如果不符合所有限制,hypercall 將會終止並出現適當的錯誤。 如果適用,將會列出下列限制:

  • 呼叫分割區必須擁有特定許可權
  • 要處理的資料分割必須處於特定狀態 (例如「Active」)

Hypercall 狀態碼

每個超安裝都會記錄為傳回包含數個欄位的輸出值。 ) 類型的 HV_STATUS 狀態值欄位 (用來指出呼叫成功或失敗。

失敗超calls 上的輸出參數有效性

除非明確陳述,否則當超集合失敗 (即,超集合結果值的結果欄位包含) 以外的 HV_STATUS_SUCCESS 值時,所有輸出參數的內容都是不確定的,而且不應該由呼叫端檢查。 只有在超安裝成功時,所有適當的輸出參數才會包含有效的預期結果。

錯誤條件的順序

Hypervisor 偵測到錯誤狀況並報告的順序為未定義。 換句話說,如果有多個錯誤存在,Hypervisor 必須選擇要報告的錯誤狀況。 應將優先順序提供給這些錯誤碼,以提供更高的安全性,目的是防止 Hypervisor 向呼叫端顯示資訊給缺乏足夠許可權的呼叫端。 例如,狀態碼是慣用的狀態碼 HV_STATUS_ACCESS_DENIED ,其會根據許可權來顯示某些內容或狀態資訊。

一般 Hypercall 狀態碼

所有超calls 都有數個結果碼很常見,因此不會針對每個超標籤個別記載。 這些選項包括:

狀態碼 錯誤狀況
HV_STATUS_SUCCESS 呼叫成功。
HV_STATUS_INVALID_HYPERCALL_CODE 無法辨識超安裝程式碼。
HV_STATUS_INVALID_HYPERCALL_INPUT 例如,代表計數不正確 (,非零的 rep 計數會傳遞至非 rep 呼叫,或將零 rep 計數傳遞至 rep 呼叫) 。
Rep 開始索引不小於 rep 計數。
指定超安裝輸入值中的保留位為非零。
HV_STATUS_INVALID_ALIGNMENT 指定的輸入或輸出 GPA 指標未對齊 8 個位元組。
指定的輸入或輸出參數清單會跨越頁面。
輸入或輸出 GPA 指標不在 GPA 空間的範圍內。

傳回碼 HV_STATUS_SUCCESS 表示未偵測到任何錯誤狀況。

報告客體 OS 身分識別

在分割區內執行的客體 OS 必須藉由將其簽章和版本寫入 MSR (HV_X64_MSR_GUEST_OS_ID) ,才能叫用超擴充功能,以識別其本身給 Hypervisor。 此 MSR 是全分割區,且會在所有虛擬處理器之間共用。

這個暫存器的值一開始為零。 必須先將非零值寫入客體 OS 識別碼 MSR,才能啟用 hypercall 字碼頁 (請參閱 建立 Hypercall 介面) 。 如果後續將這個暫存器設為零,將會停用 Hypercall 字碼頁。

#define HV_X64_MSR_GUEST_OS_ID 0x40000000

專屬作業系統的客體 OS 身分識別

以下是此 MSR 的建議編碼方式。 某些欄位可能不適用於某些客體 OS。

Bits 欄位 描述
15:0 組建編號 指出 OS 的組建編號
23:16 服務版本 指出服務版本 (,例如「Service Pack」 號碼)
31:24 次要版本 指出作業系統的次要版本
39:32 主要版本 指出作業系統的主要版本
47:40 OS 識別碼 表示 OS 變體。 編碼對廠商而言是唯一的。 Microsoft 作業系統編碼方式如下:0=Undefined、1=MS-DOS®、2=Windows ® 3.x、3=Windows 9x、4=Windows ® ® NT (和衍生) 、5=Windows ® CE
62:48 廠商識別碼 指出客體 OS 廠商。 保留值為 0。 請參閱下方的廠商清單。
63 OS 類型 指出 OS 類型。 值為 0 表示專屬的封閉式來源 OS。 值為 1 表示開放原始碼 OS。

廠商值是由 Microsoft 配置。 若要要求新的廠商,請在GitHub虛擬化檔存放庫 () https://aka.ms/VirtualizationDocumentationIssuesTLFS 提出問題。

廠商
Microsoft 0x0001
HPE 0x0002
LANCOM 0x0200

開放原始碼作業系統的客體 OS 身分識別 MSR

下列編碼方式提供作為開放原始碼作業系統廠商想要符合此規格的指引。 建議開放原始碼作業系統調整下列慣例。

Bits 欄位 描述
15:0 組建編號 其他資訊
47:16 版本 上游核心版本資訊。
55:48 OS 識別碼 其他廠商資訊
62:56 OS 類型 OS 類型 (例如 Linux、FreeBSD 等) 。 請參閱下面的已知 OS 類型清單
63 開放原始碼 值為 1 表示開放原始碼 OS。

作業系統類型值是由 Microsoft 配置。 若要要求新的 OS 類型,請在GitHub虛擬化檔存放庫 () https://aka.ms/VirtualizationDocumentationIssuesTLFS 提出問題。

OS 類型
Linux 0x1
FreeBSD 0x2
Xen 0x3
Illumos 0x4

建立 Hypercall 介面

超calls 是使用特殊的 opcode 來叫用。 由於此 opcode 在虛擬化實作之間有所差異,因此 Hypervisor 必須抽象化這項差異。 這是透過特殊超安裝頁面來完成的。 此頁面是由 Hypervisor 提供,並出現在客體 GPA 空間中。 需要來賓,才能透過程式設計客體 Hypercall MSR 來指定頁面的位置。

#define HV_X64_MSR_HYPERCALL 0x40000001
Bits 描述 屬性
63:12 Hypercall GPFN - 指出 Hypercall 頁面的來賓實體頁碼 讀取/寫入
11:2 RsvdP。 讀取時應該忽略位,並在寫入時保留。 保留
1 鎖。 指出 MSR 是否不可變。 如果設定,此 MSR 會鎖定,因而防止重新配置超安裝頁面。 設定之後,只有系統重設可以清除位。 讀取/寫入
0 啟用 hypercall 頁面 讀取/寫入

Hypercall 頁面可以在來賓的 GPA 空間內的任何位置放置,但必須對齊頁面。 如果客體嘗試將 hypercall 頁面移到 GPA 空間的界限之外,則寫入 MSR 時會產生#GP錯誤。

此 MSR 是全分割的 MSR。 換句話說,它是由分割區中的所有虛擬處理器共用。 如果一個虛擬處理器成功寫入 MSR,另一個虛擬處理器會讀取相同的值。

啟用 Hypercall 頁面之前,客體 OS 必須將其版本簽章寫入個別 MSR (HV_X64_MSR_GUEST_OS_ID) 來報告其身分識別。 如果未指定任何客體 OS 身分識別,嘗試啟用 Hypercall 將會失敗。 即使已將啟用位寫入其中,啟用位仍會維持零。 此外,如果在啟用超安裝頁面之後將客體 OS 身分識別清除為零,則會停用。

Hypercall 頁面會顯示為 GPA 空間的「重迭」;也就是說,它涵蓋對應至 GPA 範圍的任何其他專案。 其內容可供來賓讀取且可執行。 嘗試寫入超安裝頁面會導致保護 (#GP) 例外狀況。 啟用 hypercall 頁面之後,叫用 hypercall 只會牽涉到呼叫頁面開頭。

以下是建立 hypercall 頁面相關步驟的詳細清單:

  1. 客體會讀取 CPUID 分葉 1,並藉由檢查註冊 ECX 的位 31 來判斷 Hypervisor 是否存在。
  2. 客體會讀取 CPUID 分葉0x40000000,以判斷註冊 EAX) 和 CPUID 分葉0x40000001中傳回的最大 Hypervisor CPUID 分葉 (,以判斷註冊 EAX) 中傳回的介面簽 (章。 它會確認分葉值上限至少為0x40000005,且介面簽章等於 「Hv#1」。 這個簽章表示 HV_X64_MSR_GUEST_OS_ID 已實作 、 HV_X64_MSR_HYPERCALLHV_X64_MSR_VP_INDEX
  3. 如果登錄為零,客體會將其 OS 身分識別寫入 MSR HV_X64_MSR_GUEST_OS_ID
  4. 來賓會讀取 Hypercall MSR (HV_X64_MSR_HYPERCALL) 。
  5. 來賓會檢查 [啟用 Hypercall 頁面位]。 如果已設定,介面已經作用中,則應該省略步驟 6 和 7。
  6. 來賓在其 GPA 空間中找到頁面,最好是 RAM、MMIO 等未佔用的頁面。 如果已佔用頁面,來賓應該避免基於其他目的使用基礎頁面。
  7. 來賓會將新值寫入 Hypercall MSR (HV_X64_MSR_HYPERCALL) ,其中包含步驟 6 中的 GPA,並將 [啟用 Hypercall 頁面位] 設定為啟用介面。
  8. 客體會建立可執行檔 VA 對應至 Hypercall 頁面 GPA。
  9. 來賓會諮詢 CPUID 分葉0x40000003,以判斷哪些 Hypervisor 設備可供使用。 建立介面之後,客體可以起始超安裝。 若要這樣做,它會根據 hypercall 通訊協定填入暫存器,併發出 Hypercall 頁面開頭的呼叫。 客體應該假設 hypercall 頁面會執行接近傳回 (0xC3) 的對等專案,以返回呼叫者。 因此,必須使用有效的堆疊叫用超安裝。

擴充 Hypercall 介面

具有上述呼叫碼的超calls 0x8000稱為擴充超calls。 擴充超calls 使用與一般超calls 相同的呼叫慣例,並從客體 VM 的觀點來看相同。 擴充超calls 會在 Hyper-V Hypervisor 內部以不同的方式處理。

您可以使用 HvExtCallQueryCapabilities來查詢擴充 Hypercall 功能。