受保護的執行設施

簡介

受保護的執行設施 (PEF) 是 POWER 9 的一項架構更改,可實現安全虛擬機器 (SVM)。 DD2.3 晶片 (PVR=0x004e1203) 或更高版本將支援 PEF。 新的 ISA 版本將包含 PEF RFC02487 更改。

啟用後,PEF 會向 POWER 架構新增一種新的、更高許可權的模式,稱為 Ultravisor 模式。 除了新模式之外,還有一種新的韌體,稱為受保護的執行 Ultravisor(簡稱 Ultravisor)。 Ultravisor 模式是 POWER 架構中許可權最高的模式。

特權狀態

問題

Supervisor

Hypervisor

Ultravisor

PEF 保護 SVM 免受 Hypervisor、特權使用者和系統中其他 VM 的影響。 SVM 在靜止時受到保護,並且只能由授權機器執行。 所有虛擬機器都使用 Hypervisor 服務。 Ultravisor 過濾 SVM 和 Hypervisor 之間的呼叫,以確保資訊不會意外洩漏。 除了 H_RANDOM 之外的所有 Hypercall 都會反映到 Hypervisor。 H_RANDOM 不會反映,以防止 Hypervisor 影響 SVM 中的隨機值。

為了支援這一點,需要對 CPU 中資源的所有權進行重構。 以前具有 Hypervisor 特權的一些資源現在具有 Ultravisor 特權。

硬體

硬體更改包括以下內容

  • MSR 中有一個新位,用於確定當前程序是否在安全模式下執行,MSR(S) 位 41。 MSR(S)=1,程序處於安全模式,MSR(s)=0,程序處於正常模式。

  • MSR(S) 位只能由 Ultravisor 設定。

  • HRFID 不能用於設定 MSR(S) 位。 如果 Hypervisor 需要返回到 SVM,則必須使用 ultracall。 它可以確定它要返回到的 VM 是否安全。

  • 有一個新的 Ultravisor 特權暫存器 SMFCTRL,它有一個啟用/停用位 SMFCTRL(E)。

  • 程序的特權現在由三個 MSR 位確定,MSR(S, HV, PR)。 在下面的每個表中,模式都按從最低特權到最高特權的順序列出。 較高特權模式可以訪問較低特權模式的所有資源。

    安全模式 MSR 設定

    S

    HV

    PR

    特權

    1

    0

    1

    問題

    1

    0

    0

    特權(作業系統)

    1

    1

    0

    Ultravisor

    1

    1

    1

    保留

    正常模式 MSR 設定

    S

    HV

    PR

    特權

    0

    0

    1

    問題

    0

    0

    0

    特權(作業系統)

    0

    1

    0

    Hypervisor

    0

    1

    1

    問題 (Host)

  • 記憶體被劃分為安全記憶體和正常記憶體。 只有在安全模式下執行的程序才能訪問安全記憶體。

  • 硬體不允許任何未以安全方式執行的程式訪問安全記憶體。 這意味著 Hypervisor 無法訪問 SVM 的記憶體,除非使用 ultracall(詢問 Ultravisor)。 Ultravisor 只允許 Hypervisor 以加密形式檢視 SVM 記憶體。

  • 不允許 I/O 系統直接定址安全記憶體。 這將 SVM 限制為僅虛擬 I/O。

  • 該架構允許 SVM 與 Hypervisor 共享未受加密保護的記憶體頁。 但是,此共享必須由 SVM 啟動。

  • 當程序在安全模式下執行時,所有 Hypercall(syscall lev=1)都會轉到 Ultravisor。

  • 當程序處於安全模式時,所有中斷都會轉到 Ultravisor。

  • 以下資源已變為 Ultravisor 特權,並且需要 Ultravisor 接口才能進行操作

    • 處理器配置暫存器 (SCOM)。

    • 停止狀態資訊。

    • 除錯暫存器 CIABR、DAWR 和 DAWRX(當設定了 SMFCTRL(D) 時)。 如果未設定 SMFCTRL(D),則它們在安全模式下不起作用。 設定後,讀取和寫入需要 Ultravisor 呼叫,否則將導致 Hypervisor 模擬輔助中斷。

    • PTCR 和分割槽表條目(分割槽表位於安全記憶體中)。 嘗試寫入 PTCR 將導致 Hypervisor 模擬輔助中斷。

    • LDBAR(LD 基址暫存器)和 IMC(記憶體集合)非架構暫存器。 嘗試寫入它們將導致 Hypervisor 模擬輔助中斷。

    • SVM 的分頁,與 Hypervisor 共享 SVM 的記憶體。 (包括虛擬處理器區域 (VPA) 和虛擬 I/O)。

