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