RFC-0013:複製 VMO 對應

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

系統呼叫可根據對應建立 VMO 的 CoW 副本,不需要控制代碼。

問題
毛皮變化
  • (443437)
作者
審查人員
提交日期 (年-月-日)2020-10-26
審查日期 (年-月-日)2020-12-09

摘要

目前只有具有帳號代碼的 VMO 才能建立 CoW 副本。 這對於 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)

建立 CoW 複製範圍,將 addr 範圍中對應至 addr+size 的頁面 handle 所參照的 VMAR 中的一個例子。 範圍必須是單一 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 執行。

實作

新增系統呼叫並不是複雜的變更;只需在一份 CL 中即可 複製演算法的實作不在此 RFC 的範圍之內。

成效

也不值得自行對這個系統呼叫執行基準測試 因為這項功能僅用於 zygote 實作。 因此,我們應該評估 zygote 實作的整體效能。

安全性考量

目前無法透過 VMAR 參照 (而非帳號代碼) 建立 VMO 子項。 但 RFC 是可行的 這有點像讓輕而易舉的新能力

在這個案例中 因為最終結果等同於建立新的 VMO 並將資料複製到 但先前可以採用 如有任何需要禁止這項功能 這個 RFC 提議使用 zx_vm_options_t 旗標 (ZX_VM_CANNOT_CREATE_VMO_CHILD) 可用與否

測試

Syscall 將進行單元測試。 針對未來實作位址空間複製的實作測試 也能做為 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 對應至程序再開始執行 也無法獲得解決辦法 我們可以修改載入器服務,將必要的控制代碼傳遞至處理程序 但這樣做會比新增這個 syscall 來得好

既有藝術品和參考資料

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