軟體/微碼

軟體更改包括

  • SVM 是使用 IBM 提供的(開源)工具從普通 VM 建立的。

  • 所有 SVM 都從普通 VM 開始,並利用 ultracall UV_ESM(進入安全模式)進行轉換。

  • 當進行 UV_ESM ultracall 時,Ultravisor 會將 VM 複製到安全記憶體中,解密驗證資訊,並檢查 SVM 的完整性。 如果完整性檢查透過,Ultravisor 會以安全模式傳遞控制。

  • 驗證資訊包括與 SVM 關聯的加密磁碟的密碼短語。 此密碼短語會在請求時提供給 SVM。

  • Ultravisor 不參與保護 SVM 在靜止時的加密磁碟。

  • 對於外部中斷,Ultravisor 會儲存 SVM 的狀態,並將中斷反映到 Hypervisor 以進行處理。 對於 Hypercall,Ultravisor 會將中性狀態插入到所有不需要用於 Hypercall 的暫存器中,然後將呼叫反映到 Hypervisor 以進行處理。 H_RANDOM Hypercall 由 Ultravisor 執行,而不是反映。

  • 為了使虛擬 I/O 工作,必須進行跳轉緩衝。

  • Ultravisor 使用 AES (IAPM) 來保護 SVM 記憶體。 IAPM 是一種 AES 模式,可同時提供完整性和保密性。

  • 正常頁面和安全頁面之間的資料移動由 Hypervisor 中的新 HMM 外掛與 Ultravisor 協調。

Ultravisor 為 Hypervisor 和 SVM 提供新服務。 這些服務透過 ultracall 訪問。

術語

  • Hypercall:用於從 Hypervisor 請求服務的特殊系統呼叫。

  • 正常記憶體:Hypervisor 可以訪問的記憶體。

  • 正常頁面:由正常記憶體支援的頁面,Hypervisor 可以使用。

  • 共享頁面:由正常記憶體支援的頁面,Hypervisor/QEMU 和 SVM 都可以使用(即,頁面在 SVM 和 Hypervisor/QEMU 中都有對映)。

  • 安全記憶體:只有 Ultravisor 和 SVM 才能訪問的記憶體。

  • 安全頁面:由安全記憶體支援的頁面,只有 Ultravisor 和 SVM 可以使用。

  • SVM:安全虛擬機器。

  • Ultracall:用於從 Ultravisor 請求服務的特殊系統呼叫。

Ultravisor 呼叫 API

本節介紹支援安全虛擬機器 (SVM) 和半虛擬化 KVM 所需的 Ultravisor 呼叫 (ultracall)。 ultracall 允許 SVM 和 Hypervisor 從 Ultravisor 請求服務,例如訪問只能在 Ultravisor 特權模式下執行的暫存器或記憶體區域。

來自 ultracall 的特定服務需要在暫存器 R3 中指定(ultracall 的第一個引數)。 如果有任何其他引數,則在暫存器 R4 到 R12 中指定。

所有 ultracall 的返回值都在暫存器 R3 中。 來自 ultracall 的其他輸出值(如果有)在暫存器 R4 到 R12 中返回。 此暫存器使用的唯一例外是下面描述的 UV_RETURN ultracall。

每個 ultracall 都返回特定的錯誤程式碼,這些程式碼適用於 ultracall 的上下文中。 但是,與 PowerPC 架構平臺參考 (PAPR) 一樣,如果沒有為特定情況定義特定的錯誤程式碼,則 ultracall 將回退到基於錯誤引數位置的程式碼。 即,U_PARAMETER、U_P2、U_P3 等,具體取決於可能導致錯誤的 ultracall 引數。

