• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    }
88
89    message SetIrq {
90        uint32 irq_id = 1;
91        bool active = 2;
92    }
93
94    message SetIrqRouting {
95        message Route {
96            message Irqchip {
97                uint32 irqchip = 1;
98                uint32 pin = 2;
99            }
100
101            message Msi {
102                uint64 address = 1;
103                uint32 data = 2;
104            }
105
106            uint32 irq_id = 1;
107            oneof route {
108                Irqchip irqchip = 2;
109                Msi msi = 3;
110            }
111        }
112
113        repeated Route routes = 1;
114    }
115
116    // Each type refers to certain piece of VM state (such as PIT state).
117    // The structure of the data corresponds to the kvm structure.
118    enum StateSet {
119        // struct kvm_pic_state
120        PIC0 = 0;
121        // struct kvm_pic_state
122        PIC1 = 1;
123        // struct kvm_ioapic_state
124        IOAPIC = 2;
125        // struct kvm_pit_state2
126        PIT = 3;
127        // struct kvm_clock_data
128        CLOCK = 4;
129    }
130
131    message GetState {
132        StateSet set = 1;
133    }
134
135    message SetState {
136        StateSet set = 1;
137        // The in memory representation of certain state, depending on the value
138        // of the StateSet.
139        bytes state = 2;
140    }
141
142    message SetIdentityMapAddr {
143        uint32 address = 1;
144    }
145
146    message PauseVcpus {
147        uint64 cpu_mask = 1;
148        uint64 user = 2;
149    }
150
151    message GetVcpus {}
152    message Start {}
153
154    message MemoryDirtyLog {
155        uint32 id = 1;
156    }
157
158    // The type of the message is determined by which of these oneof fields is present in the
159    // protobuf.
160    oneof message {
161        // Common method for instantiating a new object of any type.
162        Create create = 1;
163        // Common method for destroying an object of any type.
164        Destroy destroy = 2;
165        NewConnection new_connection = 3;
166        GetShutdownEventfd get_shutdown_eventfd = 4;
167        CheckExtension check_extension = 5;
168        CpuidRequest get_supported_cpuid = 6;
169        CpuidRequest get_emulated_cpuid = 7;
170        MsrListRequest get_msr_index_list = 8;
171        GetNetConfig get_net_config = 9;
172        ReserveRange reserve_range = 10;
173        SetIrq set_irq = 11;
174        SetIrqRouting set_irq_routing = 12;
175        GetState get_state = 13;
176        SetState set_state = 14;
177        SetIdentityMapAddr set_identity_map_addr = 15;
178        PauseVcpus pause_vcpus = 16;
179        GetVcpus get_vcpus = 17;
180        Start start = 18;
181        // Method for a Memory type object for retrieving the dirty bitmap. Only valid if the memory
182        // object was created with dirty_log set.
183        MemoryDirtyLog dirty_log = 101;
184    }
185}
186
187message MainResponse {
188    // Depending on the object that was created, an fd might also come from the socket.
189    message Create {}
190    message Destroy {}
191    // NewMessage receives a socket fd along with the data from reading this socket.
192    // The returned socket can be used totally independently of the original socket, and can perform
193    // requests and responses independent of the other sockets.
194    message NewConnection {}
195    message GetShutdownEventfd {}
196    message CheckExtension {
197        bool has_extension = 1;
198    }
199    message CpuidResponse {
200        repeated CpuidEntry entries = 1;
201    }
202    message MsrListResponse {
203        repeated uint32 indices = 1;
204    }
205
206    // GetNetConfig messages also return a file descriptor for the tap device.
207    message GetNetConfig {
208        bytes host_mac_address = 1;
209        fixed32 host_ipv4_address = 2;
210        fixed32 netmask = 3;
211    }
212
213    message ReserveRange {}
214    message SetIrq {}
215    message SetIrqRouting {}
216    message GetState {
217        // The in memory representation of a state, depending on what StateSet was
218        // requested in GetState.
219        bytes state = 1;
220    }
221    message SetState {}
222    message SetIdentityMapAddr {}
223    message PauseVcpus {}
224    // This message should also receive a socket fd per VCPU along with the data from reading this
225    // socket. The VcpuRequest/VcpuResponse protocol is run over each of the returned fds.
226    message GetVcpus {}
227    message Start {}
228    message MemoryDirtyLog {
229        bytes bitmap = 1;
230    }
231
232    // This is zero on success, and a negative integer on failure.
233    sint32 errno = 1;
234    // The field present here is always the same as the one present in the corresponding
235    // MainRequest.
236    oneof message {
237        Create create = 2;
238        Destroy destroy = 3;
239        NewConnection new_connection = 4;
240        GetShutdownEventfd get_shutdown_eventfd = 5;
241        CheckExtension check_extension = 6;
242        CpuidResponse get_supported_cpuid = 7;
243        CpuidResponse get_emulated_cpuid = 8;
244        MsrListResponse get_msr_index_list = 9;
245        GetNetConfig get_net_config = 10;
246        ReserveRange reserve_range = 11;
247        SetIrq set_irq = 12;
248        SetIrqRouting set_irq_routing = 13;
249        GetState get_state = 14;
250        SetState set_state = 15;
251        SetIdentityMapAddr set_identity_map_addr = 16;
252        PauseVcpus pause_vcpus = 17;
253        GetVcpus get_vcpus = 18;
254        Start start = 19;
255        MemoryDirtyLog dirty_log = 101;
256    }
257}
258
259// A request made for a specific VCPU. These requests are sent over the sockets returned from the
260// GetVcpu MainRequest.
261message VcpuRequest {
262    // This message will block until a non-empty response can be sent. The first response will
263    // always be an Init wait reason.
264    message Wait {
265    }
266
267    message Resume {
268        // The data is only necessary for non-write (read) I/O accesses. In all other cases, data is
269        // ignored.
270        bytes data = 1;
271    }
272
273    // Each type refers to certain piece of VCPU state (a set registers, or something else).
274    // The structure of the data corresponds to the kvm structure.
275    enum StateSet {
276        // struct kvm_regs
277        REGS = 0;
278        // struct kvm_sregs
279        SREGS = 1;
280        // struct kvm_fpu
281        FPU = 2;
282        // struct kvm_debugregs
283        DEBUGREGS = 3;
284        // struct kvm_lapic_state
285        LAPIC = 4;
286        // struct kvm_mp_state
287        MP = 5;
288        // struct kvm_xcrs
289        XCREGS = 6;
290        // struct kvm_vcpu_events
291        EVENTS = 7;
292    }
293
294    message GetState {
295        StateSet set = 1;
296    }
297
298    message SetState {
299        StateSet set = 1;
300        // The in memory representation of a struct kvm_regs, struct kvm_sregs,
301        // struct kvm_fpu, struct kvm_debugregs, struct kvm_lapic_state,
302        // struct kvm_mp_state, struct kvm_xcrs or struct kvm_vcpu_events
303        // depending on the value of the StateSet.
304        bytes state = 2;
305    }
306
307    message GetMsrs {
308        // The entry data will be returned in the same order as this in the
309        // VcpuResponse::GetMsrs::entry_data array.
310        repeated uint32 entry_indices = 1;
311    }
312
313    message MsrEntry {
314        uint32 index = 1;
315        uint64 data = 2;
316    }
317
318    message SetMsrs {
319        repeated MsrEntry entries = 1;
320    }
321
322    message SetCpuid {
323        repeated CpuidEntry entries = 1;
324    }
325
326    message Shutdown {
327    }
328
329    // The type of the message is determined by which of these oneof fields is present in the
330    // protobuf.
331    oneof message {
332        Wait wait = 1;
333        Resume resume = 2;
334        GetState get_state = 3;
335        SetState set_state = 4;
336        GetMsrs get_msrs = 5;
337        SetMsrs set_msrs = 6;
338        SetCpuid set_cpuid = 7;
339        Shutdown shutdown = 8;
340    }
341}
342
343
344message VcpuResponse  {
345    // Depending on the reason a VCPU has exited, the Wait request will unblock and return a field
346    // in the oneof exit. This is called the "wait reason."
347    message Wait {
348        // This request will always be the first wait reason returend by the first wait request.
349        message Init {
350        }
351
352        // This type of wait reason is only generated if the access occurred on this VCPU on an
353        // address previously reserved by a ReserveRange main request.
354        message Io {
355            AddressSpace space = 1;
356            uint64 address = 2;
357            bool is_write = 3;
358            bytes data = 4;
359        }
360
361        // This type of wait reason is only generated after a PuaseVcpus request on this VCPU.
362        message User {
363            uint64 user = 1;
364        }
365
366        oneof exit {
367            Init init = 1;
368            Io io = 2;
369            User user = 3;
370        }
371    }
372
373    message Resume {}
374
375    message GetState {
376        // The in memory representation of a struct kvm_regs, struct kvm_sregs,
377        // struct kvm_fpu, struct kvm_debugregs, struct kvm_lapic_state,
378        // struct kvm_mp_state, struct kvm_xcrs or struct kvm_vcpu_events
379        // depending on the value of the StateSet.
380        bytes state = 1;
381    }
382
383    message SetState {
384    }
385
386    message GetMsrs {
387        // The order of the entry_data values is the same order as the array of indices given in the
388        // corresponding request.
389        repeated uint64 entry_data = 1;
390    }
391
392    message SetMsrs {}
393
394    message SetCpuid {}
395
396    // This is zero on success, and a negative integer on failure.
397    sint32 errno = 1;
398    // The field present here is always the same as the one present in the corresponding
399    // VcpuRequest.
400    oneof message {
401        Wait wait = 2;
402        Resume resume = 3;
403        GetState get_state = 4;
404        SetState set_state = 5;
405        GetMsrs get_msrs = 6;
406        SetMsrs set_msrs = 7;
407        SetCpuid set_cpuid = 8;
408    }
409}
410