RFC-0013:複製 VMO 對應 | |
---|---|
狀態 | 已接受 |
領域 |
|
說明 | 系統呼叫可根據對應建立 VMO 的 CoW 副本,不需要控制代碼。 |
問題 | |
毛皮變化 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 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_SNAPSHOT
、ZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITE
和ZX_VMO_CHILD_NO_WRITE
。
其解讀方式與 zx_vmo_create_child
相同。
(基於安全考量,目前無法使用 ZX_VMO_CHILD_SLICE
:
因此他們必須特別小心
而修改父項 VMO 的功能不會破壞任何安全性界限)。
如果符合下列情況,則傳回 ZX_ERR_INVALID_ARGS
:
addr
到addr
+size
的範圍不是單一 VMO 對應的子範圍addr
或size
未對齊頁面
如果符合下列情況,則傳回 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