一些 ultracall 涉及在 Ultravisor 和 Hypervisor 之間傳輸資料頁。 從安全記憶體傳輸到正常記憶體的安全頁面可以使用動態生成的金鑰進行加密。 當安全頁面傳輸回安全記憶體時,可以使用相同的動態生成的金鑰對其進行解密。 這些金鑰的生成和管理將在單獨的文件中介紹。

目前,這僅涵蓋 Hypervisor 和 SVM 當前實現和正在使用的 ultracall,但可以在有意義時在此處新增其他 ultracall。

所有 Hypercall/Ultracall 的完整規範最終將在 PAPR 規範的公共/OpenPower 版本中提供。

注意

如果未啟用 PEF,ultracall 將重定向到 Hypervisor,後者必須處理/使呼叫失敗。

Hypervisor 使用的 Ultracall

本節介紹 Hypervisor 用來管理 SVM 的虛擬記憶體管理 ultracall。

UV_PAGE_OUT

加密並將頁面的內容從安全記憶體移動到正常記憶體。

語法
uint64_t ultracall(const uint64_t UV_PAGE_OUT,
        uint16_t lpid,          /* LPAR ID */
        uint64_t dest_ra,       /* real address of destination page */
        uint64_t src_gpa,       /* source guest-physical-address */
        uint8_t  flags,         /* flags */
        uint64_t order)         /* page size order */
返回值

以下值之一

  • 成功時返回 U_SUCCESS。

  • 如果 lpid 無效,則返回 U_PARAMETER。

  • 如果 dest_ra 無效,則返回 U_P2。

  • 如果 src_gpa 地址無效,則返回 U_P3。

  • 如果 flags 中的任何位無法識別,則返回 U_P4。

  • 如果不支援 order 引數,則返回 U_P5。

  • 如果不支援該功能,則返回 U_FUNCTION。

  • 如果當前無法調出頁面,則返回 U_BUSY。

描述

加密安全頁面的內容,並使其在正常頁面中可供 Hypervisor 使用。

預設情況下,源頁面從 SVM 的分割槽範圍的頁面表中取消對映。 但是,Hypervisor 可以透過在 flags 引數中設定 UV_SNAPSHOT 標誌,向 Ultravisor 提供提示以保留頁面對映。

如果源頁面已經是共享頁面,則該呼叫將返回 U_SUCCESS,而不執行任何操作。

用例
  1. QEMU 嘗試訪問屬於 SVM 的地址,但是該地址的頁面幀未對映到 QEMU 的地址空間中。 在這種情況下,Hypervisor 將分配一個頁面幀,將其對映到 QEMU 的地址空間中,併發出 UV_PAGE_OUT 呼叫以檢索頁面的加密內容。

  2. 當 Ultravisor 的安全記憶體不足並且需要調出 LRU 頁面時。 在這種情況下,Ultravisor 將向 Hypervisor 發出 H_SVM_PAGE_OUT Hypercall。 然後,Hypervisor 將分配一個正常頁面併發出 UV_PAGE_OUT ultracall,並且 Ultravisor 將加密安全頁面的內容並將其移動到正常頁面中。

  3. 當 Hypervisor 訪問 SVM 資料時,Hypervisor 請求 Ultravisor 將相應的頁面傳輸到非安全頁面中,Hypervisor 可以訪問該頁面。 但是,正常頁面中的資料將被加密。

UV_PAGE_IN

將頁面的內容從正常記憶體移動到安全記憶體。

語法
uint64_t ultracall(const uint64_t UV_PAGE_IN,
        uint16_t lpid,          /* the LPAR ID */
        uint64_t src_ra,        /* source real address of page */
        uint64_t dest_gpa,      /* destination guest physical address */
        uint64_t flags,         /* flags */
        uint64_t order)         /* page size order */
返回值

以下值之一

  • 成功時返回 U_SUCCESS。

  • 如果當前無法調入頁面,則返回 U_BUSY。

  • 如果不支援該功能,則返回 U_FUNCTION。

  • 如果 lpid 無效,則返回 U_PARAMETER。

  • 如果 src_ra 無效,則返回 U_P2。

  • 如果 dest_gpa 地址無效,則返回 U_P3。

  • 如果 flags 中的任何位無法識別,則返回 U_P4。

  • 如果不支援 order 引數,則返回 U_P5。

描述

