1syntax = "proto3";
2
3// The protocol defined here is actually two sub-protocols, one protocol for control of the main
4// process (MainRequest/MainResponse), and one for control of each VCPU thread
5// (VcpuRequest/VcpuResponse). Each protocol works the same: the client creates a protobuf of either
6// a MainRequest or VcpuRequest, sends it encoded over the main socket or one of the vcpu sockets,
7// reads the the MainResponse or VcpuResponse over the same socket and decodes it as a protobuf. For
8// specific information on the purpose of each request, see the C API in crosvm.h. Most requests
9// here map 1:1 to a function in that API. Only the intricacies unique to the wire protocol are
10// commented on here.
11
12enum AddressSpace {
13    IOPORT = 0;
14    MMIO = 1;
15 }
16
17message CpuidEntry  {
18    uint32 function = 1;
19    bool has_index = 3;
20    uint32 index = 4;
21    uint32 eax = 5;
22    uint32 ebx = 6;
23    uint32 ecx = 7;
24    uint32 edx = 8;
25}
26
27// A request made to the crosvm main process that affects the global aspects of the VM.
28message MainRequest {
29    // Every message under the Create namespace will instantiate an object with the given ID. The
30    // type of object is determined by the oneof constructor field.
31    message Create {
32        message IoEvent {
33            AddressSpace space = 1;
34            uint64 address = 2;
35            uint32 length = 3;
36            uint64 datamatch = 4;
37        }
38
39        message Memory {
40            uint64 offset = 1;
41            uint64 start = 2;
42            uint64 length = 3;
43            bool read_only = 4;
44            // Must be true for the MemoryDirtyLog method to work on this object.
45            bool dirty_log = 5;
46        }
47
48        message IrqEvent {
49            uint32 irq_id = 1;
50            bool resample = 2;
51        }
52
53        uint32 id = 1;
54        oneof constructor {
55            IoEvent io_event = 2;
56            // This message also requires a memfd sent over the socket.
57            Memory memory = 3;
58            IrqEvent irq_event = 4;
59        }
60    }
61
62    // No matter what the type an object is, it can be destroyed using this common method.
63    message Destroy {
64        uint32 id = 1;
65    }
66
67    message NewConnection {}
68
69    message GetShutdownEventfd {}
70
71    message CheckExtension {
72        uint32 extension = 1;
73    }
74
75    message CpuidRequest {
76    }
77
78    message MsrListRequest {
79    }
80
81    message GetNetConfig {}
82
83    message ReserveRange {
84        AddressSpace space = 1;
85        uint64 start = 2;
86        uint64 length = 3;
87        bool async_write = 4;
88    }
89
90    message SetIrq {
91        uint32 irq_id = 1;
92        bool active = 2;
93    }
94
95    message SetIrqRouting {
96        message Route {
97            message Irqchip {
98                uint32 irqchip = 1;
99                uint32 pin = 2;
100            }
101
102            message Msi {
103                uint64 address = 1;
104                uint32 data = 2;
105            }
106
107            uint32 irq_id = 1;
108            oneof route {
109                Irqchip irqchip = 2;
110                Msi msi = 3;
111            }
112        }
113
114        repeated Route routes = 1;
115    }
116
117    // Each type refers to certain piece of VM state (such as PIT state).
118    // The structure of the data corresponds to the kvm structure.
119    enum StateSet {
120        // struct kvm_pic_state
121        PIC0 = 0;
122        // struct kvm_pic_state
123        PIC1 = 1;
124        // struct kvm_ioapic_state
125        IOAPIC = 2;
126        // struct kvm_pit_state2
127        PIT = 3;
128        // struct kvm_clock_data
129        CLOCK = 4;
130    }
131
132    message GetState {
133        StateSet set = 1;
134    }
135
136    message SetState {
137        StateSet set = 1;
138        // The in memory representation of certain state, depending on the value
139        // of the StateSet.
140        bytes state = 2;
141    }
142
143    message SetIdentityMapAddr {
144        uint32 address = 1;
145    }
146
147    message PauseVcpus {
148        uint64 cpu_mask = 1;
149        uint64 user = 2;
150    }
151
152    message GetVcpus {}
153    message Start {}
154
155    message SetCallHint {
156        message RegHint {
157	    bool match_rax = 1;
158	    bool match_rbx = 2;
159	    bool match_rcx = 3;
160	    bool match_rdx = 4;
161	    uint64 rax = 5;
162	    uint64 rbx = 6;
163	    uint64 rcx = 7;
164	    uint64 rdx = 8;
165	    bool send_sregs = 9;
166	    bool send_debugregs = 10;
167	}
168
169        AddressSpace space = 1;
170        uint64 address = 2;
171        bool on_write = 3;
172
173        repeated RegHint hints = 4;
174    }
175
176    message MemoryDirtyLog {
177        uint32 id = 1;
178    }
179
180    // The type of the message is determined by which of these oneof fields is present in the
181    // protobuf.
182    oneof message {
183        // Common method for instantiating a new object of any type.
184        Create create = 1;
185        // Common method for destroying an object of any type.
186        Destroy destroy = 2;
187        NewConnection new_connection = 3;
188        GetShutdownEventfd get_shutdown_eventfd = 4;
189        CheckExtension check_extension = 5;
190        CpuidRequest get_supported_cpuid = 6;
191        CpuidRequest get_emulated_cpuid = 7;
192        MsrListRequest get_msr_index_list = 8;
193        GetNetConfig get_net_config = 9;
194        ReserveRange reserve_range = 10;
195        SetIrq set_irq = 11;
196        SetIrqRouting set_irq_routing = 12;
197        GetState get_state = 13;
198        SetState set_state = 14;
199        SetIdentityMapAddr set_identity_map_addr = 15;
200        PauseVcpus pause_vcpus = 16;
201        GetVcpus get_vcpus = 17;
202        Start start = 18;
203        SetCallHint set_call_hint = 19;
204        // Method for a Memory type object for retrieving the dirty bitmap. Only valid if the memory
205        // object was created with dirty_log set.
206        MemoryDirtyLog dirty_log = 101;
207    }
208}
209
210message MainResponse {
211    // Depending on the object that was created, an fd might also come from the socket.
212    message Create {}
213    message Destroy {}
214    // NewMessage receives a socket fd along with the data from reading this socket.
215    // The returned socket can be used totally independently of the original socket, and can perform
216    // requests and responses independent of the other sockets.
217    message NewConnection {}
218    message GetShutdownEventfd {}
219    message CheckExtension {
220        bool has_extension = 1;
221    }
222    message CpuidResponse {
223        repeated CpuidEntry entries = 1;
224    }
225    message MsrListResponse {
226        repeated uint32 indices = 1;
227    }
228
229    // GetNetConfig messages also return a file descriptor for the tap device.
230    message GetNetConfig {
231        bytes host_mac_address = 1;
232        fixed32 host_ipv4_address = 2;
233        fixed32 netmask = 3;
234    }
235
236    message ReserveRange {}
237    message SetIrq {}
238    message SetIrqRouting {}
239    message GetState {
240        // The in memory representation of a state, depending on what StateSet was
241        // requested in GetState.
242        bytes state = 1;
243    }
244    message SetState {}
245    message SetIdentityMapAddr {}
246    message PauseVcpus {}
247    // This message should also receive a socket fd per VCPU along with the data from reading this
248    // socket. The VcpuRequest/VcpuResponse protocol is run over each of the returned fds.
249    message GetVcpus {}
250    message Start {}
251    message SetCallHint {}
252    message MemoryDirtyLog {
253        bytes bitmap = 1;
254    }
255
256    // This is zero on success, and a negative integer on failure.
257    sint32 errno = 1;
258    // The field present here is always the same as the one present in the corresponding
259    // MainRequest.
260    oneof message {
261        Create create = 2;
262        Destroy destroy = 3;
263        NewConnection new_connection = 4;
264        GetShutdownEventfd get_shutdown_eventfd = 5;
265        CheckExtension check_extension = 6;
266        CpuidResponse get_supported_cpuid = 7;
267        CpuidResponse get_emulated_cpuid = 8;
268        MsrListResponse get_msr_index_list = 9;
269        GetNetConfig get_net_config = 10;
270        ReserveRange reserve_range = 11;
271        SetIrq set_irq = 12;
272        SetIrqRouting set_irq_routing = 13;
273        GetState get_state = 14;
274        SetState set_state = 15;
275        SetIdentityMapAddr set_identity_map_addr = 16;
276        PauseVcpus pause_vcpus = 17;
277        GetVcpus get_vcpus = 18;
278        Start start = 19;
279        SetCallHint set_call_hint = 20;
280        MemoryDirtyLog dirty_log = 101;
281    }
282}
283
284// A request made for a specific VCPU. These requests are sent over the sockets returned from the
285// GetVcpu MainRequest.
286message VcpuRequest {
287    // This message will block until a non-empty response can be sent. The first response will
288    // always be an Init wait reason.
289    message Wait {
290    }
291
292    message Resume {
293        // The data is only necessary for non-write (read) I/O accesses. In all other cases, data is
294        // ignored.
295        bytes data = 1;
296
297        // The following tracks what deferred set calls to apply.
298        bytes regs = 2;
299        bytes sregs = 3;
300        bytes debugregs = 4;
301    }
302
303    // Each type refers to certain piece of VCPU state (a set registers, or something else).
304    // The structure of the data corresponds to the kvm structure.
305    enum StateSet {
306        // struct kvm_regs
307        REGS = 0;
308        // struct kvm_sregs
309        SREGS = 1;
310        // struct kvm_fpu
311        FPU = 2;
312        // struct kvm_debugregs
313        DEBUGREGS = 3;
314        // struct kvm_lapic_state
315        LAPIC = 4;
316        // struct kvm_mp_state
317        MP = 5;
318        // struct kvm_xcrs
319        XCREGS = 6;
320        // struct kvm_vcpu_events
321        EVENTS = 7;
322    }
323
324    message GetState {
325        StateSet set = 1;
326    }
327
328    message SetState {
329        StateSet set = 1;
330        // The in memory representation of a struct kvm_regs, struct kvm_sregs,
331        // struct kvm_fpu, struct kvm_debugregs, struct kvm_lapic_state,
332        // struct kvm_mp_state, struct kvm_xcrs or struct kvm_vcpu_events
333        // depending on the value of the StateSet.
334        bytes state = 2;
335    }
336
337    message CpuidRequest {
338    }
339
340    message GetMsrs {
341        // The entry data will be returned in the same order as this in the
342        // VcpuResponse::GetMsrs::entry_data array.
343        repeated uint32 entry_indices = 1;
344    }
345
346    message MsrEntry {
347        uint32 index = 1;
348        uint64 data = 2;
349    }
350
351    message SetMsrs {
352        repeated MsrEntry entries = 1;
353    }
354
355    message SetCpuid {
356        repeated CpuidEntry entries = 1;
357    }
358
359    message Shutdown {
360    }
361
362    message EnableCapability {
363        uint32 capability = 1;
364    }
365
366    // The type of the message is determined by which of these oneof fields is present in the
367    // protobuf.
368    oneof message {
369        Wait wait = 1;
370        Resume resume = 2;
371        GetState get_state = 3;
372        SetState set_state = 4;
373        GetMsrs get_msrs = 5;
374        SetMsrs set_msrs = 6;
375        SetCpuid set_cpuid = 7;
376        Shutdown shutdown = 8;
377        CpuidRequest get_hyperv_cpuid = 9;
378        EnableCapability enable_capability = 10;
379    }
380}
381
382
383message VcpuResponse  {
384    // Depending on the reason a VCPU has exited, the Wait request will unblock and return a field
385    // in the oneof exit. This is called the "wait reason."
386    message Wait {
387        // This request will always be the first wait reason returend by the first wait request.
388        message Init {
389        }
390
391        // This type of wait reason is only generated if the access occurred on this VCPU on an
392        // address previously reserved by a ReserveRange main request.
393        message Io {
394            AddressSpace space = 1;
395            uint64 address = 2;
396            bool is_write = 3;
397            bool no_resume = 4;
398            bytes data = 5;
399
400            // The following can be eagerly provided.
401            bytes regs = 6;
402            bytes sregs = 7;
403            bytes debugregs = 8;
404        }
405
406        // This type of wait reason is only generated after a PauseVcpus request on this VCPU.
407        message User {
408            uint64 user = 1;
409        }
410
411        message HypervCall {
412            uint64 input = 1;
413            uint64 params0 = 2;
414            uint64 params1 = 3;
415        }
416
417        message HypervSynic {
418            uint32 msr = 1;
419            uint64 control = 2;
420            uint64 evt_page = 3;
421            uint64 msg_page = 4;
422        }
423
424        oneof exit {
425            Init init = 1;
426            Io io = 2;
427            User user = 3;
428            HypervCall hyperv_call = 4;
429            HypervSynic hyperv_synic = 5;
430        }
431    }
432
433    message GetState {
434        // The in memory representation of a struct kvm_regs, struct kvm_sregs,
435        // struct kvm_fpu, struct kvm_debugregs, struct kvm_lapic_state,
436        // struct kvm_mp_state, struct kvm_xcrs or struct kvm_vcpu_events
437        // depending on the value of the StateSet.
438        bytes state = 1;
439    }
440
441    message SetState {
442    }
443
444    message CpuidResponse {
445        repeated CpuidEntry entries = 1;
446    }
447
448    message GetMsrs {
449        // The order of the entry_data values is the same order as the array of indices given in the
450        // corresponding request.
451        repeated uint64 entry_data = 1;
452    }
453
454    message SetMsrs {}
455
456    message SetCpuid {}
457
458    message EnableCapability {}
459
460    // This is zero on success, and a negative integer on failure.
461    sint32 errno = 1;
462    // The field present here is always the same as the one present in the corresponding
463    // VcpuRequest.
464    oneof message {
465        Wait wait = 2;
466        // resume was 3 but no longer gets a reply.
467        GetState get_state = 4;
468        SetState set_state = 5;
469        GetMsrs get_msrs = 6;
470        SetMsrs set_msrs = 7;
471        SetCpuid set_cpuid = 8;
472        CpuidResponse get_hyperv_cpuid = 9;
473        EnableCapability enable_capability = 10;
474    }
475}
476