摘要
建立分頁器擁有的 VMO。
宣告
#include <zircon/syscalls.h>
zx_status_t zx_pager_create_vmo(zx_handle_t pager,
uint32_t options,
zx_handle_t port,
uint64_t key,
uint64_t size,
zx_handle_t* out);
說明
建立分頁器物件所擁有的 VMO。size 會四捨五入至下一個頁面大小邊界,而「options」必須為零或以下標記的組合:
ZX_VMO_RESIZABLE
:如果 VMO 可以調整大小。
ZX_VMO_TRAP_DIRTY
- 如果寫入 VMO 中的乾淨頁面應受核心信任,並轉送至分頁器服務確認,再繼續寫入。
ZX_VMO_UNBOUNDED
:建立可初始化為最大大小的 VMO。無法與 ZX_VMO_RESIZABLE
搭配使用。傳入的大小引數不使用,且必須設為 0。
成功後,傳回的 VMO 會與使用 zx_vmo_create()
建立的 VMO 擁有相同的權利,以及對 ZX_VMO_ZERO_CHILDREN
的行為也相同。在 VMO 上運作的 Syscall 需要明確標記,以允許封鎖 IPC 存取使用者空間呼叫器服務;除此之外,不論 VMO 是否由呼叫器擁有,都不會影響 Syscall 的語意。
TODO(stevend):更新複製及修訂後更新的差異
網頁要求會在符合特定條件時傳送到通訊埠。這些封包的 type 會設為 ZX_PKT_TYPE_PAGE_REQUEST
,鍵則會設為提供給 zx_pager_create_vmo()
的值。封包的聯集為 zx_packet_page_request_t
類型:
typedef struct zx_packet_page_request {
uint16_t command;
uint16_t flags;
uint32_t reserved0;
uint64_t offset;
uint64_t length;
uint64_t reserved1;
} zx_packet_page_request_t;
offset 和 length 一律採用頁面對齊方式。未定義標記的旗標中任何位元的值,目前並未定義。封包的觸發條件和意義取決於 command,該指令可接受下列其中一個值:
ZX_PAGER_VMO_READ
:在應用程式存取呼叫器 VMO 中的非常駐頁面時傳送。Pager 服務應使用 zx_pager_supply_pages()
,在已註冊的 VMO 中填入 [偏移、偏移 + 長度] 範圍。消耗網頁就是對要求發出隱含認可的確認函,
ZX_PAGER_VMO_DIRTY
:在應用程式透過 ZX_VMO_TRAP_DIRTY
旗標建立的呼叫器 VMO 中,在應用程式寫入常駐乾淨頁面時傳送。Pager 服務應確認範圍 [offset、 offset + 長度) 可以失效,以允許寫入作業,並使用 zx_pager_op_range()
ZX_PAGER_OP_DIRTY
。
ZX_PAGER_VMO_COMPLETE
:如果因為 zx_pager_detach_vmo()
,或在沒有對 VMO 的參照而傳送更多分頁要求時傳送,就會傳送這個事件。
如果 pager 關閉,系統就不會將任何封包傳送至「通訊埠」 (包括沒有 ZX_PAGER_VMO_COMPLETE
訊息)。此外,日後所有存取行為都會以系統呼叫 zx_pager_detach_vmo()
的方式運作。
權限
pager 必須是 ZX_OBJ_TYPE_PAGER
類型,且包含 ZX_RIGHT_ATTACH_VMO
。
port 必須是 ZX_OBJ_TYPE_PORT
類型,且包含 ZX_RIGHT_WRITE
。
傳回值
zx_pager_create_vmo()
會在成功時傳回 ZX_OK;失敗時則傳回下列其中一個錯誤代碼。
錯誤
ZX_ERR_INVALID_ARGS
out 是無效指標或 NULL,options 包含不支援的標記組合,或 ZX_VMO_UNBOUNDED
使用了 0 以外的大小。
ZX_ERR_BAD_HANDLE
Pager 或 port 不是有效的帳號代碼。
ZX_ERR_ACCESS_DENIED
pager 沒有 ZX_RIGHT_ATTACH_VMO
或 port 沒有 ZX_RIGHT_WRITE
。
ZX_ERR_WRONG_TYPE
Pager 不是分頁器控制代碼,或 port 不是通訊埠控制代碼。
ZX_ERR_OUT_OF_RANGE
要求的大小超過 VMO 大小上限。
ZX_ERR_NO_MEMORY
因記憶體不足而失敗。