將由 src_ra 標識的頁面的內容從正常記憶體移動到安全記憶體,並將其對映到客戶物理地址 dest_gpa

如果 dest_gpa 指的是共享地址,則將頁面對映到 SVM 的分割槽範圍的頁面表中。 如果 dest_gpa 不是共享的,則將頁面的內容複製到相應的安全頁面中。 根據上下文,在複製之前解密頁面。

呼叫方透過 flags 引數提供頁面的屬性。 flags 的有效值為

  • CACHE_INHIBITED

  • CACHE_ENABLED

  • WRITE_PROTECTION

Hypervisor 必須在發出 UV_PAGE_IN ultracall 之前將頁面固定在記憶體中。

用例
  1. 當正常 VM 切換到安全模式時,其駐留在正常記憶體中的所有頁面都會移動到安全記憶體中。

  2. 當 SVM 請求與 Hypervisor 共享頁面時,Hypervisor 會分配一個頁面並通知 Ultravisor。

  3. 當 SVM 訪問已調出的安全頁面時,Ultravisor 會呼叫 Hypervisor 以定位該頁面。 在定位該頁面後,Hypervisor 使用 UV_PAGE_IN 使該頁面可供 Ultravisor 使用。

UV_PAGE_INVAL

使 Ultravisor 頁面對映無效。

語法
uint64_t ultracall(const uint64_t UV_PAGE_INVAL,
        uint16_t lpid,          /* the LPAR ID */
        uint64_t guest_pa,      /* destination guest-physical-address */
        uint64_t order)         /* page size order */
返回值

以下值之一

  • 成功時返回 U_SUCCESS。

  • 如果 lpid 無效,則返回 U_PARAMETER。

  • 如果 guest_pa 無效(或對應於安全頁面對映),則返回 U_P2。

    頁面對映)。

  • 如果 order 無效,則返回 U_P3。

  • 如果不支援該功能,則返回 U_FUNCTION。

  • 如果當前無法使頁面無效,則返回 U_BUSY。

描述

此 ultracall 通知 Ultravisor,Hypervisor 中對應於給定客戶物理地址的頁面對映已無效,並且 Ultravisor 不應訪問該頁面。 如果指定的 guest_pa 對應於安全頁面,則 Ultravisor 將忽略使頁面無效的嘗試,並返回 U_P2。

用例
  1. 當從 QEMU 的頁面表中取消對映共享頁面時(可能是因為它已調出到磁碟),Ultravisor 需要知道也不應從其端訪問該頁面。

UV_WRITE_PATE

驗證並寫入給定分割槽的分割槽表條目 (PATE)。

語法
uint64_t ultracall(const uint64_t UV_WRITE_PATE,
        uint32_t lpid,          /* the LPAR ID */
        uint64_t dw0            /* the first double word to write */
        uint64_t dw1)           /* the second double word to write */
返回值

以下值之一

  • 成功時返回 U_SUCCESS。

  • 如果當前無法寫入 PATE,則返回 U_BUSY。

  • 如果不支援該功能,則返回 U_FUNCTION。

  • 如果 lpid 無效,則返回 U_PARAMETER。

  • 如果 dw0 無效,則返回 U_P2。

  • 如果 dw1 地址無效,則返回 U_P3。

  • 如果 Hypervisor 嘗試更改安全虛擬機器的 PATE,或者從 Hypervisor 以外的上下文中呼叫,則返回 U_PERMISSION。

    從 Hypervisor 以外的上下文呼叫。

描述

驗證並寫入給定 LPID 的 LPID 及其分割槽表條目。 如果已分配和初始化 LPID,則此呼叫將導致更改分割槽表條目。

用例
  1. 分割槽表駐留在安全記憶體中,其條目(稱為 PATE(分割槽表條目))指向 Hypervisor 以及每個虛擬機器(安全和正常)的分割槽範圍的頁面表。 Hypervisor 在分割槽 0 中執行,其分割槽範圍的頁面表駐留在正常記憶體中。

  2. 此 ultracall 允許 Hypervisor 向 Ultravisor 註冊 Hypervisor 和其他分割槽(虛擬機器)的分割槽範圍和程序範圍的頁面表條目。

  3. 如果現有分割槽 (VM) 的 PATE 值更改,則會重新整理該分割槽的 TLB 快取。

  4. Hypervisor 負責分配 LPID。 LPID 及其 PATE 條目一起註冊。 Hypervisor 管理正常 VM 的 PATE 條目,並且可以隨時更改 PATE 條目。 Ultravisor 管理 SVM 的 PATE 條目,並且不允許 Hypervisor 修改它們。

