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