mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-12-26 13:10:56 +00:00
658357638c
Add crossvm plugin API to allow fetching list of supported MSRs. BUG=b:111083877 TEST=cargo test -p kvm; cargo test --features=plugin Change-Id: I178c7bc33d606bef10422faac6bb9afb3fe0a014 Signed-off-by: Dmitry Torokhov <dtor@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1152229 Reviewed-by: Zach Reizner <zachr@chromium.org>
403 lines
12 KiB
Protocol Buffer
403 lines
12 KiB
Protocol Buffer
syntax = "proto3";
|
|
|
|
// The protocol defined here is actually two sub-protocols, one protocol for control of the main
|
|
// process (MainRequest/MainResponse), and one for control of each VCPU thread
|
|
// (VcpuRequest/VcpuResponse). Each protocol works the same: the client creates a protobuf of either
|
|
// a MainRequest or VcpuRequest, sends it encoded over the main socket or one of the vcpu sockets,
|
|
// reads the the MainResponse or VcpuResponse over the same socket and decodes it as a protobuf. For
|
|
// specific information on the purpose of each request, see the C API in crosvm.h. Most requests
|
|
// here map 1:1 to a function in that API. Only the intricacies unique to the wire protocol are
|
|
// commented on here.
|
|
|
|
enum AddressSpace {
|
|
IOPORT = 0;
|
|
MMIO = 1;
|
|
}
|
|
|
|
message CpuidEntry {
|
|
uint32 function = 1;
|
|
bool has_index = 3;
|
|
uint32 index = 4;
|
|
uint32 eax = 5;
|
|
uint32 ebx = 6;
|
|
uint32 ecx = 7;
|
|
uint32 edx = 8;
|
|
}
|
|
|
|
// A request made to the crosvm main process that affects the global aspects of the VM.
|
|
message MainRequest {
|
|
// Every message under the Create namespace will instantiate an object with the given ID. The
|
|
// type of object is determined by the oneof constructor field.
|
|
message Create {
|
|
message IoEvent {
|
|
AddressSpace space = 1;
|
|
uint64 address = 2;
|
|
uint32 length = 3;
|
|
uint64 datamatch = 4;
|
|
}
|
|
|
|
message Memory {
|
|
uint64 offset = 1;
|
|
uint64 start = 2;
|
|
uint64 length = 3;
|
|
bool read_only = 4;
|
|
// Must be true for the MemoryDirtyLog method to work on this object.
|
|
bool dirty_log = 5;
|
|
}
|
|
|
|
message IrqEvent {
|
|
uint32 irq_id = 1;
|
|
bool resample = 2;
|
|
}
|
|
|
|
uint32 id = 1;
|
|
oneof constructor {
|
|
IoEvent io_event = 2;
|
|
// This message also requires a memfd sent over the socket.
|
|
Memory memory = 3;
|
|
IrqEvent irq_event = 4;
|
|
}
|
|
}
|
|
|
|
// No matter what the type an object is, it can be destroyed using this common method.
|
|
message Destroy {
|
|
uint32 id = 1;
|
|
}
|
|
|
|
message NewConnection {}
|
|
|
|
message GetShutdownEventfd {}
|
|
|
|
message CheckExtension {
|
|
uint32 extension = 1;
|
|
}
|
|
|
|
message CpuidRequest {
|
|
}
|
|
|
|
message MsrListRequest {
|
|
}
|
|
|
|
message GetNetConfig {}
|
|
|
|
message ReserveRange {
|
|
AddressSpace space = 1;
|
|
uint64 start = 2;
|
|
uint64 length = 3;
|
|
}
|
|
|
|
message SetIrq {
|
|
uint32 irq_id = 1;
|
|
bool active = 2;
|
|
}
|
|
|
|
message SetIrqRouting {
|
|
message Route {
|
|
message Irqchip {
|
|
uint32 irqchip = 1;
|
|
uint32 pin = 2;
|
|
}
|
|
|
|
message Msi {
|
|
uint64 address = 1;
|
|
uint32 data = 2;
|
|
}
|
|
|
|
uint32 irq_id = 1;
|
|
oneof route {
|
|
Irqchip irqchip = 2;
|
|
Msi msi = 3;
|
|
}
|
|
}
|
|
|
|
repeated Route routes = 1;
|
|
}
|
|
|
|
// Each type refers to certain piece of VM state (such as PIT state).
|
|
// The structure of the data corresponds to the kvm structure.
|
|
enum StateSet {
|
|
// struct kvm_pic_state
|
|
PIC0 = 0;
|
|
// struct kvm_pic_state
|
|
PIC1 = 1;
|
|
// struct kvm_ioapic_state
|
|
IOAPIC = 2;
|
|
// struct kvm_pit_state2
|
|
PIT = 3;
|
|
}
|
|
|
|
message GetState {
|
|
StateSet set = 1;
|
|
}
|
|
|
|
message SetState {
|
|
StateSet set = 1;
|
|
// The in memory representation of certain state, depending on the value
|
|
// of the StateSet.
|
|
bytes state = 2;
|
|
}
|
|
|
|
message SetIdentityMapAddr {
|
|
uint32 address = 1;
|
|
}
|
|
|
|
message PauseVcpus {
|
|
uint64 cpu_mask = 1;
|
|
uint64 user = 2;
|
|
}
|
|
|
|
message GetVcpus {}
|
|
message Start {}
|
|
|
|
message MemoryDirtyLog {
|
|
uint32 id = 1;
|
|
}
|
|
|
|
// The type of the message is determined by which of these oneof fields is present in the
|
|
// protobuf.
|
|
oneof message {
|
|
// Common method for instantiating a new object of any type.
|
|
Create create = 1;
|
|
// Common method for destroying an object of any type.
|
|
Destroy destroy = 2;
|
|
NewConnection new_connection = 3;
|
|
GetShutdownEventfd get_shutdown_eventfd = 4;
|
|
CheckExtension check_extension = 5;
|
|
CpuidRequest get_supported_cpuid = 6;
|
|
CpuidRequest get_emulated_cpuid = 7;
|
|
MsrListRequest get_msr_index_list = 8;
|
|
GetNetConfig get_net_config = 9;
|
|
ReserveRange reserve_range = 10;
|
|
SetIrq set_irq = 11;
|
|
SetIrqRouting set_irq_routing = 12;
|
|
GetState get_state = 13;
|
|
SetState set_state = 14;
|
|
SetIdentityMapAddr set_identity_map_addr = 15;
|
|
PauseVcpus pause_vcpus = 16;
|
|
GetVcpus get_vcpus = 17;
|
|
Start start = 18;
|
|
// Method for a Memory type object for retrieving the dirty bitmap. Only valid if the memory
|
|
// object was created with dirty_log set.
|
|
MemoryDirtyLog dirty_log = 101;
|
|
}
|
|
}
|
|
|
|
message MainResponse {
|
|
// Depending on the object that was created, an fd might also come from the socket.
|
|
message Create {}
|
|
message Destroy {}
|
|
// NewMessage receives a socket fd along with the data from reading this socket.
|
|
// The returned socket can be used totally independently of the original socket, and can perform
|
|
// requests and responses independent of the other sockets.
|
|
message NewConnection {}
|
|
message GetShutdownEventfd {}
|
|
message CheckExtension {
|
|
bool has_extension = 1;
|
|
}
|
|
message CpuidResponse {
|
|
repeated CpuidEntry entries = 1;
|
|
}
|
|
message MsrListResponse {
|
|
repeated uint32 indices = 1;
|
|
}
|
|
|
|
// GetNetConfig messages also return a file descriptor for the tap device.
|
|
message GetNetConfig {
|
|
bytes host_mac_address = 1;
|
|
fixed32 host_ipv4_address = 2;
|
|
fixed32 netmask = 3;
|
|
}
|
|
|
|
message ReserveRange {}
|
|
message SetIrq {}
|
|
message SetIrqRouting {}
|
|
message GetState {
|
|
// The in memory representation of a state, depending on what StateSet was
|
|
// requested in GetState.
|
|
bytes state = 1;
|
|
}
|
|
message SetState {}
|
|
message SetIdentityMapAddr {}
|
|
message PauseVcpus {}
|
|
// This message should also receive a socket fd per VCPU along with the data from reading this
|
|
// socket. The VcpuRequest/VcpuResponse protocol is run over each of the returned fds.
|
|
message GetVcpus {}
|
|
message Start {}
|
|
message MemoryDirtyLog {
|
|
bytes bitmap = 1;
|
|
}
|
|
|
|
// This is zero on success, and a negative integer on failure.
|
|
sint32 errno = 1;
|
|
// The field present here is always the same as the one present in the corresponding
|
|
// MainRequest.
|
|
oneof message {
|
|
Create create = 2;
|
|
Destroy destroy = 3;
|
|
NewConnection new_connection = 4;
|
|
GetShutdownEventfd get_shutdown_eventfd = 5;
|
|
CheckExtension check_extension = 6;
|
|
CpuidResponse get_supported_cpuid = 7;
|
|
CpuidResponse get_emulated_cpuid = 8;
|
|
MsrListResponse get_msr_index_list = 9;
|
|
GetNetConfig get_net_config = 10;
|
|
ReserveRange reserve_range = 11;
|
|
SetIrq set_irq = 12;
|
|
SetIrqRouting set_irq_routing = 13;
|
|
GetState get_state = 14;
|
|
SetState set_state = 15;
|
|
SetIdentityMapAddr set_identity_map_addr = 16;
|
|
PauseVcpus pause_vcpus = 17;
|
|
GetVcpus get_vcpus = 18;
|
|
Start start = 19;
|
|
MemoryDirtyLog dirty_log = 101;
|
|
}
|
|
}
|
|
|
|
// A request made for a specific VCPU. These requests are sent over the sockets returned from the
|
|
// GetVcpu MainRequest.
|
|
message VcpuRequest {
|
|
// This message will block until a non-empty response can be sent. The first response will
|
|
// always be an Init wait reason.
|
|
message Wait {
|
|
}
|
|
|
|
message Resume {
|
|
// The data is only necessary for non-write (read) I/O accesses. In all other cases, data is
|
|
// ignored.
|
|
bytes data = 1;
|
|
}
|
|
|
|
// Each type refers to certain piece of VCPU state (a set registers, or something else).
|
|
// The structure of the data corresponds to the kvm structure.
|
|
enum StateSet {
|
|
// struct kvm_regs
|
|
REGS = 0;
|
|
// struct kvm_sregs
|
|
SREGS = 1;
|
|
// struct kvm_fpu
|
|
FPU = 2;
|
|
// struct kvm_debugregs
|
|
DEBUGREGS = 3;
|
|
// struct kvm_lapic_state
|
|
LAPIC = 4;
|
|
// struct kvm_mp_state
|
|
MP = 5;
|
|
// struct kvm_xcrs
|
|
XCREGS = 6;
|
|
// struct kvm_vcpu_events
|
|
EVENTS = 7;
|
|
}
|
|
|
|
message GetState {
|
|
StateSet set = 1;
|
|
}
|
|
|
|
message SetState {
|
|
StateSet set = 1;
|
|
// The in memory representation of a struct kvm_regs, struct kvm_sregs,
|
|
// struct kvm_fpu, struct kvm_debugregs, struct kvm_lapic_state,
|
|
// struct kvm_mp_state, struct kvm_xcrs or struct kvm_vcpu_events
|
|
// depending on the value of the StateSet.
|
|
bytes state = 2;
|
|
}
|
|
|
|
message GetMsrs {
|
|
// The entry data will be returned in the same order as this in the
|
|
// VcpuResponse::GetMsrs::entry_data array.
|
|
repeated uint32 entry_indices = 1;
|
|
}
|
|
|
|
message MsrEntry {
|
|
uint32 index = 1;
|
|
uint64 data = 2;
|
|
}
|
|
|
|
message SetMsrs {
|
|
repeated MsrEntry entries = 1;
|
|
}
|
|
|
|
message SetCpuid {
|
|
repeated CpuidEntry entries = 1;
|
|
}
|
|
|
|
// The type of the message is determined by which of these oneof fields is present in the
|
|
// protobuf.
|
|
oneof message {
|
|
Wait wait = 1;
|
|
Resume resume = 2;
|
|
GetState get_state = 3;
|
|
SetState set_state = 4;
|
|
GetMsrs get_msrs = 5;
|
|
SetMsrs set_msrs = 6;
|
|
SetCpuid set_cpuid = 7;
|
|
}
|
|
}
|
|
|
|
|
|
message VcpuResponse {
|
|
// Depending on the reason a VCPU has exited, the Wait request will unblock and return a field
|
|
// in the oneof exit. This is called the "wait reason."
|
|
message Wait {
|
|
// This request will always be the first wait reason returend by the first wait request.
|
|
message Init {
|
|
}
|
|
|
|
// This type of wait reason is only generated if the access occurred on this VCPU on an
|
|
// address previously reserved by a ReserveRange main request.
|
|
message Io {
|
|
AddressSpace space = 1;
|
|
uint64 address = 2;
|
|
bool is_write = 3;
|
|
bytes data = 4;
|
|
}
|
|
|
|
// This type of wait reason is only generated after a PuaseVcpus request on this VCPU.
|
|
message User {
|
|
uint64 user = 1;
|
|
}
|
|
|
|
oneof exit {
|
|
Init init = 1;
|
|
Io io = 2;
|
|
User user = 3;
|
|
}
|
|
}
|
|
|
|
message Resume {}
|
|
|
|
message GetState {
|
|
// The in memory representation of a struct kvm_regs, struct kvm_sregs,
|
|
// struct kvm_fpu, struct kvm_debugregs, struct kvm_lapic_state,
|
|
// struct kvm_mp_state, struct kvm_xcrs or struct kvm_vcpu_events
|
|
// depending on the value of the StateSet.
|
|
bytes state = 1;
|
|
}
|
|
|
|
message SetState {
|
|
}
|
|
|
|
message GetMsrs {
|
|
// The order of the entry_data values is the same order as the array of indices given in the
|
|
// corresponding request.
|
|
repeated uint64 entry_data = 1;
|
|
}
|
|
|
|
message SetMsrs {}
|
|
|
|
message SetCpuid {}
|
|
|
|
// This is zero on success, and a negative integer on failure.
|
|
sint32 errno = 1;
|
|
// The field present here is always the same as the one present in the corresponding
|
|
// VcpuRequest.
|
|
oneof message {
|
|
Wait wait = 2;
|
|
Resume resume = 3;
|
|
GetState get_state = 4;
|
|
SetState set_state = 5;
|
|
GetMsrs get_msrs = 6;
|
|
SetMsrs set_msrs = 7;
|
|
SetCpuid set_cpuid = 8;
|
|
}
|
|
}
|