diff options
author | Zach Reizner <zachr@google.com> | 2018-01-16 17:35:27 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-01-30 17:47:17 -0800 |
commit | e0983c762535a6c82b1206d4857b17eb9803d38c (patch) | |
tree | 064ba884fc17b26deb31ca7294cb3dbcb00d444c /plugin_proto | |
parent | fc44d8059b2333b7f49c1a11012eb6ca7d2250a5 (diff) | |
download | crosvm-e0983c762535a6c82b1206d4857b17eb9803d38c.tar crosvm-e0983c762535a6c82b1206d4857b17eb9803d38c.tar.gz crosvm-e0983c762535a6c82b1206d4857b17eb9803d38c.tar.bz2 crosvm-e0983c762535a6c82b1206d4857b17eb9803d38c.tar.lz crosvm-e0983c762535a6c82b1206d4857b17eb9803d38c.tar.xz crosvm-e0983c762535a6c82b1206d4857b17eb9803d38c.tar.zst crosvm-e0983c762535a6c82b1206d4857b17eb9803d38c.zip |
add plugin_proto crate
This module defines the protocol shared between the crosvm plugin process and main crosvm process. TEST=cargo build --features plugin BUG=chromium:800626 CQ-DEPEND=CL:892048 Change-Id: I5dfbe845644b7489f1918cecfcc07f28a223aa42 Reviewed-on: https://chromium-review.googlesource.com/869355 Commit-Ready: Zach Reizner <zachr@chromium.org> Tested-by: Zach Reizner <zachr@chromium.org> Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'plugin_proto')
-rw-r--r-- | plugin_proto/Cargo.toml | 12 | ||||
-rw-r--r-- | plugin_proto/build.rs | 27 | ||||
-rw-r--r-- | plugin_proto/protos/plugin.proto | 268 | ||||
-rw-r--r-- | plugin_proto/src/lib.rs | 2 |
4 files changed, 309 insertions, 0 deletions
diff --git a/plugin_proto/Cargo.toml b/plugin_proto/Cargo.toml new file mode 100644 index 0000000..6fe8198 --- /dev/null +++ b/plugin_proto/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "plugin_proto" +version = "0.5.0" +authors = ["The Chromium OS Authors"] +build = "build.rs" + +[dependencies] +protobuf = "=1.4.3" + +[build-dependencies] +gcc = "=0.3.54" +protoc-rust = "=1.4.3" diff --git a/plugin_proto/build.rs b/plugin_proto/build.rs new file mode 100644 index 0000000..5e30fcd --- /dev/null +++ b/plugin_proto/build.rs @@ -0,0 +1,27 @@ +// Copyright 2017 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +extern crate protoc_rust; + +use std::env; +use std::fs; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + + protoc_rust::run(protoc_rust::Args { + out_dir: out_dir.as_os_str().to_str().unwrap(), + input: &["protos/plugin.proto"], + includes: &["protos"], + }) + .expect("protoc"); + + let mut mod_out = fs::File::create(out_dir.join("proto_include.rs")).unwrap(); + writeln!(mod_out, + "#[path = \"{}\"] pub mod plugin_proto;\npub use plugin_proto::*;", + out_dir.join("plugin.rs").display()) + .unwrap(); +} diff --git a/plugin_proto/protos/plugin.proto b/plugin_proto/protos/plugin.proto new file mode 100644 index 0000000..aa959fc --- /dev/null +++ b/plugin_proto/protos/plugin.proto @@ -0,0 +1,268 @@ +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; + } + +// 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; + } + + 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 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; + } + + 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; + ReserveRange reserve_range = 5; + SetIrq set_irq = 6; + SetIrqRouting set_irq_routing = 7; + SetIdentityMapAddr set_identity_map_addr = 8; + PauseVcpus pause_vcpus = 9; + GetVcpus get_vcpus = 10; + Start start = 11; + // Method for a Memory type object for retrieving the dirty bitmap. + 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 ReserveRange {} + message SetIrq {} + message SetIrqRouting {} + 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; + ReserveRange reserve_range = 6; + SetIrq set_irq = 7; + SetIrqRouting set_irq_routing = 8; + SetIdentityMapAddr set_identity_map_addr = 9; + PauseVcpus pause_vcpus = 10; + GetVcpus get_vcpus = 11; + Start start = 12; + 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 a set of KVM VCPU registers. 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; + } + + message GetState { + StateSet set = 1; + } + + message SetState { + StateSet set = 1; + // The in memory representation of a struct kvm_regs, struct kvm_sregs, or struct kvm_fpu, + // depending on the value of the StateSet. + bytes state = 2; + } + + // 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; + } +} + + +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, or struct kvm_fpu, + // depending on what StateSet was requested in GetState. + bytes state = 1; + } + + message SetState { + } + + // 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; + } +} diff --git a/plugin_proto/src/lib.rs b/plugin_proto/src/lib.rs new file mode 100644 index 0000000..7f0d66c --- /dev/null +++ b/plugin_proto/src/lib.rs @@ -0,0 +1,2 @@ +extern crate protobuf; +include!(concat!(env!("OUT_DIR"), "/proto_include.rs")); |