摘要
新增記憶體對應。
宣告
#include <zircon/syscalls.h>
zx_status_t zx_vmar_map(zx_handle_t handle,
zx_vm_option_t options,
size_t vmar_offset,
zx_handle_t vmo,
uint64_t vmo_offset,
size_t len,
zx_vaddr_t* mapped_addr);
說明
將指定的 VMO 對應至指定的虛擬記憶體位址區域。對應會保留基礎虛擬記憶體物件的參照,這表示關閉 VMO 控制代碼並不會移除這個函式新增的對應。
options 是下列位元向量:
ZX_VM_SPECIFIC
請使用 vmar_offset 放置對應。如果 handle 沒有ZX_VM_CAN_MAP_SPECIFIC
權限,則對應無效。vmar_offset 是相對於指定 VMAR 基礎位址的偏移量。指定與其他 VMAR 或對應重疊的範圍是錯誤。ZX_VM_SPECIFIC_OVERWRITE
與ZX_VM_SPECIFIC
相同,但可能會重疊其他對應關係。即使範圍與其他 VMAR 部分重疊,仍是發生錯誤。如果範圍符合這些要求,就會以不可分割的形式 (於所有其他對應/取消對應/保護作業) 取代 vmar_offset 和 len 指定範圍內的現有對應。如果這個範圍部分與任何對應重疊,則範圍外的對應部分會維持對應部分。ZX_VM_OFFSET_IS_UPPER_LIMIT
將 vmar_offset 解讀為上限,以限制核心選取偏移量;如果「處理常式」沒有ZX_VM_CAN_MAP_SPECIFIC
權限,則無效。產生的對應會有偏移值 + len 為 <= vmar_offset。如果使用ZX_VM_SPECIFIC
或ZX_VM_SPECIFIC_OVERWRITE
,則無法指定這個選項。ZX_VM_PERM_READ
將 vmo 對應至可讀的格式。如果處理程式沒有ZX_VM_CAN_MAP_READ
權限、處理常式沒有ZX_RIGHT_READ
權利,或者 vmo 控制代碼沒有ZX_RIGHT_READ
權利,則視為錯誤。ZX_VM_PERM_WRITE
將 vmo 對應至可寫入。如果處理程式沒有ZX_VM_CAN_MAP_WRITE
權限、處理常式沒有ZX_RIGHT_WRITE
權利、vmo 控制代碼沒有ZX_RIGHT_WRITE
的權限,或 options 未指定ZX_VM_PERM_READ
會發生錯誤。ZX_VM_PERM_EXECUTE
將「vmo」對應為執行檔。如果「處理程式」沒有ZX_VM_CAN_MAP_EXECUTE
權限、handle 控制代碼沒有ZX_RIGHT_EXECUTE
權利、vmo 控制代碼沒有ZX_RIGHT_EXECUTE
的權利,或者 options 未指定ZX_VM_PERM_READ
,則為錯誤。ZX_VM_MAP_RANGE
立即頁面至 VMO 所有支援的新對應區域。如果使用ZX_VM_SPECIFIC_OVERWRITE
,就無法指定這個值。ZX_VM_ALLOW_FAULTS
必要時,如果建立的對應可以產生錯誤,則為必要項目。請特別注意,如果 vmo 可以調整大小、如果 vmo 無法調整大小,但對應已超過 vmo 的結尾、可捨棄 vmo,或者 vmo 是透過zx_pager_create_vmo()
建立,則為必要欄位。ZX_VM_PERM_READ_IF_XOM_UNSUPPORTED
如果系統不支援只能對應執行的網頁,請將 vmo 對應至可讀取的內容。如果系統可以對應僅執行,這個旗標會遭到忽略。
如果 options 沒有設定 ZX_VM_SPECIFIC
、ZX_VM_SPECIFIC_OVERWRITE
或 ZX_VM_OFFSET_IS_UPPER_LIMIT
,vmar_offset 都必須為 0。
ZX_VM_OFFSET_IS_UPPER_LIMIT
可用來限制選取範圍,否則運作方式類似於未設定 ZX_VM_SPECIFIC
和 ZX_VM_SPECIFIC_OVERWRITE
的情況,同時由核心隨機指派偏移量 (由目標 VMAR 設定的政策決定)。
len 不得為零且頁面對齊。
此外,還可以新增下列其中一種雙重對齊旗標:
ZX_VM_ALIGN_1KB
會將 child_addr 的值調整為 2 的次方至少 1,000 個位元組。ZX_VM_ALIGN_2KB
會將 child_addr 的乘冪調整為至少 2,000 個位元組。ZX_VM_ALIGN_4KB
會將 child_addr 調整為 2 的次方,至少為 4K 個位元組。ZX_VM_ALIGN_8KB
會將 child_addr 的值調整為 2 的 8,000 個位元組以上。ZX_VM_ALIGN_4GB
會將 child_addr 調整為 2 號至少 4G 位元組。
如果 vmar 基本位址 + vmo_offset 不符合要求的值,則搭配 ZX_VM_SPECIFIC
使用 ZX_VM_ALIGN
標記會失敗。
權限
handle 必須是 ZX_OBJ_TYPE_VMAR
類型。
vmo 必須是 ZX_OBJ_TYPE_VMO
類型。
傳回值
zx_vmar_map()
會在成功時傳回 ZX_OK
和對應的絕對基本地址 (透過 mapped_addr)。基本地址將以頁面對齊,而非零。如果失敗,系統會傳回負值錯誤值。
錯誤
ZX_ERR_BAD_HANDLE
控制代碼或 vmo 不是有效的帳號代碼。
ZX_ERR_WRONG_TYPE
帳號代碼或 vmo 並非 VMAR 或 VMO 控制代碼。
ZX_ERR_BAD_STATE
「控制代碼」是指遭到刪除的 VMAR。
以下任一項目的 ZX_ERR_INVALID_ARGS
:
- mapped_addr 或 options 無效。- 如未指定 ZX_VM_SPECIFIC
、ZX_VM_SPECIFIC_OVERWRITE
或 ZX_VM_OFFSET_IS_UPPER_LIMIT
,vmar_offset 就不是零。- 同時指定 ZX_VM_SPECIFIC_OVERWRITE
和 ZX_VM_MAP_RANGE
。
- ZX_VM_OFFSET_IS_UPPER_LIMIT
會和 ZX_VM_SPECIFIC
或 ZX_VM_SPECIFIC_OVERWRITE
一起指定。- vmar_offset 和 len 說明超過區域邊界造成的配置情形不令人滿意。
- vmar_offset 或 vmo_offset 未與頁面對齊。
- len 為 0 或非頁面對齊。
指定的 ZX_ERR_ALREADY_EXISTS
ZX_VM_SPECIFIC
不含 ZX_VM_SPECIFIC_OVERWRITE
,且要求的範圍與其他對應重疊。
ZX_ERR_NO_RESOURCES
如果找不到 VMAR 中的某個位置,以便建立對應關係。
ZX_ERR_ACCESS_DENIED
您的權限不足,無法進行要求的對應。
ZX_ERR_NOT_SUPPORTED
:如果 vmo 可調整大小、可捨棄或由 Pager 支援,但未設定 ZX_VM_ALLOW_FAULTS
,
ZX_ERR_BUFFER_TOO_SMALL
:VMO 無法調整大小,對應關係會超過 VMO 結尾,但未設定 ZX_VM_ALLOW_FAULTS
。
ZX_ERR_NO_MEMORY
因記憶體不足而失敗。使用者空間無法以任何方式處理這個錯誤 (極可能) 錯誤。日後的建構作業不會再發生這個錯誤。
ZX_ERR_OUT_OF_RANGE
vmo_offset + ROUNDUP(len, PAGE_SIZE)
溢位。
附註
支援記憶體對應的 VMO 可調整大小為較小的尺寸。這可能會導致執行緒讀取或寫入 VMAR 區域出錯。為避免這個安全漏洞,從用戶端接收 VMO 的服務應在對應 VMO 時使用 ZX_VM_REQUIRE_NON_RESIZABLE
。