RFC-0013:複製 VMO 對應

RFC-0013:複製 VMO 對應
狀態已接受
區域
  • 核心
說明

一種系統呼叫,可從對應建立 VMO 副本,不需處理程式。

問題
變更
作者
審查人員
提交日期 (年/月)2020-10-26
審查日期 (年/月)2020-12-09

摘要

目前必須擁有 VMO 帳號代碼,才能建立 VMO 副本。但這並不適用於 zygote 的用途,因為 CoW 必須複製整個位址空間,包括所有 VMO 控制代碼已關閉的對應。此 RFC 提議新的系統呼叫來解決這個差距。

激勵與問題陳述

Linux 上的 Chromium 會透過 zygote 程序建立轉譯器,進而節省大量記憶體和 CPU。我們希望這能為 Fuchsia 省錢。

為此,我們需要一些方法來實作「位址空間複製」作業,如有指定:

  • 程序根層級 VMAR
  • 一些參照位址空間中對應的 VMO 帳號代碼

會傳回:

  • 新程序的位址空間是由輸入程序中對應的 VMO 副本所填入
  • 針對在輸入過程中參照 VMO 的每個控制代碼,在新程序中參照該 VMO 對應副本的新控制代碼

新增這項系統呼叫後,我們就可以放心在使用者空間中進行實作。方法是使用 ZX_INFO_PROCESS_MAPS 取得位址空間版面配置,並使用 zx_vmar_create_vmo_child 建立每個對應關係的本機副本,但具有控制代碼的 VMO 除外 (使用 zx_vmo_create_child 處理)。

設計

zx_vmar_create_vmo_child

zx_status_t zx_vmar_create_vmo_child(zx_handle_t handle,
                                     uint32_t options,
                                     zx_vaddr_t addr,
                                     size_t size,
                                     zx_handle_t* out)

handle 參照的 VMAR 中,為範圍 addraddr+size 範圍內的網頁建立 CoW 副本。範圍必須是單一 VMO 對應的子範圍,也就是說,範圍不得涵蓋兩個對應,或包含任何未對應的頁面。結果會產生一個新的 VMO,是該範圍內對應的 VMO 子項。

允許的選項包括 ZX_VMO_CHILD_SNAPSHOTZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITEZX_VMO_CHILD_NO_WRITE。兩者的解釋方式與 zx_vmo_create_child 相同。(有安全疑慮,因此目前無法使用 ZX_VMO_CHILD_SLICE:特別注意,確保父項 VMO 的修改權限不會破壞任何安全性邊界)。

在下列情況中,會傳回 ZX_ERR_INVALID_ARGS

  • addraddr+size 的範圍並非單一 VMO 對應的子範圍
  • addrsize 未對齊頁面

在下列情況中,會傳回 ZX_ERR_ACCESS_DENIED

  • 也就是使用新標記 ZX_VM_CANNOT_CREATE_VMO_CHILD 完成對應,vmar 選項則包含此標記
  • handle沒有 ZX_RIGHT_INSPECT

如果 handle 不是有效的控制代碼,會傳回 ZX_ERR_BAD_HANDLE;如果 handle 並非 VMAR,則傳回 ZX_ERR_WRONG_TYPE;如果 VMAR 遭到刪除,則傳回 ZX_ERR_BAD_STATE。如果的說明原因適用,也可以傳回 zx_vmo_create_child 傳回的任何錯誤。

傳回的 VMO 控制代碼將包含 ZX_DEFAULT_VMO_RIGHTS,包含以下變更:

  • 如果指定 ZX_VMO_CHILD_NO_WRITE,系統就會移除 ZX_RIGHT_WRITE
  • 如果對應是執行檔且未指定 ZX_VMO_CHILD_NO_WRITE,系統就會新增 ZX_RIGHT_EXECUTE。也就是說,您可以建立可執行對應項目的可執行副本,但這些副本必須是唯讀項目。

ZX_VM_CANNOT_CREATE_VMO_CHILD

ZX_VM_CANNOT_CREATE_VMO_CHILD 是一個新的 zx_vm_options_t 旗標,可用於 VMO 對應或 VMAR。如此一來,程式碼就能對應 VMO 或建立 VMAR,藉此禁止其使用 zx_vmar_create_vmo_child

實作

新增 Syscall 並非很複雜的變更,而可以在單一 CL 中進行。複製演算法的實作不在這個 RFC 的涵蓋範圍內。

效能

您不必自行對這個 Snack 呼叫進行基準測試,因為這個 Sygote 僅用於 zygote 實作。相反地,我們要評估 zygote 實作的整體效能。

安全性考量

目前無法使用 VMAR 參照而非帳號來建立 VMO 子項,但這個 RFC 可以這樣做。就像是利用輕薄空氣的方式授予新能力。

在本例中,似乎沒有風險,因為最終結果和建立新的 VMO 並複製資料 (但記憶體用量較低),因此不會造成風險。如果有需要禁止的功能,這個 RFC 建議提供可用於使用的 zx_vm_options_t 旗標 (ZX_VM_CANNOT_CREATE_VMO_CHILD)。

測試

Syscall 會進行單元測試。日後位址空間複製的測試將作為系統呼叫的整合測試。

說明文件

這個 RFC 是 zx_vmar_create_vmo_child 說明文件的起點。

缺點、替代方案和未知

還有哪些策略可以解決相同問題?

我們可以新增系統呼叫,以執行整個位址空間複製作業。無論在介面和實作過程中,這都是非常複雜的系統呼叫。最好將複雜的程度推送到使用者空間。

我們可以新增系統呼叫,允許從對應挖掘 VMO 控制代碼。這基本上就是 zx_vmar_create_vmo_child 的使用者空間實作方式,首先從對應中建立控制代碼,然後呼叫 zx_vmo_create_child。但 Zircon API 通常只允許將控點套用至新建立的物件,以方便介面推理介面。這種系統呼叫必須建立較輕薄的控點。

您可能會透過各種技巧來避免關閉任何 VMO 控制代碼,例如修改所有建立並對應 VMO 來避免關閉或攔截 zx_handle_close 的程式碼。但是,這並不足以實作位址空間複製功能,因為載入器服務會先將部分 VMO 對應至該程序,再開始執行,但無法讓您對這些 VMO 進行處理。我們可以修改載入器服務,將必要控制代碼傳送到程序,但這樣的做法比加入這個系統呼叫要來得多。

先前的圖片和參考資料

https://chromium.googlesource.com/chromium/src/+/master/docs/linux/zygote.md http://neugierig.org/software/chromium/notes/2011/08/zygote.html