mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-01-27 02:28:22 +00:00
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>
This commit is contained in:
parent
fc44d8059b
commit
e0983c7625
6 changed files with 417 additions and 12 deletions
116
Cargo.lock
generated
116
Cargo.lock
generated
|
@ -1,8 +1,30 @@
|
|||
[root]
|
||||
name = "x86_64"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"data_model 0.1.0",
|
||||
"kvm 0.1.0",
|
||||
"kvm_sys 0.1.0",
|
||||
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sys_util 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "crosvm"
|
||||
version = "0.1.0"
|
||||
|
@ -14,6 +36,7 @@ dependencies = [
|
|||
"kernel_loader 0.1.0",
|
||||
"kvm 0.1.0",
|
||||
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"plugin_proto 0.5.0",
|
||||
"qcow 0.1.0",
|
||||
"sys_util 0.1.0",
|
||||
"vm_control 0.1.0",
|
||||
|
@ -40,6 +63,20 @@ dependencies = [
|
|||
"vm_control 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon-sys"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.54"
|
||||
|
@ -82,6 +119,14 @@ name = "libc"
|
|||
version = "0.2.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "net_sys"
|
||||
version = "0.1.0"
|
||||
|
@ -98,6 +143,38 @@ dependencies = [
|
|||
"sys_util 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plugin_proto"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"protobuf 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"protoc-rust 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "protoc"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protoc-rust"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"protobuf 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"protoc 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "qcow"
|
||||
version = "0.1.0"
|
||||
|
@ -107,6 +184,15 @@ dependencies = [
|
|||
"sys_util 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.3.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sys_util"
|
||||
version = "0.1.0"
|
||||
|
@ -121,6 +207,14 @@ dependencies = [
|
|||
name = "syscall_defines"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "tempdir"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vhost"
|
||||
version = "0.1.0"
|
||||
|
@ -149,19 +243,17 @@ dependencies = [
|
|||
"sys_util 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x86_64"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"data_model 0.1.0",
|
||||
"kvm 0.1.0",
|
||||
"kvm_sys 0.1.0",
|
||||
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sys_util 0.1.0",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
||||
"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d"
|
||||
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
|
||||
"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0"
|
||||
"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2"
|
||||
"checksum protobuf 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bec26e67194b7d991908145fdf21b7cae8b08423d96dcb9e860cd31f854b9506"
|
||||
"checksum protoc 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5379c34ea2f9c69b99e6f25f6d0e6619876195ae7a3dcaf69f66bdb6c2e4dceb"
|
||||
"checksum protoc-rust 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e211a7f56b2d020a59d483f652cfdfa6fd42e37bf544c0231e373807aa316c45"
|
||||
"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1"
|
||||
"checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6"
|
||||
|
|
|
@ -9,6 +9,9 @@ panic = 'abort'
|
|||
|
||||
[workspace]
|
||||
|
||||
[features]
|
||||
plugin = ["plugin_proto"]
|
||||
|
||||
[dependencies]
|
||||
devices = { path = "devices" }
|
||||
io_jail = { path = "io_jail" }
|
||||
|
@ -20,6 +23,7 @@ byteorder = "=1.1.0"
|
|||
vm_control = { path = "vm_control" }
|
||||
data_model = { path = "data_model" }
|
||||
qcow = { path = "qcow" }
|
||||
plugin_proto = { path = "plugin_proto", optional = true }
|
||||
|
||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||
x86_64 = { path = "x86_64" }
|
||||
|
|
12
plugin_proto/Cargo.toml
Normal file
12
plugin_proto/Cargo.toml
Normal file
|
@ -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"
|
27
plugin_proto/build.rs
Normal file
27
plugin_proto/build.rs
Normal file
|
@ -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();
|
||||
}
|
268
plugin_proto/protos/plugin.proto
Normal file
268
plugin_proto/protos/plugin.proto
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
2
plugin_proto/src/lib.rs
Normal file
2
plugin_proto/src/lib.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
extern crate protobuf;
|
||||
include!(concat!(env!("OUT_DIR"), "/proto_include.rs"));
|
Loading…
Reference in a new issue