摘要
在訪客內設定陷阱。
宣告
#include <zircon/syscalls.h>
zx_status_t zx_guest_set_trap(zx_handle_t handle,
uint32_t kind,
zx_vaddr_t addr,
size_t size,
zx_handle_t port_handle,
uint64_t key);
說明
zx_guest_set_trap()
會在訪客內設定陷阱,當 vCPU 出現在addr 和 size 定義的位址範圍中,且位於 種類 定義的位址空間內時,就會產生封包。
「Kind」可以是 ZX_GUEST_TRAP_BELL
、ZX_GUEST_TRAP_MEM
或 ZX_GUEST_TRAP_IO
。如果指定了 ZX_GUEST_TRAP_BELL
或 ZX_GUEST_TRAP_MEM
,則 addr 和 size 都必須對齊頁面。ZX_GUEST_TRAP_BELL
是非同步陷阱,ZX_GUEST_TRAP_MEM
和 ZX_GUEST_TRAP_IO
都是同步陷阱。
同步陷阱的封包將透過 zx_vcpu_enter()
傳送,非同步陷阱的封包則會透過 port_handle 傳送。
同步梯度的 port_handle 必須為 ZX_HANDLE_INVALID
。對於非同步陷阱 port_handle 必須有效,則每次觸發陷阱時,都會透過 port_handle 傳送 Trap 的封包。每個陷阱預先分配固定數量的封包。如果所有封包都用盡,系統將暫停執行陷阱的 VCPU 執行作業。如有至少一個封包移出佇列,vCPU 的執行作業將繼續執行。如要將 port_handle 中的封包解除佇列,請使用 zx_port_wait()
。多個執行緒可能會使用 zx_port_wait()
將封包移出佇列,以便使用執行緒集區處理陷阱。
key 用於設定 zx_port_packet_t
中的金鑰欄位,並可用於區分不同陷阱的封包。
ZX_GUEST_TRAP_BELL
是定義門鈴的陷阱類型。如果使用者可以存取陷阱指定的記憶體區域,則會產生一個封包,該封包不會擷取與存取相關聯的指示。然後,系統會透過 port_handle 以非同步方式傳送封包。
如要找出產生的封包「類型」,請使用 ZX_PKT_TYPE_GUEST_MEM
、ZX_PKT_TYPE_GUEST_IO
、ZX_PKT_TYPE_GUEST_BELL
和 ZX_PKT_TYPE_GUEST_VCPU
。ZX_PKT_TYPE_GUEST_VCPU
是特殊封包,並非由陷阱造成,表示訪客要求啟動其他 vCPU。
權限
handle 必須是 ZX_OBJ_TYPE_GUEST
類型,且具有 ZX_RIGHT_WRITE
。
port_handle 必須為 ZX_OBJ_TYPE_PORT
類型,且具有 ZX_RIGHT_WRITE
。
傳回值
zx_guest_set_trap()
會在成功時傳回 ZX_OK
。失敗時,系統會傳回錯誤值。
錯誤
ZX_ERR_ACCESS_DENIED
handle 或 port_handle 沒有 ZX_RIGHT_WRITE
的右側。
ZX_ERR_ALREADY_EXISTS
Kind 陷阱已存在與 addr 和 size 交集。
ZX_ERR_BAD_HANDLE
handle 或 port_handle 是無效的控制代碼。
ZX_ERR_INVALID_ARGS
Kind 不是有效的位址空間,或者使用 port_handle 指定 ZX_GUEST_TRAP_MEM
。
ZX_ERR_NO_MEMORY
因記憶體不足而失敗。使用者空間無法以任何方式處理這個錯誤 (極可能) 錯誤。日後的建構作業不會再發生這個錯誤。
ZX_ERR_OUT_OF_RANGE
addr 和 size 指定的區域不在位址空間「種類」的有效邊界內。
ZX_ERR_WRONG_TYPE
處理常式不是訪客的控制代碼,或者 port_handle 不是通訊埠的控制代碼。
附註
ZX_GUEST_TRAP_BELL
與 ZX_GUEST_TRAP_MEM
共用相同的位址空間。
在 x86-64 上,如果「Kind」為 ZX_GUEST_TRAP_BELL
或 ZX_GUEST_TRAP_MEM
,且「addr」是本機 APIC 的位址,則「size」必須等同於網頁大小。這是因為系統對本機 APIC 位址要求陷阱時,對應了一個特殊網頁。這樣我們就能利用硬體加速功能 (如果可用)。
另請參閱
zx_guest_create()
zx_port_create()
zx_port_wait()
zx_vcpu_create()
zx_vcpu_enter()
zx_vcpu_interrupt()
zx_vcpu_kick()
zx_vcpu_read_state()
zx_vcpu_write_state()