blob: d9545915ddeb11dff9e3d9f5f2129fc240060d2f [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library zx;
@transport("Syscall")
protocol Vcpu {
/// ## Summary
///
/// Create a VCPU.
///
/// ## Declaration
///
/// ```c
/// #include <zircon/syscalls.h>
///
/// zx_status_t zx_vcpu_create(zx_handle_t guest,
/// uint32_t options,
/// zx_vaddr_t entry,
/// zx_handle_t* out);
/// ```
///
/// ## Description
///
/// `zx_vcpu_create()` creates a VCPU within a guest, which allows for execution
/// within the virtual machine. One or more VCPUs may be created per guest, where
/// the number of VCPUs does not need to match the number of physical CPUs on the
/// machine.
///
/// *entry* is the instruction pointer used to indicate where in guest physical
/// memory execution of the VCPU should start.
///
/// *out* is bound to the thread that created it, and all syscalls that operate on
/// it must be called from the same thread, with the exception of
/// [`zx_vcpu_interrupt()`].
///
/// Only one VCPU may exist on a thread at a time. A thread can create another VCPU
/// after it has closed the existing one.
///
/// N.B. VCPU is an abbreviation of virtual CPU.
///
/// The following rights will be set on the handle *out* by default:
///
/// **ZX_RIGHT_DUPLICATE** &mdash; *out* may be duplicated.
///
/// **ZX_RIGHT_TRANSFER** &mdash; *out* may be transferred over a channel.
///
/// **ZX_RIGHT_EXECUTE** &mdash; *out* may have its execution resumed (or begun)
///
/// **ZX_RIGHT_SIGNAL** &mdash; *out* may be interrupted
///
/// **ZX_RIGHT_READ** &mdash; *out* may have its state read
///
/// **ZX_RIGHT_WRITE** &mdash; may have its state written
///
/// ## Rights
///
/// *guest* must be of type **ZX_OBJ_TYPE_GUEST** and have **ZX_RIGHT_MANAGE_THREAD**.
///
/// ## Return value
///
/// `zx_vcpu_create()` returns **ZX_OK** on success. On failure, an error value is
/// returned.
///
/// ## Errors
///
/// **ZX_ERR_ACCESS_DENIED** *guest* does not have the **ZX_RIGHT_MANAGE_THREAD**
/// right.
///
/// **ZX_ERR_BAD_HANDLE** *guest* is an invalid handle.
///
/// **ZX_ERR_BAD_STATE** The thread currently has a VCPU. Only one VCPU can be
/// active on a thread at a time.
///
/// **ZX_ERR_INVALID_ARGS** *args* contains an invalid argument, or *out* is an
/// invalid pointer, or *options* is nonzero.
///
/// **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_WRONG_TYPE** *guest* is not a handle to a guest.
///
/// ## See also
///
/// - [`zx_guest_create()`]
/// - [`zx_guest_set_trap()`]
/// - [`zx_vcpu_enter()`]
/// - [`zx_vcpu_interrupt()`]
/// - [`zx_vcpu_kick()`]
/// - [`zx_vcpu_read_state()`]
/// - [`zx_vcpu_write_state()`]
///
/// [`zx_guest_create()`]: guest_create.md
/// [`zx_guest_set_trap()`]: guest_set_trap.md
/// [`zx_vcpu_enter()`]: vcpu_enter.md
/// [`zx_vcpu_interrupt()`]: vcpu_interrupt.md
/// [`zx_vcpu_kick()`]: vcpu_kick.md
/// [`zx_vcpu_read_state()`]: vcpu_read_state.md
/// [`zx_vcpu_write_state()`]: vcpu_write_state.md
Create(resource struct {
guest Handle:GUEST;
options uint32;
entry Vaddr;
}) -> (resource struct {
out Handle:VCPU;
}) error Status;
// See port.fidl for definition of PortPacket.
/// ## Summary
///
/// Enter a VCPU, causing it to resume execution.
///
/// ## Declaration
///
/// ```c
/// #include <zircon/syscalls.h>
/// #include <zircon/syscalls/port.h>
///
/// zx_status_t zx_vcpu_enter(zx_handle_t handle, zx_port_packet_t* packet);
/// ```
///
/// ## Description
///
/// `zx_vcpu_enter()` begins or resumes execution of *handle*, and blocks until it
/// has paused execution. On pause of execution, *packet* is populated with reason
/// for the pause. After handling the reason, execution may be resumed by calling
/// `zx_vcpu_enter()` again.
///
/// If `zx_vcpu_enter()` returns **ZX_ERR_CANCELED** due to `zx_vcpu_kick()` being
/// called on *handle*, execution may be resumed by calling `zx_vcpu_enter()` again.
///
/// `zx_vcpu_enter()` must be called on the same thread *handle* was created on.
///
/// ## Rights
///
/// *handle* must be of type **ZX_OBJ_TYPE_VCPU** and have **ZX_RIGHT_EXECUTE**.
///
/// ## Return value
///
/// `zx_vcpu_enter()` returns **ZX_OK** on success. On failure, an error value is
/// returned.
///
/// ## Errors
///
/// **ZX_ERR_ACCESS_DENIED** *handle* does not have the **ZX_RIGHT_EXECUTE** right.
///
/// **ZX_ERR_BAD_HANDLE** *handle* is an invalid handle.
///
/// **ZX_ERR_BAD_STATE** *handle* is in a bad state, and can not be executed.
///
/// **ZX_ERR_CANCELED** execution of *handle* was canceled, due to `zx_vcpu_kick()`
/// being called on *handle*.
///
/// **ZX_ERR_INTERNAL** There was an error executing *handle*.
///
/// **ZX_ERR_INVALID_ARGS** *packet* is an invalid pointer.
///
/// **ZX_ERR_NOT_SUPPORTED** An unsupported operation was encountered while
/// executing *handle*.
///
/// **ZX_ERR_WRONG_TYPE** *handle* is not a handle to a VCPU.
///
/// ## See also
///
/// - [`zx_guest_create()`]
/// - [`zx_guest_set_trap()`]
/// - [`zx_vcpu_create()`]
/// - [`zx_vcpu_interrupt()`]
/// - [`zx_vcpu_kick()`]
/// - [`zx_vcpu_read_state()`]
/// - [`zx_vcpu_write_state()`]
///
/// [`zx_guest_create()`]: guest_create.md
/// [`zx_guest_set_trap()`]: guest_set_trap.md
/// [`zx_vcpu_create()`]: vcpu_create.md
/// [`zx_vcpu_interrupt()`]: vcpu_interrupt.md
/// [`zx_vcpu_kick()`]: vcpu_kick.md
/// [`zx_vcpu_read_state()`]: vcpu_read_state.md
/// [`zx_vcpu_write_state()`]: vcpu_write_state.md
@blocking
Enter(resource struct {
handle Handle:VCPU;
}) -> (struct {
packet PortPacket;
}) error Status;
/// ## Summary
///
/// Kick a VCPU, causing it to stop execution.
///
/// ## Declaration
///
/// ```c
/// #include <zircon/syscalls.h>
///
/// zx_status_t zx_vcpu_kick(zx_handle_t handle);
/// ```
///
/// ## Description
///
/// `zx_vcpu_kick()` forces the current or next execution of `zx_vcpu_enter()` on
/// *handle* to return immediately with **ZX_ERR_CANCELED**.
///
/// `zx_vcpu_kick()` may be called multiple times on *handle*, but will only affect
/// the current or next execution of `zx_vcpu_enter()`.
///
/// ## Rights
///
/// *handle* must be of type **ZX_OBJ_TYPE_VCPU** and have **ZX_RIGHT_EXECUTE**.
///
/// ## Return value
///
/// `zx_vcpu_kick()` returns **ZX_OK** on success. On failure, an error value is
/// returned.
///
/// ## Errors
///
/// **ZX_ERR_ACCESS_DENIED** *handle* does not have the **ZX_RIGHT_EXECUTE** right.
///
/// **ZX_ERR_BAD_HANDLE** *handle* is an invalid handle.
///
/// **ZX_ERR_WRONG_TYPE** *handle* is not a handle to a VCPU.
///
/// ## See also
///
/// - [`zx_guest_create()`]
/// - [`zx_guest_set_trap()`]
/// - [`zx_vcpu_create()`]
/// - [`zx_vcpu_enter()`]
/// - [`zx_vcpu_interrupt()`]
/// - [`zx_vcpu_read_state()`]
/// - [`zx_vcpu_write_state()`]
///
/// [`zx_guest_create()`]: guest_create.md
/// [`zx_guest_set_trap()`]: guest_set_trap.md
/// [`zx_vcpu_create()`]: vcpu_create.md
/// [`zx_vcpu_enter()`]: vcpu_enter.md
/// [`zx_vcpu_interrupt()`]: vcpu_interrupt.md
/// [`zx_vcpu_read_state()`]: vcpu_read_state.md
/// [`zx_vcpu_write_state()`]: vcpu_write_state.md
Kick(resource struct {
handle Handle:VCPU;
}) -> () error Status;
/// ## Summary
///
/// Raise an interrupt on a VCPU.
///
/// ## Declaration
///
/// ```c
/// #include <zircon/syscalls.h>
///
/// zx_status_t zx_vcpu_interrupt(zx_handle_t handle, uint32_t vector);
/// ```
///
/// ## Description
///
/// `zx_vcpu_interrupt()` raises an interrupt of *vector* on *handle*, and may be
/// called from any thread.
///
/// ## Rights
///
/// *handle* must be of type **ZX_OBJ_TYPE_VCPU** and have **ZX_RIGHT_SIGNAL**.
///
/// ## Return value
///
/// `zx_vcpu_interrupt()` returns **ZX_OK** on success. On failure, an error value is
/// returned.
///
/// ## Errors
///
/// **ZX_ERR_ACCESS_DENIED** *handle* does not have the **ZX_RIGHT_SIGNAL** right.
///
/// **ZX_ERR_BAD_HANDLE** *handle* is an invalid handle.
///
/// **ZX_ERR_OUT_OF_RANGE** *vector* is outside of the range interrupts supported by
/// the current architecture.
///
/// **ZX_ERR_WRONG_TYPE** *handle* is not a handle to a VCPU.
///
/// ## See also
///
/// - [`zx_guest_create()`]
/// - [`zx_guest_set_trap()`]
/// - [`zx_vcpu_create()`]
/// - [`zx_vcpu_enter()`]
/// - [`zx_vcpu_kick()`]
/// - [`zx_vcpu_read_state()`]
/// - [`zx_vcpu_write_state()`]
///
/// [`zx_guest_create()`]: guest_create.md
/// [`zx_guest_set_trap()`]: guest_set_trap.md
/// [`zx_vcpu_create()`]: vcpu_create.md
/// [`zx_vcpu_enter()`]: vcpu_enter.md
/// [`zx_vcpu_kick()`]: vcpu_kick.md
/// [`zx_vcpu_read_state()`]: vcpu_read_state.md
/// [`zx_vcpu_write_state()`]: vcpu_write_state.md
Interrupt(resource struct {
handle Handle:VCPU;
vector uint32;
}) -> () error Status;
/// ## Summary
///
/// Read the state of a VCPU.
///
/// ## Declaration
///
/// ```c
/// #include <zircon/syscalls.h>
///
/// zx_status_t zx_vcpu_read_state(zx_handle_t handle,
/// uint32_t kind,
/// void* buffer,
/// size_t buffer_size);
/// ```
///
/// ## Description
///
/// `zx_vcpu_read_state()` reads the state of *handle* as specified by *kind* into
/// *buffer*. It is only valid to read the state of *handle* when execution has been
/// paused.
///
/// *kind* must be **ZX_VCPU_STATE**.
///
/// `zx_vcpu_read_state()` must be called on the same thread *handle* was created
/// on.
///
/// ## Rights
///
/// *handle* must be of type **ZX_OBJ_TYPE_VCPU** and have **ZX_RIGHT_READ**.
///
/// ## Return value
///
/// `zx_vcpu_read_state()` returns **ZX_OK** on success. On failure, an error value
/// is returned.
///
/// ## Errors
///
/// **ZX_ERR_ACCESS_DENIED** *handle* does not have the **ZX_RIGHT_READ** right.
///
/// **ZX_ERR_BAD_HANDLE** *handle* is an invalid handle.
///
/// **ZX_ERR_BAD_STATE** *handle* is in a bad state, and state can not be read.
///
/// **ZX_ERR_INVALID_ARGS** *kind* does not name a known VCPU state, *buffer* is an
/// invalid pointer, or *buffer_size* does not match the expected size of *kind*.
///
/// **ZX_ERR_WRONG_TYPE** *handle* is not a handle to a VCPU.
///
/// ## See also
///
/// - [`zx_guest_create()`]
/// - [`zx_guest_set_trap()`]
/// - [`zx_vcpu_create()`]
/// - [`zx_vcpu_enter()`]
/// - [`zx_vcpu_interrupt()`]
/// - [`zx_vcpu_kick()`]
/// - [`zx_vcpu_write_state()`]
///
/// [`zx_guest_create()`]: guest_create.md
/// [`zx_guest_set_trap()`]: guest_set_trap.md
/// [`zx_vcpu_create()`]: vcpu_create.md
/// [`zx_vcpu_enter()`]: vcpu_enter.md
/// [`zx_vcpu_interrupt()`]: vcpu_interrupt.md
/// [`zx_vcpu_kick()`]: vcpu_kick.md
/// [`zx_vcpu_write_state()`]: vcpu_write_state.md
ReadState(resource struct {
handle Handle:VCPU;
kind uint32;
}) -> (struct {
@voidptr
buffer vector<byte>:MAX;
}) error Status;
/// ## Summary
///
/// Write the state of a VCPU.
///
/// ## Declaration
///
/// ```c
/// #include <zircon/syscalls.h>
///
/// zx_status_t zx_vcpu_write_state(zx_handle_t handle,
/// uint32_t kind,
/// const void* buffer,
/// size_t buffer_size);
/// ```
///
/// ## Description
///
/// `zx_vcpu_write_state()` writes the state of *handle* as specified by *kind* from
/// *buffer*. It is only valid to write the state of *handle* when execution has
/// been paused.
///
/// *kind* may be **ZX_VCPU_STATE** or **ZX_VCPU_IO**.
///
/// `zx_vcpu_write_state()` must be called on the same thread *handle* was created
/// on.
///
/// ## Rights
///
/// *handle* must be of type **ZX_OBJ_TYPE_VCPU** and have **ZX_RIGHT_WRITE**.
///
/// ## Return value
///
/// `zx_vcpu_write_state()` returns **ZX_OK** on success. On failure, an error value
/// is returned.
///
/// ## Errors
///
/// **ZX_ERR_ACCESS_DENIED** *handle* does not have the **ZX_RIGHT_WRITE** right.
///
/// **ZX_ERR_BAD_HANDLE** *handle* is an invalid handle.
///
/// **ZX_ERR_BAD_STATE** *handle* is in a bad state, and state can not be written.
///
/// **ZX_ERR_INVALID_ARGS** *kind* does not name a known VCPU state, *buffer* is an
/// invalid pointer, or *buffer_size* does not match the expected size of *kind*.
///
/// **ZX_ERR_WRONG_TYPE** *handle* is not a handle to a VCPU.
///
/// ## See also
///
/// - [`zx_guest_create()`]
/// - [`zx_guest_set_trap()`]
/// - [`zx_vcpu_create()`]
/// - [`zx_vcpu_enter()`]
/// - [`zx_vcpu_interrupt()`]
/// - [`zx_vcpu_kick()`]
/// - [`zx_vcpu_read_state()`]
///
/// [`zx_guest_create()`]: guest_create.md
/// [`zx_guest_set_trap()`]: guest_set_trap.md
/// [`zx_vcpu_create()`]: vcpu_create.md
/// [`zx_vcpu_enter()`]: vcpu_enter.md
/// [`zx_vcpu_interrupt()`]: vcpu_interrupt.md
/// [`zx_vcpu_kick()`]: vcpu_kick.md
/// [`zx_vcpu_read_state()`]: vcpu_read_state.md
WriteState(resource struct {
handle Handle:VCPU;
kind uint32;
@voidptr
buffer vector<byte>:MAX;
}) -> () error Status;
};