summary refs log tree commit diff
path: root/protos/src/plugin.proto
blob: 332ed5d8f800779f7ae8fe19e6f0ebfd3d744e9d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
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;
        // struct kvm_clock_data
        CLOCK = 4;
    }

    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;
    }

    message Shutdown {
    }

    // 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;
        Shutdown shutdown = 8;
    }
}


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 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 was 3 but no longer gets a reply.
        GetState get_state = 4;
        SetState set_state = 5;
        GetMsrs get_msrs = 6;
        SetMsrs set_msrs = 7;
        SetCpuid set_cpuid = 8;
    }
}