blob: 48e1659d82e9f7fdac210bb690b1582d5040dcc6 [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")
closed 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
strict 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
strict 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
strict 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
strict 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
strict 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
strict WriteState(resource struct {
handle Handle:VCPU;
kind uint32;
@voidptr
buffer vector<byte>:MAX;
}) -> () error Status;
};