UV_RETURN

在處理完已轉發(也稱為反射)到 Hypervisor 的 Hypercall 或中斷後,將控制權從 Hypervisor 返回給 Ultravisor。

語法
uint64_t ultracall(const uint64_t UV_RETURN)
返回值

成功後,此呼叫永遠不會返回到 Hypervisor。 如果 ultracall 不是從 Hypervisor 上下文進行的,則返回 U_INVALID。

描述

當 SVM 進行 Hypercall 或發生其他異常時,Ultravisor 通常會將異常轉發(也稱為反射)到 Hypervisor。 在處理完異常後,Hypervisor 使用 UV_RETURN ultracall 將控制權返回給 SVM。

此 ultracall 的入口處的預期暫存器狀態為

  • 非易失性暫存器恢復為其原始值。

  • 如果從 Hypercall 返回,則暫存器 R0 包含返回值(與其他 ultracall 不同),並且暫存器 R4 到 R12 包含 Hypercall 的任何輸出值。

  • R3 包含 ultracall 編號,即 UV_RETURN。

  • 如果返回合成中斷,則 R2 包含合成中斷編號。

用例
  1. Ultravisor 依賴 Hypervisor 為 SVM 提供多項服務,例如處理 Hypercall 和其他異常。 在處理完異常後,Hypervisor 使用 UV_RETURN 將控制權返回給 Ultravisor。

  2. Hypervisor 必須使用此 ultracall 將控制權返回給 SVM。

UV_REGISTER_MEM_SLOT

使用指定的屬性註冊 SVM 地址範圍。

語法
uint64_t ultracall(const uint64_t UV_REGISTER_MEM_SLOT,
        uint64_t lpid,          /* LPAR ID of the SVM */
        uint64_t start_gpa,     /* start guest physical address */
        uint64_t size,          /* size of address range in bytes */
        uint64_t flags          /* reserved for future expansion */
        uint16_t slotid)        /* slot identifier */
返回值

以下值之一

  • 成功時返回 U_SUCCESS。

  • 如果 lpid 無效,則返回 U_PARAMETER。

  • 如果 start_gpa 無效,則返回 U_P2。

  • 如果 size 無效,則返回 U_P3。

  • 如果 flags 中的任何位無法識別,則返回 U_P4。

  • 如果不支援 slotid 引數,則返回 U_P5。

  • 如果從 Hypervisor 以外的上下文中呼叫,則返回 U_PERMISSION。

  • 如果不支援該功能,則返回 U_FUNCTION。

描述

註冊 SVM 的記憶體範圍。 記憶體範圍從客戶物理地址 start_gpa 開始,長度為 size 位元組。

用例
  1. 當虛擬機器變為安全虛擬機器時,Hypervisor 管理的所有記憶體插槽都會移動到安全記憶體中。 Hypervisor 會迭代每個記憶體插槽,並使用 Ultravisor 註冊該插槽。 Hypervisor 可能會丟棄一些插槽,例如用於韌體的插槽 (SLOF)。

  2. 當熱插拔新記憶體時,會註冊新的記憶體插槽。

UV_UNREGISTER_MEM_SLOT

登出先前使用 UV_REGISTER_MEM_SLOT 註冊的 SVM 地址範圍。

語法
uint64_t ultracall(const uint64_t UV_UNREGISTER_MEM_SLOT,
        uint64_t lpid,          /* LPAR ID of the SVM */
        uint64_t slotid)        /* reservation slotid */
返回值

以下值之一

  • 成功時返回 U_SUCCESS。

  • 如果不支援該功能,則返回 U_FUNCTION。

  • 如果 lpid 無效,則返回 U_PARAMETER。

  • 如果 slotid 無效,則返回 U_P2。

  • 如果從 Hypervisor 以外的上下文中呼叫,則返回 U_PERMISSION。

描述

釋放由 slotid 標識的記憶體槽,並釋放為預留分配的任何資源。

用例
  1. 記憶體熱移除。

