ZX_vmo_create_child

摘要

建立 VM 物件的子項。

宣告

#include <zircon/syscalls.h>

zx_status_t zx_vmo_create_child(zx_handle_t handle,
                                uint32_t options,
                                uint64_t offset,
                                uint64_t size,
                                zx_handle_t* out);

說明

zx_vmo_create_child() 會建立新的虛擬記憶體物件 (VMO),成為現有 vmo 的子項。語意的行為取決於子項的類型。

成功時會傳回一個控制代碼,代表含有要求大小的物件。

options 必須包含下列其中一個標記,才能指定子項類型:

  • ZX_VMO_CHILD_SNAPSHOT - 建立子項,使其行為就像執行緊急副本一樣。當寫入發生時,父項和子項都會執行延遲複本。延遲複製可讓子項和父項互相區別。在父項 VMO 大小範圍之外的任何讀取作業都含有零,且會寫入新的零填入頁面。以下項目不支援這個標記:

啟用 ZX_VMO_CHILD_NO_WRITE 選項且停用 ZX_VMO_CHILD_RESIZABLE 選項時,ZX_VMO_CHILD_SNAPSHOT 會建立不可變更的 VMO。

  • ZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITE - 建立子項,至少對寫入語意進行複製。子項的任何寫入作業都會從父項取得頁面副本,其內容可能會與父項不同。在頁面寫入及複製之前,系統允許讀取作業,但不保證一定能在父項執行寫入作業時傳回變更值。此旗標可能無法用於透過 zx_vmo_create_physical()zx_vmo_create_contiguous() 或這類 VMO 的子系建立的 VMO。如要瞭解 VMO 系統呼叫與子項的互動,請參閱「附註」。

ZX_VMO_CHILD_SNAPSHOT_MODIFIED - 建立子項,使其行為就像在上層沒有分頁器支援的任何頁面上執行 (也就是由已呼叫頁面 VMO 的子項修改過的頁面)。採用 Pager 的頁面將至少具備「寫入時複製」語意。這個標記可能不適用於透過 zx_vmo_create_physical()zx_vmo_create_contiguous()、含有固定頁面的 VMO,或這類 VMO 的子系建立的 VMO。如果使用 SNAPSHOT_AT_LEAST_ON_WRITE 建立具有非配量子項或非分頁式 VMO 子項,也不支援這個標記。如要瞭解 VMO 系統呼叫與子項的互動,請參閱「附註」。

  • ZX_VMO_CHILD_SLICE - 建立具有直接讀取/寫入權限父項區段的配量。配量 VMO 的所有作業都會以在父項上完成的方式運作。切片和父項 VMO 的重複控制代碼不同,前者僅允許存取父項 VMO 子範圍,並允許使用 ZX_VMO_ZERO_CHILDREN 信號。這個標記可與透過 zx_vmo_create_physical()zx_vmo_create_contiguous() 及其子系建立的 VMO 搭配使用。這個標記可能無法與使用 ZX_VMO_RESIZABLE 選項建立的 VMO 搭配使用。

  • ZX_VMO_CHILD_REFERENCE - 建立 VMO 的參照。在參考 VMO 上的所有作業,其行為就像是在父項上完成一樣。參照一律橫跨父項,而 offsetsize 必須為 0。如果使用者想使用 ZX_VMO_ZERO_CHILDREN 信號追蹤 VMO 的待處理參照,這個方法就能派上用場。如要進一步瞭解這個信號,請參閱「附註」。此旗標可能無法用於透過 zx_vmo_create_physical()zx_vmo_create_contiguous() 或這類 VMO 的子系建立的 VMO。

此外,options 可包含零或多個下列標記,進一步指定子項的行為:

  • ZX_VMO_CHILD_RESIZABLE:建立可調整大小的子項 VMO。這與 ZX_VMO_CHILD_SLICE 不相容。

  • ZX_VMO_CHILD_NO_WRITE - 建立無法寫入的子項。這與 ZX_VMO_CHILD_RESIZABLE 不相容。

