• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #![allow(non_camel_case_types)]
6 
7 //! This module implements the dynamically loaded client library API used by a crosvm plugin,
8 //! defined in `crosvm.h`. It implements the client half of the plugin protocol, which is defined in
9 //! the `protos::plugin` module.
10 //!
11 //! To implement the `crosvm.h` C API, each function and struct definition is repeated here, with
12 //! concrete definitions for each struct. Most functions are thin shims to the underlying object
13 //! oriented Rust implementation method. Most methods require a request over the crosvm connection,
14 //! which is done by creating a `MainRequest` or `VcpuRequest` protobuf and sending it over the
15 //! connection's socket. Then, that socket is read for a `MainResponse` or `VcpuResponse`, which is
16 //! translated to the appropriate return type for the C API.
17 
18 use std::env;
19 use std::fs::File;
20 use std::io::{Read, Write};
21 use std::mem::{size_of, swap};
22 use std::os::raw::{c_int, c_void};
23 use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
24 use std::os::unix::net::UnixDatagram;
25 use std::ptr::{self, null_mut};
26 use std::result;
27 use std::slice;
28 use std::slice::{from_raw_parts, from_raw_parts_mut};
29 use std::sync::atomic::{AtomicUsize, Ordering};
30 use std::sync::Arc;
31 use std::time::Instant;
32 
33 use libc::{E2BIG, EINVAL, ENOENT, ENOTCONN, EPROTO};
34 
35 use protobuf::{parse_from_bytes, Message, ProtobufEnum, RepeatedField};
36 
37 use sys_util::ScmSocket;
38 
39 use kvm::dirty_log_bitmap_size;
40 
41 use kvm_sys::{
42     kvm_clock_data, kvm_cpuid_entry2, kvm_debugregs, kvm_fpu, kvm_ioapic_state, kvm_lapic_state,
43     kvm_mp_state, kvm_msr_entry, kvm_pic_state, kvm_pit_state2, kvm_regs, kvm_sregs,
44     kvm_vcpu_events, kvm_xcrs,
45 };
46 
47 use protos::plugin::*;
48 
49 // Needs to be large enough to receive all the VCPU sockets.
50 const MAX_DATAGRAM_FD: usize = 32;
51 // Needs to be large enough for a sizable dirty log.
52 const MAX_DATAGRAM_SIZE: usize = 0x40000;
53 
54 const CROSVM_IRQ_ROUTE_IRQCHIP: u32 = 0;
55 const CROSVM_IRQ_ROUTE_MSI: u32 = 1;
56 
57 const CROSVM_VCPU_EVENT_KIND_INIT: u32 = 0;
58 const CROSVM_VCPU_EVENT_KIND_IO_ACCESS: u32 = 1;
59 const CROSVM_VCPU_EVENT_KIND_PAUSED: u32 = 2;
60 
61 #[repr(C)]
62 #[derive(Copy, Clone)]
63 pub struct crosvm_net_config {
64     tap_fd: c_int,
65     host_ipv4_address: u32,
66     netmask: u32,
67     host_mac_address: [u8; 6],
68     _reserved: [u8; 2],
69 }
70 
71 #[repr(C)]
72 #[derive(Copy, Clone)]
73 pub struct anon_irqchip {
74     irqchip: u32,
75     pin: u32,
76 }
77 
78 #[repr(C)]
79 #[derive(Copy, Clone)]
80 pub struct anon_msi {
81     address: u64,
82     data: u32,
83 }
84 
85 #[repr(C)]
86 pub union anon_route {
87     irqchip: anon_irqchip,
88     msi: anon_msi,
89     reserved: [u8; 16],
90 }
91 
92 #[repr(C)]
93 pub struct crosvm_irq_route {
94     irq_id: u32,
95     kind: u32,
96     route: anon_route,
97 }
98 
proto_error_to_int(e: protobuf::ProtobufError) -> c_int99 fn proto_error_to_int(e: protobuf::ProtobufError) -> c_int {
100     match e {
101         protobuf::ProtobufError::IoError(e) => e.raw_os_error().unwrap_or(EINVAL),
102         _ => EINVAL,
103     }
104 }
105 
fd_cast<F: FromRawFd>(f: File) -> F106 fn fd_cast<F: FromRawFd>(f: File) -> F {
107     // Safe because we are transferring unique ownership.
108     unsafe { F::from_raw_fd(f.into_raw_fd()) }
109 }
110 
111 #[derive(Default)]
112 struct IdAllocator(AtomicUsize);
113 
114 impl IdAllocator {
alloc(&self) -> u32115     fn alloc(&self) -> u32 {
116         self.0.fetch_add(1, Ordering::Relaxed) as u32
117     }
118 
free(&self, id: u32)119     fn free(&self, id: u32) {
120         self.0
121             .compare_and_swap(id as usize + 1, id as usize, Ordering::Relaxed);
122     }
123 }
124 
125 #[repr(u8)]
126 #[derive(Debug, Clone, Copy)]
127 enum Stat {
128     IoEventFd,
129     MemoryGetDirtyLog,
130     IrqEventGetFd,
131     IrqEventGetResampleFd,
132     Connect,
133     DestroyConnection,
134     GetShutdownEventFd,
135     CheckExtentsion,
136     GetSupportedCpuid,
137     GetEmulatedCpuid,
138     GetMsrIndexList,
139     NetGetConfig,
140     ReserveRange,
141     SetIrq,
142     SetIrqRouting,
143     GetPicState,
144     SetPicState,
145     GetIoapicState,
146     SetIoapicState,
147     GetPitState,
148     SetPitState,
149     GetClock,
150     SetClock,
151     SetIdentityMapAddr,
152     PauseVcpus,
153     Start,
154     GetVcpu,
155     VcpuWait,
156     VcpuResume,
157     VcpuGetRegs,
158     VcpuSetRegs,
159     VcpuGetSregs,
160     VcpuSetSregs,
161     GetFpu,
162     SetFpu,
163     GetDebugRegs,
164     SetDebugRegs,
165     GetXCRegs,
166     SetXCRegs,
167     VcpuGetMsrs,
168     VcpuSetMsrs,
169     VcpuSetCpuid,
170     VcpuGetLapicState,
171     VcpuSetLapicState,
172     VcpuGetMpState,
173     VcpuSetMpState,
174     VcpuGetVcpuEvents,
175     VcpuSetVcpuEvents,
176     NewConnection,
177 
178     Count,
179 }
180 
181 #[derive(Clone, Copy)]
182 struct StatEntry {
183     count: u64,
184     total: u64,
185     max: u64,
186 }
187 
188 struct StatUpdater {
189     idx: usize,
190     start: Instant,
191 }
192 
193 struct GlobalStats {
194     entries: [StatEntry; Stat::Count as usize],
195 }
196 
197 static mut STATS: GlobalStats = GlobalStats {
198     entries: [StatEntry {
199         count: 0,
200         total: 0,
201         max: 0,
202     }; Stat::Count as usize],
203 };
204 
205 impl GlobalStats {
206     // Record latency from this call until the end of block/function
207     // Example:
208     // pub fn foo() {
209     //     let _u = STATS.record(Stat::Foo);
210     //     // ... some operation ...
211     // }
212     // The added STATS.record will record latency of "some operation" and will
213     // update max and average latencies for it under Stats::Foo. Subsequent
214     // call to STATS.print() will print out max and average latencies for all
215     // operations that were performed.
record(&mut self, idx: Stat) -> StatUpdater216     fn record(&mut self, idx: Stat) -> StatUpdater {
217         StatUpdater {
218             idx: idx as usize,
219             start: Instant::now(),
220         }
221     }
222 
print(&self)223     fn print(&self) {
224         for idx in 0..Stat::Count as usize {
225             let e = &self.entries[idx as usize];
226             let stat = unsafe { std::mem::transmute::<u8, Stat>(idx as u8) };
227             if e.count > 0 {
228                 println!(
229                     "Stat::{:?}: avg {}ns max {}ns",
230                     stat,
231                     e.total / e.count,
232                     e.max
233                 );
234             }
235         }
236     }
237 
update(&mut self, idx: usize, elapsed_nanos: u64)238     fn update(&mut self, idx: usize, elapsed_nanos: u64) {
239         let e = &mut self.entries[idx as usize];
240         e.total += elapsed_nanos;
241         if e.max < elapsed_nanos {
242             e.max = elapsed_nanos;
243         }
244         e.count += 1;
245     }
246 }
247 
248 impl Drop for StatUpdater {
drop(&mut self)249     fn drop(&mut self) {
250         let elapsed = self.start.elapsed();
251         let elapsed_nanos = elapsed.as_secs() * 1000000000 + elapsed.subsec_nanos() as u64;
252         // Unsafe due to racy access - OK for stats
253         unsafe {
254             STATS.update(self.idx, elapsed_nanos);
255         }
256     }
257 }
258 
259 pub struct crosvm {
260     id_allocator: Arc<IdAllocator>,
261     socket: UnixDatagram,
262     request_buffer: Vec<u8>,
263     response_buffer: Vec<u8>,
264     vcpus: Arc<Vec<crosvm_vcpu>>,
265 }
266 
267 impl crosvm {
from_connection(socket: UnixDatagram) -> result::Result<crosvm, c_int>268     fn from_connection(socket: UnixDatagram) -> result::Result<crosvm, c_int> {
269         let mut crosvm = crosvm {
270             id_allocator: Default::default(),
271             socket,
272             request_buffer: Vec::new(),
273             response_buffer: vec![0; MAX_DATAGRAM_SIZE],
274             vcpus: Default::default(),
275         };
276         crosvm.load_all_vcpus()?;
277         Ok(crosvm)
278     }
279 
new( id_allocator: Arc<IdAllocator>, socket: UnixDatagram, vcpus: Arc<Vec<crosvm_vcpu>>, ) -> crosvm280     fn new(
281         id_allocator: Arc<IdAllocator>,
282         socket: UnixDatagram,
283         vcpus: Arc<Vec<crosvm_vcpu>>,
284     ) -> crosvm {
285         crosvm {
286             id_allocator,
287             socket,
288             request_buffer: Vec::new(),
289             response_buffer: vec![0; MAX_DATAGRAM_SIZE],
290             vcpus,
291         }
292     }
293 
get_id_allocator(&self) -> &IdAllocator294     fn get_id_allocator(&self) -> &IdAllocator {
295         &*self.id_allocator
296     }
297 
main_transaction( &mut self, request: &MainRequest, fds: &[RawFd], ) -> result::Result<(MainResponse, Vec<File>), c_int>298     fn main_transaction(
299         &mut self,
300         request: &MainRequest,
301         fds: &[RawFd],
302     ) -> result::Result<(MainResponse, Vec<File>), c_int> {
303         self.request_buffer.clear();
304         request
305             .write_to_vec(&mut self.request_buffer)
306             .map_err(proto_error_to_int)?;
307         self.socket
308             .send_with_fds(self.request_buffer.as_slice(), fds)
309             .map_err(|e| -e.errno())?;
310 
311         let mut datagram_fds = [0; MAX_DATAGRAM_FD];
312         let (msg_size, fd_count) = self
313             .socket
314             .recv_with_fds(&mut self.response_buffer, &mut datagram_fds)
315             .map_err(|e| -e.errno())?;
316         // Safe because the first fd_count fds from recv_with_fds are owned by us and valid.
317         let datagram_files = datagram_fds[..fd_count]
318             .iter()
319             .map(|&fd| unsafe { File::from_raw_fd(fd) })
320             .collect();
321 
322         let response: MainResponse =
323             parse_from_bytes(&self.response_buffer[..msg_size]).map_err(proto_error_to_int)?;
324         if response.errno != 0 {
325             return Err(response.errno);
326         }
327         Ok((response, datagram_files))
328     }
329 
try_clone(&mut self) -> result::Result<crosvm, c_int>330     fn try_clone(&mut self) -> result::Result<crosvm, c_int> {
331         let mut r = MainRequest::new();
332         r.mut_new_connection();
333         let mut files = self.main_transaction(&r, &[])?.1;
334         match files.pop() {
335             Some(new_socket) => Ok(crosvm::new(
336                 self.id_allocator.clone(),
337                 fd_cast(new_socket),
338                 self.vcpus.clone(),
339             )),
340             None => Err(EPROTO),
341         }
342     }
343 
destroy(&mut self, id: u32) -> result::Result<(), c_int>344     fn destroy(&mut self, id: u32) -> result::Result<(), c_int> {
345         let mut r = MainRequest::new();
346         r.mut_destroy().id = id;
347         self.main_transaction(&r, &[])?;
348         self.get_id_allocator().free(id);
349         // Unsafe due to racy access - OK for stats
350         if std::env::var("CROSVM_STATS").is_ok() {
351             unsafe {
352                 STATS.print();
353             }
354         }
355         Ok(())
356     }
357 
358     // Only call this at `from_connection` function.
load_all_vcpus(&mut self) -> result::Result<(), c_int>359     fn load_all_vcpus(&mut self) -> result::Result<(), c_int> {
360         let mut r = MainRequest::new();
361         r.mut_get_vcpus();
362         let (_, mut files) = self.main_transaction(&r, &[])?;
363         if files.is_empty() || files.len() % 2 != 0 {
364             return Err(EPROTO);
365         }
366 
367         let mut vcpus = Vec::with_capacity(files.len() / 2);
368         while files.len() > 1 {
369             let write_pipe = files.remove(0);
370             let read_pipe = files.remove(0);
371             vcpus.push(crosvm_vcpu::new(fd_cast(read_pipe), fd_cast(write_pipe)));
372         }
373         // Only called once by the `from_connection` constructor, which makes a new unique
374         // `self.vcpus`.
375         let self_vcpus = Arc::get_mut(&mut self.vcpus).unwrap();
376         *self_vcpus = vcpus;
377         Ok(())
378     }
379 
get_shutdown_eventfd(&mut self) -> result::Result<File, c_int>380     fn get_shutdown_eventfd(&mut self) -> result::Result<File, c_int> {
381         let mut r = MainRequest::new();
382         r.mut_get_shutdown_eventfd();
383         let (_, mut files) = self.main_transaction(&r, &[])?;
384         match files.pop() {
385             Some(f) => Ok(f),
386             None => Err(EPROTO),
387         }
388     }
389 
check_extension(&mut self, extension: u32) -> result::Result<bool, c_int>390     fn check_extension(&mut self, extension: u32) -> result::Result<bool, c_int> {
391         let mut r = MainRequest::new();
392         r.mut_check_extension().extension = extension;
393         let (response, _) = self.main_transaction(&r, &[])?;
394         if !response.has_check_extension() {
395             return Err(EPROTO);
396         }
397         Ok(response.get_check_extension().has_extension)
398     }
399 
get_supported_cpuid( &mut self, cpuid_entries: &mut [kvm_cpuid_entry2], cpuid_count: &mut usize, ) -> result::Result<(), c_int>400     fn get_supported_cpuid(
401         &mut self,
402         cpuid_entries: &mut [kvm_cpuid_entry2],
403         cpuid_count: &mut usize,
404     ) -> result::Result<(), c_int> {
405         *cpuid_count = 0;
406 
407         let mut r = MainRequest::new();
408         r.mut_get_supported_cpuid();
409 
410         let (response, _) = self.main_transaction(&r, &[])?;
411         if !response.has_get_supported_cpuid() {
412             return Err(EPROTO);
413         }
414 
415         let supported_cpuids: &MainResponse_CpuidResponse = response.get_get_supported_cpuid();
416 
417         *cpuid_count = supported_cpuids.get_entries().len();
418         if *cpuid_count > cpuid_entries.len() {
419             return Err(E2BIG);
420         }
421 
422         for (proto_entry, kvm_entry) in supported_cpuids
423             .get_entries()
424             .iter()
425             .zip(cpuid_entries.iter_mut())
426         {
427             *kvm_entry = cpuid_proto_to_kvm(proto_entry);
428         }
429 
430         Ok(())
431     }
432 
get_emulated_cpuid( &mut self, cpuid_entries: &mut [kvm_cpuid_entry2], cpuid_count: &mut usize, ) -> result::Result<(), c_int>433     fn get_emulated_cpuid(
434         &mut self,
435         cpuid_entries: &mut [kvm_cpuid_entry2],
436         cpuid_count: &mut usize,
437     ) -> result::Result<(), c_int> {
438         *cpuid_count = 0;
439 
440         let mut r = MainRequest::new();
441         r.mut_get_emulated_cpuid();
442 
443         let (response, _) = self.main_transaction(&r, &[])?;
444         if !response.has_get_emulated_cpuid() {
445             return Err(EPROTO);
446         }
447 
448         let emulated_cpuids: &MainResponse_CpuidResponse = response.get_get_emulated_cpuid();
449 
450         *cpuid_count = emulated_cpuids.get_entries().len();
451         if *cpuid_count > cpuid_entries.len() {
452             return Err(E2BIG);
453         }
454 
455         for (proto_entry, kvm_entry) in emulated_cpuids
456             .get_entries()
457             .iter()
458             .zip(cpuid_entries.iter_mut())
459         {
460             *kvm_entry = cpuid_proto_to_kvm(proto_entry);
461         }
462 
463         Ok(())
464     }
465 
get_msr_index_list( &mut self, msr_indices: &mut [u32], msr_count: &mut usize, ) -> result::Result<(), c_int>466     fn get_msr_index_list(
467         &mut self,
468         msr_indices: &mut [u32],
469         msr_count: &mut usize,
470     ) -> result::Result<(), c_int> {
471         *msr_count = 0;
472 
473         let mut r = MainRequest::new();
474         r.mut_get_msr_index_list();
475 
476         let (response, _) = self.main_transaction(&r, &[])?;
477         if !response.has_get_msr_index_list() {
478             return Err(EPROTO);
479         }
480 
481         let msr_list: &MainResponse_MsrListResponse = response.get_get_msr_index_list();
482 
483         *msr_count = msr_list.get_indices().len();
484         if *msr_count > msr_indices.len() {
485             return Err(E2BIG);
486         }
487 
488         for (proto_entry, kvm_entry) in msr_list.get_indices().iter().zip(msr_indices.iter_mut()) {
489             *kvm_entry = *proto_entry;
490         }
491 
492         Ok(())
493     }
494 
reserve_range(&mut self, space: u32, start: u64, length: u64) -> result::Result<(), c_int>495     fn reserve_range(&mut self, space: u32, start: u64, length: u64) -> result::Result<(), c_int> {
496         let mut r = MainRequest::new();
497         let reserve: &mut MainRequest_ReserveRange = r.mut_reserve_range();
498         reserve.space = AddressSpace::from_i32(space as i32).ok_or(EINVAL)?;
499         reserve.start = start;
500         reserve.length = length;
501 
502         self.main_transaction(&r, &[])?;
503         Ok(())
504     }
505 
set_irq(&mut self, irq_id: u32, active: bool) -> result::Result<(), c_int>506     fn set_irq(&mut self, irq_id: u32, active: bool) -> result::Result<(), c_int> {
507         let mut r = MainRequest::new();
508         let set_irq: &mut MainRequest_SetIrq = r.mut_set_irq();
509         set_irq.irq_id = irq_id;
510         set_irq.active = active;
511 
512         self.main_transaction(&r, &[])?;
513         Ok(())
514     }
515 
set_irq_routing(&mut self, routing: &[crosvm_irq_route]) -> result::Result<(), c_int>516     fn set_irq_routing(&mut self, routing: &[crosvm_irq_route]) -> result::Result<(), c_int> {
517         let mut r = MainRequest::new();
518         let set_irq_routing: &mut RepeatedField<MainRequest_SetIrqRouting_Route> =
519             r.mut_set_irq_routing().mut_routes();
520         for route in routing {
521             let mut entry = MainRequest_SetIrqRouting_Route::new();
522             entry.irq_id = route.irq_id;
523             match route.kind {
524                 CROSVM_IRQ_ROUTE_IRQCHIP => {
525                     let irqchip: &mut MainRequest_SetIrqRouting_Route_Irqchip;
526                     irqchip = entry.mut_irqchip();
527                     // Safe because route.kind indicates which union field is valid.
528                     irqchip.irqchip = unsafe { route.route.irqchip }.irqchip;
529                     irqchip.pin = unsafe { route.route.irqchip }.pin;
530                 }
531                 CROSVM_IRQ_ROUTE_MSI => {
532                     let msi: &mut MainRequest_SetIrqRouting_Route_Msi = entry.mut_msi();
533                     // Safe because route.kind indicates which union field is valid.
534                     msi.address = unsafe { route.route.msi }.address;
535                     msi.data = unsafe { route.route.msi }.data;
536                 }
537                 _ => return Err(EINVAL),
538             }
539             set_irq_routing.push(entry);
540         }
541 
542         self.main_transaction(&r, &[])?;
543         Ok(())
544     }
545 
get_state( &mut self, state_set: MainRequest_StateSet, out: &mut [u8], ) -> result::Result<(), c_int>546     fn get_state(
547         &mut self,
548         state_set: MainRequest_StateSet,
549         out: &mut [u8],
550     ) -> result::Result<(), c_int> {
551         let mut r = MainRequest::new();
552         r.mut_get_state().set = state_set;
553         let (response, _) = self.main_transaction(&r, &[])?;
554         if !response.has_get_state() {
555             return Err(EPROTO);
556         }
557         let get_state: &MainResponse_GetState = response.get_get_state();
558         if get_state.state.len() != out.len() {
559             return Err(EPROTO);
560         }
561         out.copy_from_slice(&get_state.state);
562         Ok(())
563     }
564 
set_state( &mut self, state_set: MainRequest_StateSet, new_state: &[u8], ) -> result::Result<(), c_int>565     fn set_state(
566         &mut self,
567         state_set: MainRequest_StateSet,
568         new_state: &[u8],
569     ) -> result::Result<(), c_int> {
570         let mut r = MainRequest::new();
571         let set_state: &mut MainRequest_SetState = r.mut_set_state();
572         set_state.set = state_set;
573         set_state.state = new_state.to_vec();
574 
575         self.main_transaction(&r, &[])?;
576         Ok(())
577     }
578 
set_identity_map_addr(&mut self, addr: u32) -> result::Result<(), c_int>579     fn set_identity_map_addr(&mut self, addr: u32) -> result::Result<(), c_int> {
580         let mut r = MainRequest::new();
581         r.mut_set_identity_map_addr().address = addr;
582 
583         self.main_transaction(&r, &[])?;
584         Ok(())
585     }
586 
pause_vcpus(&mut self, cpu_mask: u64, user: *mut c_void) -> result::Result<(), c_int>587     fn pause_vcpus(&mut self, cpu_mask: u64, user: *mut c_void) -> result::Result<(), c_int> {
588         let mut r = MainRequest::new();
589         let pause_vcpus: &mut MainRequest_PauseVcpus = r.mut_pause_vcpus();
590         pause_vcpus.cpu_mask = cpu_mask;
591         pause_vcpus.user = user as u64;
592         self.main_transaction(&r, &[])?;
593         Ok(())
594     }
595 
start(&mut self) -> result::Result<(), c_int>596     fn start(&mut self) -> result::Result<(), c_int> {
597         let mut r = MainRequest::new();
598         r.mut_start();
599         self.main_transaction(&r, &[])?;
600         Ok(())
601     }
602 
get_vcpu(&mut self, cpu_id: u32) -> Result<*mut crosvm_vcpu, c_int>603     fn get_vcpu(&mut self, cpu_id: u32) -> Result<*mut crosvm_vcpu, c_int> {
604         if let Some(vcpu) = self.vcpus.get(cpu_id as usize) {
605             Ok(vcpu as *const crosvm_vcpu as *mut crosvm_vcpu)
606         } else {
607             Err(ENOENT)
608         }
609     }
610 
get_net_config(&mut self) -> result::Result<crosvm_net_config, c_int>611     fn get_net_config(&mut self) -> result::Result<crosvm_net_config, c_int> {
612         let mut r = MainRequest::new();
613         r.mut_get_net_config();
614 
615         let (response, mut files) = self.main_transaction(&r, &[])?;
616         if !response.has_get_net_config() {
617             return Err(EPROTO);
618         }
619         let config = response.get_get_net_config();
620 
621         match files.pop() {
622             Some(f) => {
623                 let mut net_config = crosvm_net_config {
624                     tap_fd: f.into_raw_fd(),
625                     host_ipv4_address: config.host_ipv4_address,
626                     netmask: config.netmask,
627                     host_mac_address: [0; 6],
628                     _reserved: [0; 2],
629                 };
630 
631                 let mac_addr = config.get_host_mac_address();
632                 if mac_addr.len() != net_config.host_mac_address.len() {
633                     return Err(EPROTO);
634                 }
635                 net_config.host_mac_address.copy_from_slice(mac_addr);
636 
637                 Ok(net_config)
638             }
639             None => Err(EPROTO),
640         }
641     }
642 }
643 
644 /// This helper macro implements the C API's constructor/destructor for a given type. Because they
645 /// all follow the same pattern and include lots of boilerplate unsafe code, it makes sense to write
646 /// it once with this helper macro.
647 macro_rules! impl_ctor_dtor {
648     (
649         $t:ident,
650         $ctor:ident ( $( $x:ident: $y:ty ),* ),
651         $dtor:ident,
652     ) => {
653         #[allow(unused_unsafe)]
654         #[no_mangle]
655         pub unsafe extern fn $ctor(self_: *mut crosvm, $($x: $y,)* obj_ptr: *mut *mut $t) -> c_int {
656             let self_ = &mut (*self_);
657             match $t::create(self_, $($x,)*) {
658                 Ok(obj) => {
659                     *obj_ptr = Box::into_raw(Box::new(obj));
660                     0
661                 }
662                 Err(e) => -e,
663             }
664         }
665         #[no_mangle]
666         pub unsafe extern fn $dtor(self_: *mut crosvm, obj_ptr: *mut *mut $t) -> c_int {
667             let self_ = &mut (*self_);
668             let obj = Box::from_raw(*obj_ptr);
669             match self_.destroy(obj.id) {
670                 Ok(_) => {
671                     *obj_ptr = null_mut();
672                     0
673                 }
674                 Err(e) =>  {
675                     Box::into_raw(obj);
676                     -e
677                 }
678             }
679         }
680     }
681 }
682 
683 pub struct crosvm_io_event {
684     id: u32,
685     evt: File,
686 }
687 
688 impl crosvm_io_event {
689     // Clippy: we use ptr::read_unaligned to read from pointers that may be
690     // underaligned. Dereferencing such a pointer is always undefined behavior
691     // in Rust.
692     //
693     // Lint can be unsuppressed once Clippy recognizes this pattern as correct.
694     // https://github.com/rust-lang/rust-clippy/issues/2881
695     #[allow(clippy::cast_ptr_alignment)]
create( crosvm: &mut crosvm, space: u32, addr: u64, length: u32, datamatch: *const u8, ) -> result::Result<crosvm_io_event, c_int>696     unsafe fn create(
697         crosvm: &mut crosvm,
698         space: u32,
699         addr: u64,
700         length: u32,
701         datamatch: *const u8,
702     ) -> result::Result<crosvm_io_event, c_int> {
703         let datamatch = match length {
704             0 => 0,
705             1 => ptr::read_unaligned(datamatch as *const u8) as u64,
706             2 => ptr::read_unaligned(datamatch as *const u16) as u64,
707             4 => ptr::read_unaligned(datamatch as *const u32) as u64,
708             8 => ptr::read_unaligned(datamatch as *const u64),
709             _ => return Err(EINVAL),
710         };
711         Self::safe_create(crosvm, space, addr, length, datamatch)
712     }
713 
safe_create( crosvm: &mut crosvm, space: u32, addr: u64, length: u32, datamatch: u64, ) -> result::Result<crosvm_io_event, c_int>714     fn safe_create(
715         crosvm: &mut crosvm,
716         space: u32,
717         addr: u64,
718         length: u32,
719         datamatch: u64,
720     ) -> result::Result<crosvm_io_event, c_int> {
721         let id = crosvm.get_id_allocator().alloc();
722 
723         let mut r = MainRequest::new();
724         let create: &mut MainRequest_Create = r.mut_create();
725         create.id = id;
726         let io_event: &mut MainRequest_Create_IoEvent = create.mut_io_event();
727         io_event.space = AddressSpace::from_i32(space as i32).ok_or(EINVAL)?;
728         io_event.address = addr;
729         io_event.length = length;
730         io_event.datamatch = datamatch;
731 
732         let ret = match crosvm.main_transaction(&r, &[]) {
733             Ok((_, mut files)) => match files.pop() {
734                 Some(evt) => return Ok(crosvm_io_event { id, evt }),
735                 None => EPROTO,
736             },
737             Err(e) => e,
738         };
739         crosvm.get_id_allocator().free(id);
740         Err(ret)
741     }
742 }
743 
744 impl_ctor_dtor!(
745     crosvm_io_event,
746     crosvm_create_io_event(space: u32, addr: u64, len: u32, datamatch: *const u8),
747     crosvm_destroy_io_event,
748 );
749 
750 #[no_mangle]
crosvm_io_event_fd(this: *mut crosvm_io_event) -> c_int751 pub unsafe extern "C" fn crosvm_io_event_fd(this: *mut crosvm_io_event) -> c_int {
752     let _u = STATS.record(Stat::IoEventFd);
753     (*this).evt.as_raw_fd()
754 }
755 
756 pub struct crosvm_memory {
757     id: u32,
758     length: u64,
759 }
760 
761 impl crosvm_memory {
create( crosvm: &mut crosvm, fd: c_int, offset: u64, length: u64, start: u64, read_only: bool, dirty_log: bool, ) -> result::Result<crosvm_memory, c_int>762     fn create(
763         crosvm: &mut crosvm,
764         fd: c_int,
765         offset: u64,
766         length: u64,
767         start: u64,
768         read_only: bool,
769         dirty_log: bool,
770     ) -> result::Result<crosvm_memory, c_int> {
771         const PAGE_MASK: u64 = 0x0fff;
772         if offset & PAGE_MASK != 0 || length & PAGE_MASK != 0 {
773             return Err(EINVAL);
774         }
775         let id = crosvm.get_id_allocator().alloc();
776 
777         let mut r = MainRequest::new();
778         let create: &mut MainRequest_Create = r.mut_create();
779         create.id = id;
780         let memory: &mut MainRequest_Create_Memory = create.mut_memory();
781         memory.offset = offset;
782         memory.start = start;
783         memory.length = length;
784         memory.read_only = read_only;
785         memory.dirty_log = dirty_log;
786 
787         let ret = match crosvm.main_transaction(&r, &[fd]) {
788             Ok(_) => return Ok(crosvm_memory { id, length }),
789             Err(e) => e,
790         };
791         crosvm.get_id_allocator().free(id);
792         Err(ret)
793     }
794 
get_dirty_log(&mut self, crosvm: &mut crosvm) -> result::Result<Vec<u8>, c_int>795     fn get_dirty_log(&mut self, crosvm: &mut crosvm) -> result::Result<Vec<u8>, c_int> {
796         let mut r = MainRequest::new();
797         r.mut_dirty_log().id = self.id;
798         let (mut response, _) = crosvm.main_transaction(&r, &[])?;
799         if !response.has_dirty_log() {
800             return Err(EPROTO);
801         }
802         Ok(response.take_dirty_log().bitmap)
803     }
804 }
805 
806 impl_ctor_dtor!(
807     crosvm_memory,
808     crosvm_create_memory(
809         fd: c_int,
810         offset: u64,
811         length: u64,
812         start: u64,
813         read_only: bool,
814         dirty_log: bool
815     ),
816     crosvm_destroy_memory,
817 );
818 
819 #[no_mangle]
crosvm_memory_get_dirty_log( crosvm: *mut crosvm, this: *mut crosvm_memory, log: *mut u8, ) -> c_int820 pub unsafe extern "C" fn crosvm_memory_get_dirty_log(
821     crosvm: *mut crosvm,
822     this: *mut crosvm_memory,
823     log: *mut u8,
824 ) -> c_int {
825     let _u = STATS.record(Stat::MemoryGetDirtyLog);
826     let crosvm = &mut *crosvm;
827     let this = &mut *this;
828     let log_slice = slice::from_raw_parts_mut(log, dirty_log_bitmap_size(this.length as usize));
829     match this.get_dirty_log(crosvm) {
830         Ok(bitmap) => {
831             if bitmap.len() == log_slice.len() {
832                 log_slice.copy_from_slice(&bitmap);
833                 0
834             } else {
835                 -EPROTO
836             }
837         }
838         Err(e) => -e,
839     }
840 }
841 
842 pub struct crosvm_irq_event {
843     id: u32,
844     trigger_evt: File,
845     resample_evt: File,
846 }
847 
848 impl crosvm_irq_event {
create(crosvm: &mut crosvm, irq_id: u32) -> result::Result<crosvm_irq_event, c_int>849     fn create(crosvm: &mut crosvm, irq_id: u32) -> result::Result<crosvm_irq_event, c_int> {
850         let id = crosvm.get_id_allocator().alloc();
851 
852         let mut r = MainRequest::new();
853         let create: &mut MainRequest_Create = r.mut_create();
854         create.id = id;
855         let irq_event: &mut MainRequest_Create_IrqEvent = create.mut_irq_event();
856         irq_event.irq_id = irq_id;
857         irq_event.resample = true;
858 
859         let ret = match crosvm.main_transaction(&r, &[]) {
860             Ok((_, mut files)) => {
861                 if files.len() >= 2 {
862                     let resample_evt = files.pop().unwrap();
863                     let trigger_evt = files.pop().unwrap();
864                     return Ok(crosvm_irq_event {
865                         id,
866                         trigger_evt,
867                         resample_evt,
868                     });
869                 }
870                 EPROTO
871             }
872             Err(e) => e,
873         };
874         crosvm.get_id_allocator().free(id);
875         Err(ret)
876     }
877 }
878 
879 impl_ctor_dtor!(
880     crosvm_irq_event,
881     crosvm_create_irq_event(irq_id: u32),
882     crosvm_destroy_irq_event,
883 );
884 
885 #[no_mangle]
crosvm_irq_event_get_fd(this: *mut crosvm_irq_event) -> c_int886 pub unsafe extern "C" fn crosvm_irq_event_get_fd(this: *mut crosvm_irq_event) -> c_int {
887     let _u = STATS.record(Stat::IrqEventGetFd);
888     (*this).trigger_evt.as_raw_fd()
889 }
890 
891 #[no_mangle]
crosvm_irq_event_get_resample_fd(this: *mut crosvm_irq_event) -> c_int892 pub unsafe extern "C" fn crosvm_irq_event_get_resample_fd(this: *mut crosvm_irq_event) -> c_int {
893     let _u = STATS.record(Stat::IrqEventGetResampleFd);
894     (*this).resample_evt.as_raw_fd()
895 }
896 
897 #[allow(dead_code)]
898 #[derive(Copy, Clone)]
899 #[repr(C)]
900 struct anon_io_access {
901     address_space: u32,
902     __reserved0: [u8; 4],
903     address: u64,
904     data: *mut u8,
905     length: u32,
906     is_write: u8,
907     __reserved1: u8,
908 }
909 
910 #[repr(C)]
911 union anon_vcpu_event {
912     io_access: anon_io_access,
913     user: *mut c_void,
914     #[allow(dead_code)]
915     __reserved: [u8; 64],
916 }
917 
918 #[repr(C)]
919 pub struct crosvm_vcpu_event {
920     kind: u32,
921     __reserved: [u8; 4],
922     event: anon_vcpu_event,
923 }
924 
925 pub struct crosvm_vcpu {
926     read_pipe: File,
927     write_pipe: File,
928     send_init: bool,
929     request_buffer: Vec<u8>,
930     response_buffer: Vec<u8>,
931     resume_data: Vec<u8>,
932 }
933 
934 impl crosvm_vcpu {
new(read_pipe: File, write_pipe: File) -> crosvm_vcpu935     fn new(read_pipe: File, write_pipe: File) -> crosvm_vcpu {
936         crosvm_vcpu {
937             read_pipe,
938             write_pipe,
939             send_init: true,
940             request_buffer: Vec::new(),
941             response_buffer: vec![0; MAX_DATAGRAM_SIZE],
942             resume_data: Vec::new(),
943         }
944     }
vcpu_send(&mut self, request: &VcpuRequest) -> result::Result<(), c_int>945     fn vcpu_send(&mut self, request: &VcpuRequest) -> result::Result<(), c_int> {
946         self.request_buffer.clear();
947         request
948             .write_to_vec(&mut self.request_buffer)
949             .map_err(proto_error_to_int)?;
950         self.write_pipe
951             .write(self.request_buffer.as_slice())
952             .map_err(|e| -e.raw_os_error().unwrap_or(EINVAL))?;
953         Ok(())
954     }
955 
vcpu_recv(&mut self) -> result::Result<VcpuResponse, c_int>956     fn vcpu_recv(&mut self) -> result::Result<VcpuResponse, c_int> {
957         let msg_size = self
958             .read_pipe
959             .read(&mut self.response_buffer)
960             .map_err(|e| -e.raw_os_error().unwrap_or(EINVAL))?;
961 
962         let response: VcpuResponse =
963             parse_from_bytes(&self.response_buffer[..msg_size]).map_err(proto_error_to_int)?;
964         if response.errno != 0 {
965             return Err(response.errno);
966         }
967         Ok(response)
968     }
969 
vcpu_transaction(&mut self, request: &VcpuRequest) -> result::Result<VcpuResponse, c_int>970     fn vcpu_transaction(&mut self, request: &VcpuRequest) -> result::Result<VcpuResponse, c_int> {
971         self.vcpu_send(request)?;
972         let response: VcpuResponse = self.vcpu_recv()?;
973         Ok(response)
974     }
975 
wait(&mut self, event: &mut crosvm_vcpu_event) -> result::Result<(), c_int>976     fn wait(&mut self, event: &mut crosvm_vcpu_event) -> result::Result<(), c_int> {
977         if self.send_init {
978             self.send_init = false;
979             let mut r = VcpuRequest::new();
980             r.mut_wait();
981             self.vcpu_send(&r)?;
982         }
983         let mut response: VcpuResponse = self.vcpu_recv()?;
984         if !response.has_wait() {
985             return Err(EPROTO);
986         }
987         let wait: &mut VcpuResponse_Wait = response.mut_wait();
988         if wait.has_init() {
989             event.kind = CROSVM_VCPU_EVENT_KIND_INIT;
990             Ok(())
991         } else if wait.has_io() {
992             let mut io: VcpuResponse_Wait_Io = wait.take_io();
993             event.kind = CROSVM_VCPU_EVENT_KIND_IO_ACCESS;
994             event.event.io_access = anon_io_access {
995                 address_space: io.space.value() as u32,
996                 __reserved0: Default::default(),
997                 address: io.address,
998                 data: io.data.as_mut_ptr(),
999                 length: io.data.len() as u32,
1000                 is_write: io.is_write as u8,
1001                 __reserved1: Default::default(),
1002             };
1003             self.resume_data = io.data;
1004             Ok(())
1005         } else if wait.has_user() {
1006             let user: &VcpuResponse_Wait_User = wait.get_user();
1007             event.kind = CROSVM_VCPU_EVENT_KIND_PAUSED;
1008             event.event.user = user.user as *mut c_void;
1009             Ok(())
1010         } else {
1011             Err(EPROTO)
1012         }
1013     }
1014 
resume(&mut self) -> result::Result<(), c_int>1015     fn resume(&mut self) -> result::Result<(), c_int> {
1016         let mut r = VcpuRequest::new();
1017         let resume: &mut VcpuRequest_Resume = r.mut_resume();
1018         swap(&mut resume.data, &mut self.resume_data);
1019 
1020         self.vcpu_send(&r)?;
1021         Ok(())
1022     }
1023 
get_state( &mut self, state_set: VcpuRequest_StateSet, out: &mut [u8], ) -> result::Result<(), c_int>1024     fn get_state(
1025         &mut self,
1026         state_set: VcpuRequest_StateSet,
1027         out: &mut [u8],
1028     ) -> result::Result<(), c_int> {
1029         let mut r = VcpuRequest::new();
1030         r.mut_get_state().set = state_set;
1031         let response = self.vcpu_transaction(&r)?;
1032         if !response.has_get_state() {
1033             return Err(EPROTO);
1034         }
1035         let get_state: &VcpuResponse_GetState = response.get_get_state();
1036         if get_state.state.len() != out.len() {
1037             return Err(EPROTO);
1038         }
1039         out.copy_from_slice(&get_state.state);
1040         Ok(())
1041     }
1042 
set_state( &mut self, state_set: VcpuRequest_StateSet, new_state: &[u8], ) -> result::Result<(), c_int>1043     fn set_state(
1044         &mut self,
1045         state_set: VcpuRequest_StateSet,
1046         new_state: &[u8],
1047     ) -> result::Result<(), c_int> {
1048         let mut r = VcpuRequest::new();
1049         let set_state: &mut VcpuRequest_SetState = r.mut_set_state();
1050         set_state.set = state_set;
1051         set_state.state = new_state.to_vec();
1052 
1053         self.vcpu_transaction(&r)?;
1054         Ok(())
1055     }
1056 
get_msrs( &mut self, msr_entries: &mut [kvm_msr_entry], msr_count: &mut usize, ) -> result::Result<(), c_int>1057     fn get_msrs(
1058         &mut self,
1059         msr_entries: &mut [kvm_msr_entry],
1060         msr_count: &mut usize,
1061     ) -> result::Result<(), c_int> {
1062         *msr_count = 0;
1063 
1064         let mut r = VcpuRequest::new();
1065         let entry_indices: &mut Vec<u32> = r.mut_get_msrs().mut_entry_indices();
1066         for entry in msr_entries.iter() {
1067             entry_indices.push(entry.index);
1068         }
1069 
1070         let response = self.vcpu_transaction(&r)?;
1071         if !response.has_get_msrs() {
1072             return Err(EPROTO);
1073         }
1074         let get_msrs: &VcpuResponse_GetMsrs = response.get_get_msrs();
1075         *msr_count = get_msrs.get_entry_data().len();
1076         if *msr_count > msr_entries.len() {
1077             return Err(E2BIG);
1078         }
1079         for (&msr_data, msr_entry) in get_msrs.get_entry_data().iter().zip(msr_entries) {
1080             msr_entry.data = msr_data;
1081         }
1082         Ok(())
1083     }
1084 
set_msrs(&mut self, msr_entries: &[kvm_msr_entry]) -> result::Result<(), c_int>1085     fn set_msrs(&mut self, msr_entries: &[kvm_msr_entry]) -> result::Result<(), c_int> {
1086         let mut r = VcpuRequest::new();
1087         let set_msrs_entries: &mut RepeatedField<VcpuRequest_MsrEntry> =
1088             r.mut_set_msrs().mut_entries();
1089         for msr_entry in msr_entries {
1090             let mut entry = VcpuRequest_MsrEntry::new();
1091             entry.index = msr_entry.index;
1092             entry.data = msr_entry.data;
1093             set_msrs_entries.push(entry);
1094         }
1095 
1096         self.vcpu_transaction(&r)?;
1097         Ok(())
1098     }
1099 
set_cpuid(&mut self, cpuid_entries: &[kvm_cpuid_entry2]) -> result::Result<(), c_int>1100     fn set_cpuid(&mut self, cpuid_entries: &[kvm_cpuid_entry2]) -> result::Result<(), c_int> {
1101         let mut r = VcpuRequest::new();
1102         let set_cpuid_entries: &mut RepeatedField<CpuidEntry> = r.mut_set_cpuid().mut_entries();
1103         for cpuid_entry in cpuid_entries {
1104             set_cpuid_entries.push(cpuid_kvm_to_proto(cpuid_entry));
1105         }
1106 
1107         self.vcpu_transaction(&r)?;
1108         Ok(())
1109     }
1110 }
1111 
1112 // crosvm API signals success as 0 and errors as negative values
1113 // derived from `errno`.
to_crosvm_rc<T>(r: result::Result<T, c_int>) -> c_int1114 fn to_crosvm_rc<T>(r: result::Result<T, c_int>) -> c_int {
1115     match r {
1116         Ok(_) => 0,
1117         Err(e) => -e,
1118     }
1119 }
1120 
1121 #[no_mangle]
crosvm_connect(out: *mut *mut crosvm) -> c_int1122 pub unsafe extern "C" fn crosvm_connect(out: *mut *mut crosvm) -> c_int {
1123     let _u = STATS.record(Stat::Connect);
1124     let socket_name = match env::var("CROSVM_SOCKET") {
1125         Ok(v) => v,
1126         _ => return -ENOTCONN,
1127     };
1128 
1129     let socket = match socket_name.parse() {
1130         Ok(v) if v < 0 => return -EINVAL,
1131         Ok(v) => v,
1132         _ => return -EINVAL,
1133     };
1134 
1135     let socket = UnixDatagram::from_raw_fd(socket);
1136     let crosvm = match crosvm::from_connection(socket) {
1137         Ok(c) => c,
1138         Err(e) => return -e,
1139     };
1140     *out = Box::into_raw(Box::new(crosvm));
1141     0
1142 }
1143 
1144 #[no_mangle]
crosvm_new_connection(self_: *mut crosvm, out: *mut *mut crosvm) -> c_int1145 pub unsafe extern "C" fn crosvm_new_connection(self_: *mut crosvm, out: *mut *mut crosvm) -> c_int {
1146     let _u = STATS.record(Stat::NewConnection);
1147     let self_ = &mut (*self_);
1148     match self_.try_clone() {
1149         Ok(cloned) => {
1150             *out = Box::into_raw(Box::new(cloned));
1151             0
1152         }
1153         Err(e) => -e,
1154     }
1155 }
1156 
1157 #[no_mangle]
crosvm_destroy_connection(self_: *mut *mut crosvm) -> c_int1158 pub unsafe extern "C" fn crosvm_destroy_connection(self_: *mut *mut crosvm) -> c_int {
1159     let _u = STATS.record(Stat::DestroyConnection);
1160     Box::from_raw(*self_);
1161     *self_ = null_mut();
1162     0
1163 }
1164 
1165 #[no_mangle]
crosvm_get_shutdown_eventfd(self_: *mut crosvm) -> c_int1166 pub unsafe extern "C" fn crosvm_get_shutdown_eventfd(self_: *mut crosvm) -> c_int {
1167     let _u = STATS.record(Stat::GetShutdownEventFd);
1168     let self_ = &mut (*self_);
1169     match self_.get_shutdown_eventfd() {
1170         Ok(f) => f.into_raw_fd(),
1171         Err(e) => -e,
1172     }
1173 }
1174 
1175 #[no_mangle]
crosvm_check_extension( self_: *mut crosvm, extension: u32, has_extension: *mut bool, ) -> c_int1176 pub unsafe extern "C" fn crosvm_check_extension(
1177     self_: *mut crosvm,
1178     extension: u32,
1179     has_extension: *mut bool,
1180 ) -> c_int {
1181     let _u = STATS.record(Stat::CheckExtentsion);
1182     let self_ = &mut (*self_);
1183     let ret = self_.check_extension(extension);
1184 
1185     if let Ok(supported) = ret {
1186         *has_extension = supported;
1187     }
1188     to_crosvm_rc(ret)
1189 }
1190 
1191 #[no_mangle]
crosvm_get_supported_cpuid( this: *mut crosvm, entry_count: u32, cpuid_entries: *mut kvm_cpuid_entry2, out_count: *mut u32, ) -> c_int1192 pub unsafe extern "C" fn crosvm_get_supported_cpuid(
1193     this: *mut crosvm,
1194     entry_count: u32,
1195     cpuid_entries: *mut kvm_cpuid_entry2,
1196     out_count: *mut u32,
1197 ) -> c_int {
1198     let _u = STATS.record(Stat::GetSupportedCpuid);
1199     let this = &mut *this;
1200     let cpuid_entries = from_raw_parts_mut(cpuid_entries, entry_count as usize);
1201     let mut cpuid_count: usize = 0;
1202     let ret = this.get_supported_cpuid(cpuid_entries, &mut cpuid_count);
1203     *out_count = cpuid_count as u32;
1204     to_crosvm_rc(ret)
1205 }
1206 
1207 #[no_mangle]
crosvm_get_emulated_cpuid( this: *mut crosvm, entry_count: u32, cpuid_entries: *mut kvm_cpuid_entry2, out_count: *mut u32, ) -> c_int1208 pub unsafe extern "C" fn crosvm_get_emulated_cpuid(
1209     this: *mut crosvm,
1210     entry_count: u32,
1211     cpuid_entries: *mut kvm_cpuid_entry2,
1212     out_count: *mut u32,
1213 ) -> c_int {
1214     let _u = STATS.record(Stat::GetEmulatedCpuid);
1215     let this = &mut *this;
1216     let cpuid_entries = from_raw_parts_mut(cpuid_entries, entry_count as usize);
1217     let mut cpuid_count: usize = 0;
1218     let ret = this.get_emulated_cpuid(cpuid_entries, &mut cpuid_count);
1219     *out_count = cpuid_count as u32;
1220     to_crosvm_rc(ret)
1221 }
1222 
1223 #[no_mangle]
crosvm_get_msr_index_list( this: *mut crosvm, entry_count: u32, msr_indices: *mut u32, out_count: *mut u32, ) -> c_int1224 pub unsafe extern "C" fn crosvm_get_msr_index_list(
1225     this: *mut crosvm,
1226     entry_count: u32,
1227     msr_indices: *mut u32,
1228     out_count: *mut u32,
1229 ) -> c_int {
1230     let _u = STATS.record(Stat::GetMsrIndexList);
1231     let this = &mut *this;
1232     let msr_indices = from_raw_parts_mut(msr_indices, entry_count as usize);
1233     let mut msr_count: usize = 0;
1234     let ret = this.get_msr_index_list(msr_indices, &mut msr_count);
1235     *out_count = msr_count as u32;
1236     to_crosvm_rc(ret)
1237 }
1238 
1239 #[no_mangle]
crosvm_net_get_config( self_: *mut crosvm, config: *mut crosvm_net_config, ) -> c_int1240 pub unsafe extern "C" fn crosvm_net_get_config(
1241     self_: *mut crosvm,
1242     config: *mut crosvm_net_config,
1243 ) -> c_int {
1244     let _u = STATS.record(Stat::NetGetConfig);
1245     let self_ = &mut (*self_);
1246     let ret = self_.get_net_config();
1247 
1248     if let Ok(c) = ret {
1249         *config = c;
1250     }
1251 
1252     to_crosvm_rc(ret)
1253 }
1254 
1255 #[no_mangle]
crosvm_reserve_range( self_: *mut crosvm, space: u32, start: u64, length: u64, ) -> c_int1256 pub unsafe extern "C" fn crosvm_reserve_range(
1257     self_: *mut crosvm,
1258     space: u32,
1259     start: u64,
1260     length: u64,
1261 ) -> c_int {
1262     let _u = STATS.record(Stat::ReserveRange);
1263     let self_ = &mut (*self_);
1264     let ret = self_.reserve_range(space, start, length);
1265     to_crosvm_rc(ret)
1266 }
1267 
1268 #[no_mangle]
crosvm_set_irq(self_: *mut crosvm, irq_id: u32, active: bool) -> c_int1269 pub unsafe extern "C" fn crosvm_set_irq(self_: *mut crosvm, irq_id: u32, active: bool) -> c_int {
1270     let _u = STATS.record(Stat::SetIrq);
1271     let self_ = &mut (*self_);
1272     let ret = self_.set_irq(irq_id, active);
1273     to_crosvm_rc(ret)
1274 }
1275 
1276 #[no_mangle]
crosvm_set_irq_routing( self_: *mut crosvm, route_count: u32, routes: *const crosvm_irq_route, ) -> c_int1277 pub unsafe extern "C" fn crosvm_set_irq_routing(
1278     self_: *mut crosvm,
1279     route_count: u32,
1280     routes: *const crosvm_irq_route,
1281 ) -> c_int {
1282     let _u = STATS.record(Stat::SetIrqRouting);
1283     let self_ = &mut (*self_);
1284     let ret = self_.set_irq_routing(slice::from_raw_parts(routes, route_count as usize));
1285     to_crosvm_rc(ret)
1286 }
1287 
1288 #[no_mangle]
crosvm_get_pic_state( this: *mut crosvm, primary: bool, state: *mut kvm_pic_state, ) -> c_int1289 pub unsafe extern "C" fn crosvm_get_pic_state(
1290     this: *mut crosvm,
1291     primary: bool,
1292     state: *mut kvm_pic_state,
1293 ) -> c_int {
1294     let _u = STATS.record(Stat::GetPicState);
1295     let this = &mut *this;
1296     let state_set = if primary {
1297         MainRequest_StateSet::PIC0
1298     } else {
1299         MainRequest_StateSet::PIC1
1300     };
1301     let state = from_raw_parts_mut(state as *mut u8, size_of::<kvm_pic_state>());
1302     let ret = this.get_state(state_set, state);
1303     to_crosvm_rc(ret)
1304 }
1305 
1306 #[no_mangle]
crosvm_set_pic_state( this: *mut crosvm, primary: bool, state: *mut kvm_pic_state, ) -> c_int1307 pub unsafe extern "C" fn crosvm_set_pic_state(
1308     this: *mut crosvm,
1309     primary: bool,
1310     state: *mut kvm_pic_state,
1311 ) -> c_int {
1312     let _u = STATS.record(Stat::SetPicState);
1313     let this = &mut *this;
1314     let state_set = if primary {
1315         MainRequest_StateSet::PIC0
1316     } else {
1317         MainRequest_StateSet::PIC1
1318     };
1319     let state = from_raw_parts(state as *mut u8, size_of::<kvm_pic_state>());
1320     let ret = this.set_state(state_set, state);
1321     to_crosvm_rc(ret)
1322 }
1323 
1324 #[no_mangle]
crosvm_get_ioapic_state( this: *mut crosvm, state: *mut kvm_ioapic_state, ) -> c_int1325 pub unsafe extern "C" fn crosvm_get_ioapic_state(
1326     this: *mut crosvm,
1327     state: *mut kvm_ioapic_state,
1328 ) -> c_int {
1329     let _u = STATS.record(Stat::GetIoapicState);
1330     let this = &mut *this;
1331     let state = from_raw_parts_mut(state as *mut u8, size_of::<kvm_ioapic_state>());
1332     let ret = this.get_state(MainRequest_StateSet::IOAPIC, state);
1333     to_crosvm_rc(ret)
1334 }
1335 
1336 #[no_mangle]
crosvm_set_ioapic_state( this: *mut crosvm, state: *const kvm_ioapic_state, ) -> c_int1337 pub unsafe extern "C" fn crosvm_set_ioapic_state(
1338     this: *mut crosvm,
1339     state: *const kvm_ioapic_state,
1340 ) -> c_int {
1341     let _u = STATS.record(Stat::SetIoapicState);
1342     let this = &mut *this;
1343     let state = from_raw_parts(state as *mut u8, size_of::<kvm_ioapic_state>());
1344     let ret = this.set_state(MainRequest_StateSet::IOAPIC, state);
1345     to_crosvm_rc(ret)
1346 }
1347 
1348 #[no_mangle]
crosvm_get_pit_state( this: *mut crosvm, state: *mut kvm_pit_state2, ) -> c_int1349 pub unsafe extern "C" fn crosvm_get_pit_state(
1350     this: *mut crosvm,
1351     state: *mut kvm_pit_state2,
1352 ) -> c_int {
1353     let _u = STATS.record(Stat::GetPitState);
1354     let this = &mut *this;
1355     let state = from_raw_parts_mut(state as *mut u8, size_of::<kvm_pit_state2>());
1356     let ret = this.get_state(MainRequest_StateSet::PIT, state);
1357     to_crosvm_rc(ret)
1358 }
1359 
1360 #[no_mangle]
crosvm_set_pit_state( this: *mut crosvm, state: *const kvm_pit_state2, ) -> c_int1361 pub unsafe extern "C" fn crosvm_set_pit_state(
1362     this: *mut crosvm,
1363     state: *const kvm_pit_state2,
1364 ) -> c_int {
1365     let _u = STATS.record(Stat::SetPitState);
1366     let this = &mut *this;
1367     let state = from_raw_parts(state as *mut u8, size_of::<kvm_pit_state2>());
1368     let ret = this.set_state(MainRequest_StateSet::PIT, state);
1369     to_crosvm_rc(ret)
1370 }
1371 
1372 #[no_mangle]
crosvm_get_clock( this: *mut crosvm, clock_data: *mut kvm_clock_data, ) -> c_int1373 pub unsafe extern "C" fn crosvm_get_clock(
1374     this: *mut crosvm,
1375     clock_data: *mut kvm_clock_data,
1376 ) -> c_int {
1377     let _u = STATS.record(Stat::GetClock);
1378     let this = &mut *this;
1379     let state = from_raw_parts_mut(clock_data as *mut u8, size_of::<kvm_clock_data>());
1380     let ret = this.get_state(MainRequest_StateSet::CLOCK, state);
1381     to_crosvm_rc(ret)
1382 }
1383 
1384 #[no_mangle]
crosvm_set_clock( this: *mut crosvm, clock_data: *const kvm_clock_data, ) -> c_int1385 pub unsafe extern "C" fn crosvm_set_clock(
1386     this: *mut crosvm,
1387     clock_data: *const kvm_clock_data,
1388 ) -> c_int {
1389     let _u = STATS.record(Stat::SetClock);
1390     let this = &mut *this;
1391     let state = from_raw_parts(clock_data as *mut u8, size_of::<kvm_clock_data>());
1392     let ret = this.set_state(MainRequest_StateSet::CLOCK, state);
1393     to_crosvm_rc(ret)
1394 }
1395 
1396 #[no_mangle]
crosvm_set_identity_map_addr(self_: *mut crosvm, addr: u32) -> c_int1397 pub unsafe extern "C" fn crosvm_set_identity_map_addr(self_: *mut crosvm, addr: u32) -> c_int {
1398     let _u = STATS.record(Stat::SetIdentityMapAddr);
1399     let self_ = &mut (*self_);
1400     let ret = self_.set_identity_map_addr(addr);
1401     to_crosvm_rc(ret)
1402 }
1403 
1404 #[no_mangle]
crosvm_pause_vcpus( self_: *mut crosvm, cpu_mask: u64, user: *mut c_void, ) -> c_int1405 pub unsafe extern "C" fn crosvm_pause_vcpus(
1406     self_: *mut crosvm,
1407     cpu_mask: u64,
1408     user: *mut c_void,
1409 ) -> c_int {
1410     let _u = STATS.record(Stat::PauseVcpus);
1411     let self_ = &mut (*self_);
1412     let ret = self_.pause_vcpus(cpu_mask, user);
1413     to_crosvm_rc(ret)
1414 }
1415 
1416 #[no_mangle]
crosvm_start(self_: *mut crosvm) -> c_int1417 pub unsafe extern "C" fn crosvm_start(self_: *mut crosvm) -> c_int {
1418     let _u = STATS.record(Stat::Start);
1419     let self_ = &mut (*self_);
1420     let ret = self_.start();
1421     to_crosvm_rc(ret)
1422 }
1423 
1424 #[no_mangle]
crosvm_get_vcpu( self_: *mut crosvm, cpu_id: u32, out: *mut *mut crosvm_vcpu, ) -> c_int1425 pub unsafe extern "C" fn crosvm_get_vcpu(
1426     self_: *mut crosvm,
1427     cpu_id: u32,
1428     out: *mut *mut crosvm_vcpu,
1429 ) -> c_int {
1430     let _u = STATS.record(Stat::GetVcpu);
1431     let self_ = &mut (*self_);
1432     let ret = self_.get_vcpu(cpu_id);
1433 
1434     if let Ok(vcpu) = ret {
1435         *out = vcpu;
1436     }
1437     to_crosvm_rc(ret)
1438 }
1439 
1440 #[no_mangle]
crosvm_vcpu_wait( this: *mut crosvm_vcpu, event: *mut crosvm_vcpu_event, ) -> c_int1441 pub unsafe extern "C" fn crosvm_vcpu_wait(
1442     this: *mut crosvm_vcpu,
1443     event: *mut crosvm_vcpu_event,
1444 ) -> c_int {
1445     let _u = STATS.record(Stat::VcpuWait);
1446     let this = &mut *this;
1447     let event = &mut *event;
1448     let ret = this.wait(event);
1449     to_crosvm_rc(ret)
1450 }
1451 
1452 #[no_mangle]
crosvm_vcpu_resume(this: *mut crosvm_vcpu) -> c_int1453 pub unsafe extern "C" fn crosvm_vcpu_resume(this: *mut crosvm_vcpu) -> c_int {
1454     let _u = STATS.record(Stat::VcpuResume);
1455     let this = &mut *this;
1456     let ret = this.resume();
1457     to_crosvm_rc(ret)
1458 }
1459 
1460 #[no_mangle]
crosvm_vcpu_get_regs( this: *mut crosvm_vcpu, regs: *mut kvm_regs, ) -> c_int1461 pub unsafe extern "C" fn crosvm_vcpu_get_regs(
1462     this: *mut crosvm_vcpu,
1463     regs: *mut kvm_regs,
1464 ) -> c_int {
1465     let _u = STATS.record(Stat::VcpuGetRegs);
1466     let this = &mut *this;
1467     let regs = from_raw_parts_mut(regs as *mut u8, size_of::<kvm_regs>());
1468     let ret = this.get_state(VcpuRequest_StateSet::REGS, regs);
1469     to_crosvm_rc(ret)
1470 }
1471 
1472 #[no_mangle]
crosvm_vcpu_set_regs( this: *mut crosvm_vcpu, regs: *const kvm_regs, ) -> c_int1473 pub unsafe extern "C" fn crosvm_vcpu_set_regs(
1474     this: *mut crosvm_vcpu,
1475     regs: *const kvm_regs,
1476 ) -> c_int {
1477     let _u = STATS.record(Stat::VcpuSetRegs);
1478     let this = &mut *this;
1479     let regs = from_raw_parts(regs as *mut u8, size_of::<kvm_regs>());
1480     let ret = this.set_state(VcpuRequest_StateSet::REGS, regs);
1481     to_crosvm_rc(ret)
1482 }
1483 
1484 #[no_mangle]
crosvm_vcpu_get_sregs( this: *mut crosvm_vcpu, sregs: *mut kvm_sregs, ) -> c_int1485 pub unsafe extern "C" fn crosvm_vcpu_get_sregs(
1486     this: *mut crosvm_vcpu,
1487     sregs: *mut kvm_sregs,
1488 ) -> c_int {
1489     let _u = STATS.record(Stat::VcpuGetSregs);
1490     let this = &mut *this;
1491     let sregs = from_raw_parts_mut(sregs as *mut u8, size_of::<kvm_sregs>());
1492     let ret = this.get_state(VcpuRequest_StateSet::SREGS, sregs);
1493     to_crosvm_rc(ret)
1494 }
1495 
1496 #[no_mangle]
crosvm_vcpu_set_sregs( this: *mut crosvm_vcpu, sregs: *const kvm_sregs, ) -> c_int1497 pub unsafe extern "C" fn crosvm_vcpu_set_sregs(
1498     this: *mut crosvm_vcpu,
1499     sregs: *const kvm_sregs,
1500 ) -> c_int {
1501     let _u = STATS.record(Stat::VcpuSetSregs);
1502     let this = &mut *this;
1503     let sregs = from_raw_parts(sregs as *mut u8, size_of::<kvm_sregs>());
1504     let ret = this.set_state(VcpuRequest_StateSet::SREGS, sregs);
1505     to_crosvm_rc(ret)
1506 }
1507 
1508 #[no_mangle]
crosvm_vcpu_get_fpu(this: *mut crosvm_vcpu, fpu: *mut kvm_fpu) -> c_int1509 pub unsafe extern "C" fn crosvm_vcpu_get_fpu(this: *mut crosvm_vcpu, fpu: *mut kvm_fpu) -> c_int {
1510     let _u = STATS.record(Stat::GetFpu);
1511     let this = &mut *this;
1512     let fpu = from_raw_parts_mut(fpu as *mut u8, size_of::<kvm_fpu>());
1513     let ret = this.get_state(VcpuRequest_StateSet::FPU, fpu);
1514     to_crosvm_rc(ret)
1515 }
1516 
1517 #[no_mangle]
crosvm_vcpu_set_fpu(this: *mut crosvm_vcpu, fpu: *const kvm_fpu) -> c_int1518 pub unsafe extern "C" fn crosvm_vcpu_set_fpu(this: *mut crosvm_vcpu, fpu: *const kvm_fpu) -> c_int {
1519     let _u = STATS.record(Stat::SetFpu);
1520     let this = &mut *this;
1521     let fpu = from_raw_parts(fpu as *mut u8, size_of::<kvm_fpu>());
1522     let ret = this.set_state(VcpuRequest_StateSet::FPU, fpu);
1523     to_crosvm_rc(ret)
1524 }
1525 
1526 #[no_mangle]
crosvm_vcpu_get_debugregs( this: *mut crosvm_vcpu, dregs: *mut kvm_debugregs, ) -> c_int1527 pub unsafe extern "C" fn crosvm_vcpu_get_debugregs(
1528     this: *mut crosvm_vcpu,
1529     dregs: *mut kvm_debugregs,
1530 ) -> c_int {
1531     let _u = STATS.record(Stat::GetDebugRegs);
1532     let this = &mut *this;
1533     let dregs = from_raw_parts_mut(dregs as *mut u8, size_of::<kvm_debugregs>());
1534     let ret = this.get_state(VcpuRequest_StateSet::DEBUGREGS, dregs);
1535     to_crosvm_rc(ret)
1536 }
1537 
1538 #[no_mangle]
crosvm_vcpu_set_debugregs( this: *mut crosvm_vcpu, dregs: *const kvm_debugregs, ) -> c_int1539 pub unsafe extern "C" fn crosvm_vcpu_set_debugregs(
1540     this: *mut crosvm_vcpu,
1541     dregs: *const kvm_debugregs,
1542 ) -> c_int {
1543     let _u = STATS.record(Stat::SetDebugRegs);
1544     let this = &mut *this;
1545     let dregs = from_raw_parts(dregs as *mut u8, size_of::<kvm_debugregs>());
1546     let ret = this.set_state(VcpuRequest_StateSet::DEBUGREGS, dregs);
1547     to_crosvm_rc(ret)
1548 }
1549 
1550 #[no_mangle]
crosvm_vcpu_get_xcrs( this: *mut crosvm_vcpu, xcrs: *mut kvm_xcrs, ) -> c_int1551 pub unsafe extern "C" fn crosvm_vcpu_get_xcrs(
1552     this: *mut crosvm_vcpu,
1553     xcrs: *mut kvm_xcrs,
1554 ) -> c_int {
1555     let _u = STATS.record(Stat::GetXCRegs);
1556     let this = &mut *this;
1557     let xcrs = from_raw_parts_mut(xcrs as *mut u8, size_of::<kvm_xcrs>());
1558     let ret = this.get_state(VcpuRequest_StateSet::XCREGS, xcrs);
1559     to_crosvm_rc(ret)
1560 }
1561 
1562 #[no_mangle]
crosvm_vcpu_set_xcrs( this: *mut crosvm_vcpu, xcrs: *const kvm_xcrs, ) -> c_int1563 pub unsafe extern "C" fn crosvm_vcpu_set_xcrs(
1564     this: *mut crosvm_vcpu,
1565     xcrs: *const kvm_xcrs,
1566 ) -> c_int {
1567     let _u = STATS.record(Stat::SetXCRegs);
1568     let this = &mut *this;
1569     let xcrs = from_raw_parts(xcrs as *mut u8, size_of::<kvm_xcrs>());
1570     let ret = this.set_state(VcpuRequest_StateSet::XCREGS, xcrs);
1571     to_crosvm_rc(ret)
1572 }
1573 
1574 #[no_mangle]
crosvm_vcpu_get_msrs( this: *mut crosvm_vcpu, msr_count: u32, msr_entries: *mut kvm_msr_entry, out_count: *mut u32, ) -> c_int1575 pub unsafe extern "C" fn crosvm_vcpu_get_msrs(
1576     this: *mut crosvm_vcpu,
1577     msr_count: u32,
1578     msr_entries: *mut kvm_msr_entry,
1579     out_count: *mut u32,
1580 ) -> c_int {
1581     let _u = STATS.record(Stat::VcpuGetMsrs);
1582     let this = &mut *this;
1583     let msr_entries = from_raw_parts_mut(msr_entries, msr_count as usize);
1584     let mut count: usize = 0;
1585     let ret = this.get_msrs(msr_entries, &mut count);
1586     *out_count = count as u32;
1587     to_crosvm_rc(ret)
1588 }
1589 
1590 #[no_mangle]
crosvm_vcpu_set_msrs( this: *mut crosvm_vcpu, msr_count: u32, msr_entries: *const kvm_msr_entry, ) -> c_int1591 pub unsafe extern "C" fn crosvm_vcpu_set_msrs(
1592     this: *mut crosvm_vcpu,
1593     msr_count: u32,
1594     msr_entries: *const kvm_msr_entry,
1595 ) -> c_int {
1596     let _u = STATS.record(Stat::VcpuSetMsrs);
1597     let this = &mut *this;
1598     let msr_entries = from_raw_parts(msr_entries, msr_count as usize);
1599     let ret = this.set_msrs(msr_entries);
1600     to_crosvm_rc(ret)
1601 }
1602 
1603 #[no_mangle]
crosvm_vcpu_set_cpuid( this: *mut crosvm_vcpu, cpuid_count: u32, cpuid_entries: *const kvm_cpuid_entry2, ) -> c_int1604 pub unsafe extern "C" fn crosvm_vcpu_set_cpuid(
1605     this: *mut crosvm_vcpu,
1606     cpuid_count: u32,
1607     cpuid_entries: *const kvm_cpuid_entry2,
1608 ) -> c_int {
1609     let _u = STATS.record(Stat::VcpuSetCpuid);
1610     let this = &mut *this;
1611     let cpuid_entries = from_raw_parts(cpuid_entries, cpuid_count as usize);
1612     let ret = this.set_cpuid(cpuid_entries);
1613     to_crosvm_rc(ret)
1614 }
1615 
1616 #[no_mangle]
crosvm_vcpu_get_lapic_state( this: *mut crosvm_vcpu, state: *mut kvm_lapic_state, ) -> c_int1617 pub unsafe extern "C" fn crosvm_vcpu_get_lapic_state(
1618     this: *mut crosvm_vcpu,
1619     state: *mut kvm_lapic_state,
1620 ) -> c_int {
1621     let _u = STATS.record(Stat::VcpuGetLapicState);
1622     let this = &mut *this;
1623     let state = from_raw_parts_mut(state as *mut u8, size_of::<kvm_lapic_state>());
1624     let ret = this.get_state(VcpuRequest_StateSet::LAPIC, state);
1625     to_crosvm_rc(ret)
1626 }
1627 
1628 #[no_mangle]
crosvm_vcpu_set_lapic_state( this: *mut crosvm_vcpu, state: *const kvm_lapic_state, ) -> c_int1629 pub unsafe extern "C" fn crosvm_vcpu_set_lapic_state(
1630     this: *mut crosvm_vcpu,
1631     state: *const kvm_lapic_state,
1632 ) -> c_int {
1633     let _u = STATS.record(Stat::VcpuSetLapicState);
1634     let this = &mut *this;
1635     let state = from_raw_parts(state as *mut u8, size_of::<kvm_lapic_state>());
1636     let ret = this.set_state(VcpuRequest_StateSet::LAPIC, state);
1637     to_crosvm_rc(ret)
1638 }
1639 
1640 #[no_mangle]
crosvm_vcpu_get_mp_state( this: *mut crosvm_vcpu, state: *mut kvm_mp_state, ) -> c_int1641 pub unsafe extern "C" fn crosvm_vcpu_get_mp_state(
1642     this: *mut crosvm_vcpu,
1643     state: *mut kvm_mp_state,
1644 ) -> c_int {
1645     let _u = STATS.record(Stat::VcpuGetMpState);
1646     let this = &mut *this;
1647     let state = from_raw_parts_mut(state as *mut u8, size_of::<kvm_mp_state>());
1648     let ret = this.get_state(VcpuRequest_StateSet::MP, state);
1649     to_crosvm_rc(ret)
1650 }
1651 
1652 #[no_mangle]
crosvm_vcpu_set_mp_state( this: *mut crosvm_vcpu, state: *const kvm_mp_state, ) -> c_int1653 pub unsafe extern "C" fn crosvm_vcpu_set_mp_state(
1654     this: *mut crosvm_vcpu,
1655     state: *const kvm_mp_state,
1656 ) -> c_int {
1657     let _u = STATS.record(Stat::VcpuSetMpState);
1658     let this = &mut *this;
1659     let state = from_raw_parts(state as *mut u8, size_of::<kvm_mp_state>());
1660     let ret = this.set_state(VcpuRequest_StateSet::MP, state);
1661     to_crosvm_rc(ret)
1662 }
1663 
1664 #[no_mangle]
crosvm_vcpu_get_vcpu_events( this: *mut crosvm_vcpu, events: *mut kvm_vcpu_events, ) -> c_int1665 pub unsafe extern "C" fn crosvm_vcpu_get_vcpu_events(
1666     this: *mut crosvm_vcpu,
1667     events: *mut kvm_vcpu_events,
1668 ) -> c_int {
1669     let _u = STATS.record(Stat::VcpuGetVcpuEvents);
1670     let this = &mut *this;
1671     let events = from_raw_parts_mut(events as *mut u8, size_of::<kvm_vcpu_events>());
1672     let ret = this.get_state(VcpuRequest_StateSet::EVENTS, events);
1673     to_crosvm_rc(ret)
1674 }
1675 
1676 #[no_mangle]
crosvm_vcpu_set_vcpu_events( this: *mut crosvm_vcpu, events: *const kvm_vcpu_events, ) -> c_int1677 pub unsafe extern "C" fn crosvm_vcpu_set_vcpu_events(
1678     this: *mut crosvm_vcpu,
1679     events: *const kvm_vcpu_events,
1680 ) -> c_int {
1681     let _u = STATS.record(Stat::VcpuSetVcpuEvents);
1682     let this = &mut *this;
1683     let events = from_raw_parts(events as *mut u8, size_of::<kvm_vcpu_events>());
1684     let ret = this.set_state(VcpuRequest_StateSet::EVENTS, events);
1685     to_crosvm_rc(ret)
1686 }
1687