UV_SVM_TERMINATE

終止 SVM 並釋放其資源。

語法
uint64_t ultracall(const uint64_t UV_SVM_TERMINATE,
        uint64_t lpid,          /* LPAR ID of the SVM */)
返回值

以下值之一

  • 成功時返回 U_SUCCESS。

  • 如果不支援該功能,則返回 U_FUNCTION。

  • 如果 lpid 無效,則返回 U_PARAMETER。

  • 如果 VM 不安全,則返回 U_INVALID。

  • 如果不是從 Hypervisor 上下文中呼叫,則返回 U_PERMISSION。

描述

終止 SVM 並釋放其所有資源。

用例
  1. 由 Hypervisor 在終止 SVM 時呼叫。

SVM 使用的 Ultracall

UV_SHARE_PAGE

與 Hypervisor 共享一組客戶機物理頁。

語法
uint64_t ultracall(const uint64_t UV_SHARE_PAGE,
        uint64_t gfn,   /* guest page frame number */
        uint64_t num)   /* number of pages of size PAGE_SIZE */
返回值

以下值之一

  • 成功時返回 U_SUCCESS。

  • 如果不支援該功能,則返回 U_FUNCTION。

  • 如果 VM 不安全,則返回 U_INVALID。

  • 如果 gfn 無效,則返回 U_PARAMETER。

  • 如果 num 無效,則返回 U_P2。

描述

與 Hypervisor 共享從客戶機物理幀號 gfn 開始的 num 個頁面。 假設頁面大小為 PAGE_SIZE 位元組。 返回前將頁面置零。

如果該地址已經由安全頁面支援,則取消對映該頁面,並在 Hypervisor 的幫助下,使用不安全頁面支援它。 如果尚未有任何頁面支援它,則將 PTE 標記為不安全,並在訪問該地址時使用不安全頁面支援它。 如果它已經由不安全頁面支援,則將頁面置零並返回。

用例
  1. Hypervisor 無法訪問 SVM 頁面,因為它們由安全頁面支援。 因此,SVM 必須顯式地向 Ultravisor 請求它可以與 Hypervisor 共享的頁面。

  2. 共享頁面是支援 SVM 中的 virtio 和虛擬處理器區域 (VPA) 所必需的。

UV_UNSHARE_PAGE

將共享的 SVM 頁面恢復到其初始狀態。

語法
uint64_t ultracall(const uint64_t UV_UNSHARE_PAGE,
        uint64_t gfn,   /* guest page frame number */
        uint73 num)     /* number of pages of size PAGE_SIZE*/
返回值

以下值之一

  • 成功時返回 U_SUCCESS。

  • 如果不支援該功能,則返回 U_FUNCTION。

  • 如果 VM 不安全,則返回 U_INVALID。

  • 如果 gfn 無效,則返回 U_PARAMETER。

  • 如果 num 無效,則返回 U_P2。

描述

停止與 Hypervisor 共享從 gfn 開始的 num 個頁面。 假設頁面大小為 PAGE_SIZE。 返回前將頁面置零。

如果該地址已經由不安全頁面支援,則取消對映該頁面,並使用安全頁面支援它。 通知 Hypervisor 釋放對其共享頁面的引用。 如果該地址尚未由頁面支援,則將 PTE 標記為安全,並在訪問該地址時使用安全頁面支援它。 如果它已經由安全頁面支援,則將頁面置零並返回。

用例
  1. SVM 可以決定從 Hypervisor 取消共享頁面。

UV_UNSHARE_ALL_PAGES

取消共享 SVM 已與 Hypervisor 共享的所有頁面。

語法
uint64_t ultracall(const uint64_t UV_UNSHARE_ALL_PAGES)
返回值

以下值之一

  • 成功時返回 U_SUCCESS。

  • 如果不支援該功能,則返回 U_FUNCTION。

  • 如果 VM 不安全,則返回 U_INVAL。

描述

取消共享來自 Hypervisor 的所有共享頁面。 返回時,所有取消共享的頁面都將被置零。 只有 SVM 使用 UV_SHARE_PAGE ultracall 顯式共享的頁面才會被取消共享。 Ultravisor 可能會在內部與 Hypervisor 共享一些頁面,而無需 SVM 的顯式請求。 這些頁面不會被此 ultracall 取消共享。