offset 必須對齊頁面。

offset + size 不得超過 64 位元未正負號值的範圍。

無論是位移或大小,開頭或大小都可能會超出原始 VMO 的大小。

VMO 的大小會四捨五入至下一個頁面大小邊界。

VMO 的內容大小會初始化為指定的 (未四捨五入) 大小。將 zx_object_get_property()ZX_PROP_VMO_CONTENT_SIZE 搭配使用,可讀取 VMO 的內容大小。將 zx_object_set_property()ZX_PROP_VMO_CONTENT_SIZE 搭配使用可設定 VMO 的內容大小,不必實際調整 VMO 大小。

根據預設,子項帳號代碼的權利將與原始帳號相同,但有幾個例外。請參閱 zx_vmo_create() 以取得相關詳細資料的討論。

如果 options 包含 ZX_VMO_CHILD_RESIZABLE,系統就會新增 ZX_RIGHT_RESIZE

如果是 ZX_VMO_CHILD_REFERENCEZX_VMO_CHILD_RESIZABLE 選項可控制是否要使用 out 中傳回的參照控點調整父項 VMO 的大小。如果父項 VMO 可以調整大小,無論 ZX_VMO_CHILD_RESIZABLE 為何,參照都會在父項 VMO 上看見大小調整。不過,只有在父項 VMO 可以調整大小時才支援 ZX_VMO_CHILD_RESIZABLE,也就是無法建立可調整大小的 VMO 參照。

在所有情況下,如果設定了 ZX_VMO_NO_WRITE,系統就會移除 ZX_RIGHT_WRITE

如果 optionsZX_VMO_CHILD_SNAPSHOTZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITEZX_VMO_CHILD_SNAPSHOT_MODIFIED,且未設定 ZX_VMO_CHILD_NO_WRITE,則系統會新增 ZX_RIGHT_WRITE 並移除 ZX_RIGHT_EXECUTE

附註

建立子 VMO 會導致現有 (來源) VMO ZX_VMO_ZERO_CHILDREN 信號變為停用狀態。只有在最後一個子項遭到刪除,且這些子項都沒有對應至位址空間時,ZX_VMO_ZERO_CHILDREN 才會再次生效。

非配量子項 VM 會以下列方式與 VMO 系統呼叫互動:

  • 子項的 zx_vmo_op_range() COMMIT 模式會將內容提交至子項的網頁,使其內容與上層的對應頁面相同。如果這些網頁是由 Pager 提供,這項作業也會修訂父項中的這些網頁。否則,如果這些頁面沒有在父項修訂,零填入的頁面將直接視為子項,而不會影響父項。
  • 系統不支援 zx_vmo_op_range() 的 DECOMMIT 模式。

權限

handle 必須是 ZX_OBJ_TYPE_VMO 類型,且包含 ZX_RIGHT_DUPLICATE,且有 ZX_RIGHT_READ

傳回值

zx_vmo_create_child() 在成功時傳回 ZX_OK。如果失敗,系統會傳回負值的錯誤值。

錯誤

ZX_ERR_BAD_TYPE 輸入控制代碼不是 VMO。

ZX_ERR_ACCESS_DENIED 輸入帳號代碼權限不足。

ZX_ERR_INVALID_ARGS out 是無效的指標或 NULL,或是未對齊頁面對齊,或提供的選項組合不相容。

ZX_ERR_OUT_OF_RANGE 偏移 + size 過大。

ZX_ERR_NO_MEMORY 由於記憶體不足而失敗。使用者空間無法妥善處理這項 (不太可能) 錯誤。日後的建構作業就不會再發生這個錯誤。

ZX_ERR_BAD_STATE vmo 有部分固定頁面,因此無法建立 COW 子項。

ZX_ERR_NOT_SUPPORTED 輸入控點是可捨棄的 VMO,或輸入控點是可調整大小的 VMO,而「選項」包含 ZX_VMO_CHILD_SLICE

另請參閱