Summary
Sets a trap within a guest.
Declaration
#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);
Description
zx_guest_set_trap()
sets a trap within a guest, which generates a packet when
there is an access by a VCPU within the address range defined by addr and
size, within the address space defined by kind.
kind may be either ZX_GUEST_TRAP_BELL
, ZX_GUEST_TRAP_MEM
, or
ZX_GUEST_TRAP_IO
. If ZX_GUEST_TRAP_BELL
or ZX_GUEST_TRAP_MEM
is
specified, then addr and size must both be page-aligned.
ZX_GUEST_TRAP_BELL
is an asynchronous trap, and both ZX_GUEST_TRAP_MEM
and ZX_GUEST_TRAP_IO
are synchronous traps.
Packets for synchronous traps will be delivered through zx_vcpu_enter()
and
packets for asynchronous traps will be delivered through port_handle.
port_handle must be ZX_HANDLE_INVALID
for synchronous traps. For
asynchronous traps port_handle must be valid and a packet for the trap will be
delivered through port_handle each time the trap is triggered. A fixed number
of packets are pre-allocated per trap. If all the packets are exhausted,
execution of the VCPU that caused the trap will be paused. When at least one
packet is dequeued, execution of the VCPU will resume. To dequeue a packet from
port_handle, use zx_port_wait()
. Multiple threads may use
zx_port_wait()
to dequeue packets, enabling the use of a thread pool to
handle traps.
key is used to set the key field within zx_port_packet_t
, and can be used to
distinguish between packets for different traps.
ZX_GUEST_TRAP_BELL
is a type of trap that defines a door-bell. If there is
an access to the memory region specified by the trap, then a packet is generated
that does not fetch the instruction associated with the access. The packet will
then be delivered asynchronously via port_handle.
To identify what kind of trap generated a packet, use
ZX_PKT_TYPE_GUEST_MEM
, ZX_PKT_TYPE_GUEST_IO
, ZX_PKT_TYPE_GUEST_BELL
,
and ZX_PKT_TYPE_GUEST_VCPU
. ZX_PKT_TYPE_GUEST_VCPU
is a special packet,
not caused by a trap, that indicates that the guest requested to start an
additional VCPU.
Rights
handle must be of type ZX_OBJ_TYPE_GUEST
and have ZX_RIGHT_WRITE
.
port_handle must be of type ZX_OBJ_TYPE_PORT
and have ZX_RIGHT_WRITE
.
Return value
zx_guest_set_trap()
returns ZX_OK
on success. On failure, an error value is
returned.
Errors
ZX_ERR_ACCESS_DENIED
handle or port_handle do not have the
ZX_RIGHT_WRITE
right.
ZX_ERR_ALREADY_EXISTS
A trap for kind already exists that intersects with
addr and size.
ZX_ERR_BAD_HANDLE
handle or port_handle are invalid handles.
ZX_ERR_INVALID_ARGS
kind is not a valid address space, or
ZX_GUEST_TRAP_MEM
was specified with a port_handle.
ZX_ERR_NO_MEMORY
Failure due to lack of memory.
There is no good way for userspace to handle this (unlikely) error.
In a future build this error will no longer occur.
ZX_ERR_OUT_OF_RANGE
The region specified by addr and size is outside of
of the valid bounds of the address space kind.
ZX_ERR_WRONG_TYPE
handle is not a handle to a guest, or port_handle is
not a handle to a port.
Notes
ZX_GUEST_TRAP_BELL
shares the same address space as ZX_GUEST_TRAP_MEM
.
On x86-64, if kind is ZX_GUEST_TRAP_BELL
or ZX_GUEST_TRAP_MEM
and addr
is the address of the local APIC, then size must be equivalent to the size of
a page. This is due to a special page being mapped when a trap is requested at the
address of the local APIC. This allows us to take advantage of hardware
acceleration when available.
See also
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()