用例
  1. 當使用 kexec 啟動不同的核心時,需要此呼叫。 在 SVM 重置期間也可能需要它。

UV_ESM

保護虛擬機器(進入安全模式)。

語法
uint64_t ultracall(const uint64_t UV_ESM,
        uint64_t esm_blob_addr, /* location of the ESM blob */
        unint64_t fdt)          /* Flattened device tree */
返回值

以下值之一

  • 成功時返回 U_SUCCESS(包括 VM 已經安全的情況)。

  • 如果不支援該功能,則返回 U_FUNCTION。

  • 如果 VM 不安全,則返回 U_INVALID。

  • 如果 esm_blob_addr 無效,則返回 U_PARAMETER。

  • 如果 fdt 無效,則返回 U_P2。

  • 如果任何完整性檢查失敗,則返回 U_PERMISSION。

  • U_RETRY:記憶體不足,無法建立 SVM。

  • U_NO_KEY:對稱金鑰不可用。

描述

保護虛擬機器。 成功完成後,將控制權返回給 ESM blob 中指定的地址處的虛擬機器。

用例
  1. 普通的虛擬機器可以選擇切換到安全模式。

Hypervisor 呼叫 API

本文件描述了支援 Ultravisor 所需的 Hypervisor 呼叫(hypercall)。 Hypercall 是 Hypervisor 向虛擬機器和 Ultravisor 提供的服務。

這些 hypercall 的暫存器用法與其他 Power Architecture Platform Reference (PAPR) 文件中定義的 hypercall 相同。 即,在輸入時,暫存器 R3 標識所請求的特定服務,暫存器 R4 到 R11 包含 hypercall 的附加引數(如果有)。 在輸出時,暫存器 R3 包含返回值,暫存器 R4 到 R9 包含 hypercall 的任何其他輸出值。

本文件僅涵蓋當前為 Ultravisor 用途實現/計劃的 hypercall,但如果合理,可以在此處新增其他 hypercall。

所有 Hypercall/Ultracall 的完整規範最終將在 PAPR 規範的公共/OpenPower 版本中提供。

支援 Ultravisor 的 Hypervisor 呼叫

以下是支援 Ultravisor 所需的一組 hypercall。

H_SVM_INIT_START

開始將普通虛擬機器轉換為 SVM 的過程。

語法
uint64_t hypercall(const uint64_t H_SVM_INIT_START)
返回值

以下值之一

  • 成功時返回 H_SUCCESS。

  • 如果 VM 不處於切換到安全狀態的位置,則返回 H_STATE。

描述

啟動保護虛擬機器的過程。 這涉及與 Ultravisor 協調,使用 ultracall 在 Ultravisor 中為新的 SVM 分配資源,將 VM 的頁面從普通記憶體傳輸到安全記憶體等。 完成該過程後,Ultravisor 發出 H_SVM_INIT_DONE hypercall。

用例
  1. Ultravisor 使用此 hypercall 通知 Hypervisor VM 已啟動切換到安全模式的過程。

H_SVM_INIT_DONE

完成保護 SVM 的過程。

語法
uint64_t hypercall(const uint64_t H_SVM_INIT_DONE)
返回值

以下值之一

  • 成功時返回 H_SUCCESS。

  • 如果從錯誤的上下文中呼叫(例如,

    從 SVM 或在 H_SVM_INIT_START hypercall 之前),則返回 H_UNSUPPORTED。

  • 如果 hypervisor 無法成功

    將 VM 轉換為安全 VM,則返回 H_STATE。

描述

完成保護虛擬機器的過程。 必須在先前呼叫 H_SVM_INIT_START hypercall 之後進行此呼叫。

用例

成功保護虛擬機器後,Ultravisor 會通知 Hypervisor。 Hypervisor 可以使用此呼叫來完成為此虛擬機器設定其內部狀態。

H_SVM_INIT_ABORT

中止保護 SVM 的過程。

語法
uint64_t hypercall(const uint64_t H_SVM_INIT_ABORT)
返回值

以下值之一

  • 成功清理狀態後,

    Hypervisor 將向**訪客**返回此值,以指示底層的 UV_ESM ultracall 失敗。

  • 如果在 VM 進入安全狀態後呼叫,則返回 H_STATE(即

    H_SVM_INIT_DONE hypercall 成功)。

  • 如果從錯誤的上下文中呼叫(例如,從

    普通的 VM),則返回 H_UNSUPPORTED。

描述

中止保護虛擬機器的過程。 必須在先前呼叫 H_SVM_INIT_START hypercall 之後,並在呼叫 H_SVM_INIT_DONE 之前進行此呼叫。

在進入此 hypercall 時,預計非易失性 GPR 和 FPR 將包含 VM 發出 UV_ESM ultracall 時的值。 此外,SRR0 預計將包含 UV_ESM ultracall 之後的指令的地址,並且 SRR1 包含返回到 VM 的 MSR 值。

此 hypercall 將清理自先前的 H_SVM_INIT_START hypercall 以來為 VM 建立的任何部分狀態,包括分頁到安全記憶體中的頁面,併發出 UV_SVM_TERMINATE ultracall 以終止 VM。

清理部分狀態後,控制權返回給 VM(**而不是 Ultravisor**),地址在 SRR0 中指定,MSR 值設定為 SRR1 中的值。

用例

如果在成功呼叫 H_SVM_INIT_START 後,Ultravisor 在保護虛擬機器時遇到錯誤,無論是由於資源不足還是由於 VM 的安全資訊無法驗證,Ultravisor 都會通知 Hypervisor。 Hypervisor 應該使用此呼叫來清理此虛擬機器的任何內部狀態並返回到 VM。

H_SVM_PAGE_IN

將頁面的內容從正常記憶體移動到安全記憶體。

語法
uint64_t hypercall(const uint64_t H_SVM_PAGE_IN,
        uint64_t guest_pa,      /* guest-physical-address */
        uint64_t flags,         /* flags */
        uint64_t order)         /* page size order */
返回值

以下值之一

  • 成功時返回 H_SUCCESS。

  • 如果 guest_pa 無效,則返回 H_PARAMETER。

  • 如果 flags 無效,則返回 H_P2。

  • 如果頁面的 order 無效,則返回 H_P3。

描述

檢索 VM 擁有的、位於指定客戶機物理地址的頁面的內容。

flags 中的唯一有效值是

  • H_PAGE_IN_SHARED,表示該頁面將與 Ultravisor 共享。

  • H_PAGE_IN_NONSHARED,表示 UV 不再對該頁面感興趣。 如果該頁面是共享頁面,則適用。

order 引數必須與配置的頁面大小相對應。

用例
  1. 當普通 VM 成為安全 VM(使用 UV_ESM ultracall)時,Ultravisor 使用此 hypercall 將 VM 的每個頁面的內容從普通記憶體移動到安全記憶體。

  2. Ultravisor 使用此 hypercall 要求 Hypervisor 提供普通記憶體中的頁面,該頁面可以在 SVM 和 Hypervisor 之間共享。

  3. Ultravisor 使用此 hypercall 來分頁調入分頁調出的頁面。 當 SVM 訪問分頁調出的頁面時,可能會發生這種情況。

  4. 如果 SVM 想要停用與 Hypervisor 的頁面共享,它可以通知 Ultravisor。 Ultravisor 然後將使用此 hypercall 並通知 Hypervisor 它已釋放對普通頁面的訪問許可權。

H_SVM_PAGE_OUT

將頁面的內容移動到普通記憶體。

語法
uint64_t hypercall(const uint64_t H_SVM_PAGE_OUT,
        uint64_t guest_pa,      /* guest-physical-address */
        uint64_t flags,         /* flags (currently none) */
        uint64_t order)         /* page size order */
返回值

以下值之一

  • 成功時返回 H_SUCCESS。

  • 如果 guest_pa 無效,則返回 H_PARAMETER。

  • 如果 flags 無效,則返回 H_P2。

  • 如果 order 無效,則返回 H_P3。

描述

將由 guest_pa 標識的頁面的內容移動到普通記憶體。

目前 flags 未使用,必須設定為 0。order 引數必須與配置的頁面大小相對應。

用例
  1. 如果 Ultravisor 的安全頁面不足,它可以使用此 hypercall 將一些安全頁面的內容移動到普通頁面。 內容將被加密。

參考資料