• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #![cfg(unix)]
6 #![cfg(any(target_arch = "x86", target_arch = "x86_64"))]
7 #![allow(non_camel_case_types)]
8 
9 //! This module implements the dynamically loaded client library API used by a crosvm plugin,
10 //! defined in `crosvm.h`. It implements the client half of the plugin protocol, which is defined in
11 //! the `protos::plugin` module.
12 //!
13 //! To implement the `crosvm.h` C API, each function and struct definition is repeated here, with
14 //! concrete definitions for each struct. Most functions are thin shims to the underlying object
15 //! oriented Rust implementation method. Most methods require a request over the crosvm connection,
16 //! which is done by creating a `MainRequest` or `VcpuRequest` protobuf and sending it over the
17 //! connection's socket. Then, that socket is read for a `MainResponse` or `VcpuResponse`, which is
18 //! translated to the appropriate return type for the C API.
19 
20 use std::env;
21 use std::fs::File;
22 use std::io::IoSlice;
23 use std::io::IoSliceMut;
24 use std::io::Read;
25 use std::io::Write;
26 use std::mem::size_of;
27 use std::mem::swap;
28 use std::os::raw::c_int;
29 use std::os::raw::c_void;
30 use std::os::unix::io::AsRawFd;
31 use std::os::unix::io::FromRawFd;
32 use std::os::unix::io::IntoRawFd;
33 use std::os::unix::io::RawFd;
34 use std::os::unix::net::UnixDatagram;
35 use std::ptr;
36 use std::ptr::null_mut;
37 use std::result;
38 use std::slice;
39 use std::slice::from_raw_parts;
40 use std::slice::from_raw_parts_mut;
41 use std::sync::atomic::AtomicUsize;
42 use std::sync::atomic::Ordering;
43 use std::sync::Arc;
44 
45 use base::ScmSocket;
46 use kvm::dirty_log_bitmap_size;
47 use kvm_sys::kvm_clock_data;
48 use kvm_sys::kvm_cpuid_entry2;
49 use kvm_sys::kvm_debugregs;
50 use kvm_sys::kvm_fpu;
51 use kvm_sys::kvm_ioapic_state;
52 use kvm_sys::kvm_lapic_state;
53 use kvm_sys::kvm_mp_state;
54 use kvm_sys::kvm_msr_entry;
55 use kvm_sys::kvm_pic_state;
56 use kvm_sys::kvm_pit_state2;
57 use kvm_sys::kvm_regs;
58 use kvm_sys::kvm_sregs;
59 use kvm_sys::kvm_vcpu_events;
60 use kvm_sys::kvm_xcrs;
61 use libc::E2BIG;
62 use libc::EINVAL;
63 use libc::ENOENT;
64 use libc::ENOTCONN;
65 use libc::EPROTO;
66 use protobuf::Message;
67 use protobuf::ProtobufEnum;
68 use protobuf::RepeatedField;
69 use protos::plugin::*;
70 
71 #[cfg(feature = "stats")]
72 mod stats;
73 
74 // Needs to be large enough to receive all the VCPU sockets.
75 const MAX_DATAGRAM_FD: usize = 32;
76 // Needs to be large enough for a sizable dirty log.
77 const MAX_DATAGRAM_SIZE: usize = 0x40000;
78 
79 const CROSVM_IRQ_ROUTE_IRQCHIP: u32 = 0;
80 const CROSVM_IRQ_ROUTE_MSI: u32 = 1;
81 
82 const CROSVM_VCPU_EVENT_KIND_INIT: u32 = 0;
83 const CROSVM_VCPU_EVENT_KIND_IO_ACCESS: u32 = 1;
84 const CROSVM_VCPU_EVENT_KIND_PAUSED: u32 = 2;
85 const CROSVM_VCPU_EVENT_KIND_HYPERV_HCALL: u32 = 3;
86 const CROSVM_VCPU_EVENT_KIND_HYPERV_SYNIC: u32 = 4;
87 
88 pub const CROSVM_GPU_SERVER_FD_ENV: &str = "CROSVM_GPU_SERVER_FD";
89 pub const CROSVM_SOCKET_ENV: &str = "CROSVM_SOCKET";
90 #[cfg(feature = "stats")]
91 pub const CROSVM_STATS_ENV: &str = "CROSVM_STATS";
92 
93 #[repr(C)]
94 #[derive(Copy, Clone)]
95 pub struct crosvm_net_config {
96     tap_fd: c_int,
97     host_ipv4_address: u32,
98     netmask: u32,
99     host_mac_address: [u8; 6],
100     _reserved: [u8; 2],
101 }
102 
103 #[repr(C)]
104 #[derive(Copy, Clone)]
105 pub struct anon_irqchip {
106     irqchip: u32,
107     pin: u32,
108 }
109 
110 #[repr(C)]
111 #[derive(Copy, Clone)]
112 pub struct anon_msi {
113     address: u64,
114     data: u32,
115 }
116 
117 #[repr(C)]
118 pub union anon_route {
119     irqchip: anon_irqchip,
120     msi: anon_msi,
121     reserved: [u8; 16],
122 }
123 
124 #[repr(C)]
125 pub struct crosvm_irq_route {
126     irq_id: u32,
127     kind: u32,
128     route: anon_route,
129 }
130 
131 const CROSVM_MAX_HINT_COUNT: u32 = 1;
132 const CROSVM_MAX_HINT_DETAIL_COUNT: u32 = 32;
133 const CROSVM_HINT_ON_WRITE: u16 = 1;
134 
135 #[repr(C)]
136 pub struct crosvm_hint {
137     hint_version: u32,
138     reserved: u32,
139     address_space: u32,
140     address_flags: u16,
141     details_count: u16,
142     address: u64,
143     details: *const crosvm_hint_detail,
144 }
145 
146 #[repr(C)]
147 pub struct crosvm_hint_detail {
148     match_rax: bool,
149     match_rbx: bool,
150     match_rcx: bool,
151     match_rdx: bool,
152     reserved1: [u8; 4],
153     rax: u64,
154     rbx: u64,
155     rcx: u64,
156     rdx: u64,
157     send_sregs: bool,
158     send_debugregs: bool,
159     reserved2: [u8; 6],
160 }
161 
proto_error_to_int(e: protobuf::ProtobufError) -> c_int162 fn proto_error_to_int(e: protobuf::ProtobufError) -> c_int {
163     match e {
164         protobuf::ProtobufError::IoError(e) => e.raw_os_error().unwrap_or(EINVAL),
165         _ => EINVAL,
166     }
167 }
168 
fd_cast<F: FromRawFd>(f: File) -> F169 fn fd_cast<F: FromRawFd>(f: File) -> F {
170     // Safe because we are transferring unique ownership.
171     unsafe { F::from_raw_fd(f.into_raw_fd()) }
172 }
173 
174 #[derive(Default)]
175 struct IdAllocator(AtomicUsize);
176 
177 impl IdAllocator {
alloc(&self) -> u32178     fn alloc(&self) -> u32 {
179         self.0.fetch_add(1, Ordering::Relaxed) as u32
180     }
181 
free(&self, id: u32)182     fn free(&self, id: u32) {
183         let _ = self.0.compare_exchange(
184             id as usize + 1,
185             id as usize,
186             Ordering::Relaxed,
187             Ordering::Relaxed,
188         );
189     }
190 }
191 
192 #[repr(u8)]
193 #[derive(Debug, Clone, Copy)]
194 pub enum Stat {
195     IoEvent,
196     MemoryGetDirtyLog,
197     IrqEventGetFd,
198     IrqEventGetResampleFd,
199     Connect,
200     DestroyConnection,
201     GetShutdownEvent,
202     CheckExtentsion,
203     EnableVmCapability,
204     EnableVcpuCapability,
205     GetSupportedCpuid,
206     GetEmulatedCpuid,
207     GetHypervCpuid,
208     GetMsrIndexList,
209     NetGetConfig,
210     ReserveRange,
211     ReserveAsyncWriteRange,
212     SetIrq,
213     SetIrqRouting,
214     GetPicState,
215     SetPicState,
216     GetIoapicState,
217     SetIoapicState,
218     GetPitState,
219     SetPitState,
220     GetClock,
221     SetClock,
222     SetIdentityMapAddr,
223     PauseVcpus,
224     Start,
225     GetVcpu,
226     VcpuWait,
227     VcpuResume,
228     VcpuGetRegs,
229     VcpuSetRegs,
230     VcpuGetSregs,
231     VcpuSetSregs,
232     GetFpu,
233     SetFpu,
234     GetDebugRegs,
235     SetDebugRegs,
236     GetXCRegs,
237     SetXCRegs,
238     VcpuGetMsrs,
239     VcpuSetMsrs,
240     VcpuSetCpuid,
241     VcpuGetLapicState,
242     VcpuSetLapicState,
243     VcpuGetMpState,
244     VcpuSetMpState,
245     VcpuGetVcpuEvents,
246     VcpuSetVcpuEvents,
247     NewConnection,
248     SetHypercallHint,
249 
250     Count,
251 }
252 
253 #[cfg(feature = "stats")]
record(a: Stat) -> stats::StatUpdater254 fn record(a: Stat) -> stats::StatUpdater {
255     unsafe { stats::STATS.record(a) }
256 }
257 
258 #[cfg(not(feature = "stats"))]
record(_a: Stat) -> u32259 fn record(_a: Stat) -> u32 {
260     0
261 }
262 
263 #[cfg(feature = "stats")]
printstats()264 fn printstats() {
265     // Unsafe due to racy access - OK for stats
266     if std::env::var(CROSVM_STATS_ENV).is_ok() {
267         unsafe {
268             stats::STATS.print();
269         }
270     }
271 }
272 
273 #[cfg(not(feature = "stats"))]
printstats()274 fn printstats() {}
275 
276 pub struct crosvm {
277     id_allocator: Arc<IdAllocator>,
278     socket: UnixDatagram,
279     request_buffer: Vec<u8>,
280     response_buffer: Vec<u8>,
281     vcpus: Arc<[crosvm_vcpu]>,
282 }
283 
284 impl crosvm {
from_connection(socket: UnixDatagram) -> result::Result<crosvm, c_int>285     fn from_connection(socket: UnixDatagram) -> result::Result<crosvm, c_int> {
286         let mut crosvm = crosvm {
287             id_allocator: Default::default(),
288             socket,
289             request_buffer: Vec::new(),
290             response_buffer: vec![0; MAX_DATAGRAM_SIZE],
291             vcpus: Arc::new([]),
292         };
293         crosvm.load_all_vcpus()?;
294         Ok(crosvm)
295     }
296 
new( id_allocator: Arc<IdAllocator>, socket: UnixDatagram, vcpus: Arc<[crosvm_vcpu]>, ) -> crosvm297     fn new(
298         id_allocator: Arc<IdAllocator>,
299         socket: UnixDatagram,
300         vcpus: Arc<[crosvm_vcpu]>,
301     ) -> crosvm {
302         crosvm {
303             id_allocator,
304             socket,
305             request_buffer: Vec::new(),
306             response_buffer: vec![0; MAX_DATAGRAM_SIZE],
307             vcpus,
308         }
309     }
310 
get_id_allocator(&self) -> &IdAllocator311     fn get_id_allocator(&self) -> &IdAllocator {
312         &self.id_allocator
313     }
314 
main_transaction( &mut self, request: &MainRequest, fds: &[RawFd], ) -> result::Result<(MainResponse, Vec<File>), c_int>315     fn main_transaction(
316         &mut self,
317         request: &MainRequest,
318         fds: &[RawFd],
319     ) -> result::Result<(MainResponse, Vec<File>), c_int> {
320         self.request_buffer.clear();
321         request
322             .write_to_vec(&mut self.request_buffer)
323             .map_err(proto_error_to_int)?;
324         self.socket
325             .send_with_fds(&[IoSlice::new(self.request_buffer.as_slice())], fds)
326             .map_err(|e| -e.errno())?;
327 
328         let mut datagram_fds = [0; MAX_DATAGRAM_FD];
329         let (msg_size, fd_count) = self
330             .socket
331             .recv_with_fds(
332                 IoSliceMut::new(&mut self.response_buffer),
333                 &mut datagram_fds,
334             )
335             .map_err(|e| -e.errno())?;
336         // Safe because the first fd_count fds from recv_with_fds are owned by us and valid.
337         let datagram_files = datagram_fds[..fd_count]
338             .iter()
339             .map(|&fd| unsafe { File::from_raw_fd(fd) })
340             .collect();
341 
342         let response: MainResponse = Message::parse_from_bytes(&self.response_buffer[..msg_size])
343             .map_err(proto_error_to_int)?;
344         if response.errno != 0 {
345             return Err(response.errno);
346         }
347         Ok((response, datagram_files))
348     }
349 
try_clone(&mut self) -> result::Result<crosvm, c_int>350     fn try_clone(&mut self) -> result::Result<crosvm, c_int> {
351         let mut r = MainRequest::new();
352         r.mut_new_connection();
353         let mut files = self.main_transaction(&r, &[])?.1;
354         match files.pop() {
355             Some(new_socket) => Ok(crosvm::new(
356                 self.id_allocator.clone(),
357                 fd_cast(new_socket),
358                 self.vcpus.clone(),
359             )),
360             None => Err(EPROTO),
361         }
362     }
363 
destroy(&mut self, id: u32) -> result::Result<(), c_int>364     fn destroy(&mut self, id: u32) -> result::Result<(), c_int> {
365         let mut r = MainRequest::new();
366         r.mut_destroy().id = id;
367         self.main_transaction(&r, &[])?;
368         self.get_id_allocator().free(id);
369         printstats();
370         Ok(())
371     }
372 
373     // Only call this at `from_connection` function.
load_all_vcpus(&mut self) -> result::Result<(), c_int>374     fn load_all_vcpus(&mut self) -> result::Result<(), c_int> {
375         let mut r = MainRequest::new();
376         r.mut_get_vcpus();
377         let (_, mut files) = self.main_transaction(&r, &[])?;
378         if files.is_empty() || files.len() % 2 != 0 {
379             return Err(EPROTO);
380         }
381 
382         let mut vcpus = Vec::with_capacity(files.len() / 2);
383         while files.len() > 1 {
384             let write_pipe = files.remove(0);
385             let read_pipe = files.remove(0);
386             vcpus.push(crosvm_vcpu::new(fd_cast(read_pipe), fd_cast(write_pipe)));
387         }
388         self.vcpus = Arc::from(vcpus);
389         Ok(())
390     }
391 
get_shutdown_event(&mut self) -> result::Result<File, c_int>392     fn get_shutdown_event(&mut self) -> result::Result<File, c_int> {
393         let mut r = MainRequest::new();
394         r.mut_get_shutdown_eventfd();
395         let (_, mut files) = self.main_transaction(&r, &[])?;
396         match files.pop() {
397             Some(f) => Ok(f),
398             None => Err(EPROTO),
399         }
400     }
401 
check_extension(&mut self, extension: u32) -> result::Result<bool, c_int>402     fn check_extension(&mut self, extension: u32) -> result::Result<bool, c_int> {
403         let mut r = MainRequest::new();
404         r.mut_check_extension().extension = extension;
405         let (response, _) = self.main_transaction(&r, &[])?;
406         if !response.has_check_extension() {
407             return Err(EPROTO);
408         }
409         Ok(response.get_check_extension().has_extension)
410     }
411 
get_supported_cpuid( &mut self, cpuid_entries: &mut [kvm_cpuid_entry2], cpuid_count: &mut usize, ) -> result::Result<(), c_int>412     fn get_supported_cpuid(
413         &mut self,
414         cpuid_entries: &mut [kvm_cpuid_entry2],
415         cpuid_count: &mut usize,
416     ) -> result::Result<(), c_int> {
417         *cpuid_count = 0;
418 
419         let mut r = MainRequest::new();
420         r.mut_get_supported_cpuid();
421 
422         let (response, _) = self.main_transaction(&r, &[])?;
423         if !response.has_get_supported_cpuid() {
424             return Err(EPROTO);
425         }
426 
427         let supported_cpuids: &MainResponse_CpuidResponse = response.get_get_supported_cpuid();
428 
429         *cpuid_count = supported_cpuids.get_entries().len();
430         if *cpuid_count > cpuid_entries.len() {
431             return Err(E2BIG);
432         }
433 
434         for (proto_entry, kvm_entry) in supported_cpuids
435             .get_entries()
436             .iter()
437             .zip(cpuid_entries.iter_mut())
438         {
439             *kvm_entry = cpuid_proto_to_kvm(proto_entry);
440         }
441 
442         Ok(())
443     }
444 
get_emulated_cpuid( &mut self, cpuid_entries: &mut [kvm_cpuid_entry2], cpuid_count: &mut usize, ) -> result::Result<(), c_int>445     fn get_emulated_cpuid(
446         &mut self,
447         cpuid_entries: &mut [kvm_cpuid_entry2],
448         cpuid_count: &mut usize,
449     ) -> result::Result<(), c_int> {
450         *cpuid_count = 0;
451 
452         let mut r = MainRequest::new();
453         r.mut_get_emulated_cpuid();
454 
455         let (response, _) = self.main_transaction(&r, &[])?;
456         if !response.has_get_emulated_cpuid() {
457             return Err(EPROTO);
458         }
459 
460         let emulated_cpuids: &MainResponse_CpuidResponse = response.get_get_emulated_cpuid();
461 
462         *cpuid_count = emulated_cpuids.get_entries().len();
463         if *cpuid_count > cpuid_entries.len() {
464             return Err(E2BIG);
465         }
466 
467         for (proto_entry, kvm_entry) in emulated_cpuids
468             .get_entries()
469             .iter()
470             .zip(cpuid_entries.iter_mut())
471         {
472             *kvm_entry = cpuid_proto_to_kvm(proto_entry);
473         }
474 
475         Ok(())
476     }
477 
get_msr_index_list( &mut self, msr_indices: &mut [u32], msr_count: &mut usize, ) -> result::Result<(), c_int>478     fn get_msr_index_list(
479         &mut self,
480         msr_indices: &mut [u32],
481         msr_count: &mut usize,
482     ) -> result::Result<(), c_int> {
483         *msr_count = 0;
484 
485         let mut r = MainRequest::new();
486         r.mut_get_msr_index_list();
487 
488         let (response, _) = self.main_transaction(&r, &[])?;
489         if !response.has_get_msr_index_list() {
490             return Err(EPROTO);
491         }
492 
493         let msr_list: &MainResponse_MsrListResponse = response.get_get_msr_index_list();
494 
495         *msr_count = msr_list.get_indices().len();
496         if *msr_count > msr_indices.len() {
497             return Err(E2BIG);
498         }
499 
500         for (proto_entry, kvm_entry) in msr_list.get_indices().iter().zip(msr_indices.iter_mut()) {
501             *kvm_entry = *proto_entry;
502         }
503 
504         Ok(())
505     }
506 
reserve_range( &mut self, space: u32, start: u64, length: u64, async_write: bool, ) -> result::Result<(), c_int>507     fn reserve_range(
508         &mut self,
509         space: u32,
510         start: u64,
511         length: u64,
512         async_write: bool,
513     ) -> result::Result<(), c_int> {
514         let mut r = MainRequest::new();
515         let reserve: &mut MainRequest_ReserveRange = r.mut_reserve_range();
516         reserve.space = AddressSpace::from_i32(space as i32).ok_or(EINVAL)?;
517         reserve.start = start;
518         reserve.length = length;
519         reserve.async_write = async_write;
520 
521         self.main_transaction(&r, &[])?;
522         Ok(())
523     }
524 
set_irq(&mut self, irq_id: u32, active: bool) -> result::Result<(), c_int>525     fn set_irq(&mut self, irq_id: u32, active: bool) -> result::Result<(), c_int> {
526         let mut r = MainRequest::new();
527         let set_irq: &mut MainRequest_SetIrq = r.mut_set_irq();
528         set_irq.irq_id = irq_id;
529         set_irq.active = active;
530 
531         self.main_transaction(&r, &[])?;
532         Ok(())
533     }
534 
set_irq_routing(&mut self, routing: &[crosvm_irq_route]) -> result::Result<(), c_int>535     fn set_irq_routing(&mut self, routing: &[crosvm_irq_route]) -> result::Result<(), c_int> {
536         let mut r = MainRequest::new();
537         let set_irq_routing: &mut RepeatedField<MainRequest_SetIrqRouting_Route> =
538             r.mut_set_irq_routing().mut_routes();
539         for route in routing {
540             let mut entry = MainRequest_SetIrqRouting_Route::new();
541             entry.irq_id = route.irq_id;
542             match route.kind {
543                 CROSVM_IRQ_ROUTE_IRQCHIP => {
544                     let irqchip: &mut MainRequest_SetIrqRouting_Route_Irqchip = entry.mut_irqchip();
545                     // Safe because route.kind indicates which union field is valid.
546                     irqchip.irqchip = unsafe { route.route.irqchip }.irqchip;
547                     irqchip.pin = unsafe { route.route.irqchip }.pin;
548                 }
549                 CROSVM_IRQ_ROUTE_MSI => {
550                     let msi: &mut MainRequest_SetIrqRouting_Route_Msi = entry.mut_msi();
551                     // Safe because route.kind indicates which union field is valid.
552                     msi.address = unsafe { route.route.msi }.address;
553                     msi.data = unsafe { route.route.msi }.data;
554                 }
555                 _ => return Err(EINVAL),
556             }
557             set_irq_routing.push(entry);
558         }
559 
560         self.main_transaction(&r, &[])?;
561         Ok(())
562     }
563 
set_hint( &mut self, space: u32, addr: u64, on_write: bool, hints: &[crosvm_hint_detail], ) -> result::Result<(), c_int>564     fn set_hint(
565         &mut self,
566         space: u32,
567         addr: u64,
568         on_write: bool,
569         hints: &[crosvm_hint_detail],
570     ) -> result::Result<(), c_int> {
571         let mut r = MainRequest::new();
572         let req: &mut MainRequest_SetCallHint = r.mut_set_call_hint();
573         let set_hints: &mut RepeatedField<MainRequest_SetCallHint_RegHint> = req.mut_hints();
574         for hint in hints {
575             let mut entry = MainRequest_SetCallHint_RegHint::new();
576             entry.match_rax = hint.match_rax;
577             entry.match_rbx = hint.match_rbx;
578             entry.match_rcx = hint.match_rcx;
579             entry.match_rdx = hint.match_rdx;
580             entry.rax = hint.rax;
581             entry.rbx = hint.rbx;
582             entry.rcx = hint.rcx;
583             entry.rdx = hint.rdx;
584             entry.send_sregs = hint.send_sregs;
585             entry.send_debugregs = hint.send_debugregs;
586             set_hints.push(entry);
587         }
588         req.space = AddressSpace::from_i32(space as i32).ok_or(EINVAL)?;
589         req.address = addr;
590         req.on_write = on_write;
591 
592         self.main_transaction(&r, &[])?;
593         Ok(())
594     }
595 
get_state( &mut self, state_set: MainRequest_StateSet, out: &mut [u8], ) -> result::Result<(), c_int>596     fn get_state(
597         &mut self,
598         state_set: MainRequest_StateSet,
599         out: &mut [u8],
600     ) -> result::Result<(), c_int> {
601         let mut r = MainRequest::new();
602         r.mut_get_state().set = state_set;
603         let (response, _) = self.main_transaction(&r, &[])?;
604         if !response.has_get_state() {
605             return Err(EPROTO);
606         }
607         let get_state: &MainResponse_GetState = response.get_get_state();
608         if get_state.state.len() != out.len() {
609             return Err(EPROTO);
610         }
611         out.copy_from_slice(&get_state.state);
612         Ok(())
613     }
614 
set_state( &mut self, state_set: MainRequest_StateSet, new_state: &[u8], ) -> result::Result<(), c_int>615     fn set_state(
616         &mut self,
617         state_set: MainRequest_StateSet,
618         new_state: &[u8],
619     ) -> result::Result<(), c_int> {
620         let mut r = MainRequest::new();
621         let set_state: &mut MainRequest_SetState = r.mut_set_state();
622         set_state.set = state_set;
623         set_state.state = new_state.to_vec();
624 
625         self.main_transaction(&r, &[])?;
626         Ok(())
627     }
628 
set_identity_map_addr(&mut self, addr: u32) -> result::Result<(), c_int>629     fn set_identity_map_addr(&mut self, addr: u32) -> result::Result<(), c_int> {
630         let mut r = MainRequest::new();
631         r.mut_set_identity_map_addr().address = addr;
632 
633         self.main_transaction(&r, &[])?;
634         Ok(())
635     }
636 
pause_vcpus(&mut self, cpu_mask: u64, user: *mut c_void) -> result::Result<(), c_int>637     fn pause_vcpus(&mut self, cpu_mask: u64, user: *mut c_void) -> result::Result<(), c_int> {
638         let mut r = MainRequest::new();
639         let pause_vcpus: &mut MainRequest_PauseVcpus = r.mut_pause_vcpus();
640         pause_vcpus.cpu_mask = cpu_mask;
641         pause_vcpus.user = user as u64;
642         self.main_transaction(&r, &[])?;
643         Ok(())
644     }
645 
start(&mut self) -> result::Result<(), c_int>646     fn start(&mut self) -> result::Result<(), c_int> {
647         let mut r = MainRequest::new();
648         r.mut_start();
649         self.main_transaction(&r, &[])?;
650         Ok(())
651     }
652 
get_vcpu(&mut self, cpu_id: u32) -> Result<*mut crosvm_vcpu, c_int>653     fn get_vcpu(&mut self, cpu_id: u32) -> Result<*mut crosvm_vcpu, c_int> {
654         if let Some(vcpu) = self.vcpus.get(cpu_id as usize) {
655             Ok(vcpu as *const crosvm_vcpu as *mut crosvm_vcpu)
656         } else {
657             Err(ENOENT)
658         }
659     }
660 
get_net_config(&mut self) -> result::Result<crosvm_net_config, c_int>661     fn get_net_config(&mut self) -> result::Result<crosvm_net_config, c_int> {
662         let mut r = MainRequest::new();
663         r.mut_get_net_config();
664 
665         let (response, mut files) = self.main_transaction(&r, &[])?;
666         if !response.has_get_net_config() {
667             return Err(EPROTO);
668         }
669         let config = response.get_get_net_config();
670 
671         match files.pop() {
672             Some(f) => {
673                 let mut net_config = crosvm_net_config {
674                     tap_fd: f.into_raw_fd(),
675                     host_ipv4_address: config.host_ipv4_address,
676                     netmask: config.netmask,
677                     host_mac_address: [0; 6],
678                     _reserved: [0; 2],
679                 };
680 
681                 let mac_addr = config.get_host_mac_address();
682                 if mac_addr.len() != net_config.host_mac_address.len() {
683                     return Err(EPROTO);
684                 }
685                 net_config.host_mac_address.copy_from_slice(mac_addr);
686 
687                 Ok(net_config)
688             }
689             None => Err(EPROTO),
690         }
691     }
692 }
693 
694 /// This helper macro implements the C API's constructor/destructor for a given type. Because they
695 /// all follow the same pattern and include lots of boilerplate unsafe code, it makes sense to write
696 /// it once with this helper macro.
697 macro_rules! impl_ctor_dtor {
698     (
699         $t:ident,
700         $ctor:ident ( $( $x:ident: $y:ty ),* ),
701         $dtor:ident,
702     ) => {
703         #[allow(unused_unsafe)]
704         #[no_mangle]
705         pub unsafe extern fn $ctor(self_: *mut crosvm, $($x: $y,)* obj_ptr: *mut *mut $t) -> c_int {
706             let self_ = &mut (*self_);
707             match $t::create(self_, $($x,)*) {
708                 Ok(obj) => {
709                     *obj_ptr = Box::into_raw(Box::new(obj));
710                     0
711                 }
712                 Err(e) => -e,
713             }
714         }
715         #[no_mangle]
716         pub unsafe extern fn $dtor(self_: *mut crosvm, obj_ptr: *mut *mut $t) -> c_int {
717             let self_ = &mut (*self_);
718             let obj = Box::from_raw(*obj_ptr);
719             match self_.destroy(obj.id) {
720                 Ok(_) => {
721                     *obj_ptr = null_mut();
722                     0
723                 }
724                 Err(e) =>  {
725                     Box::into_raw(obj);
726                     -e
727                 }
728             }
729         }
730     }
731 }
732 
733 pub struct crosvm_io_event {
734     id: u32,
735     evt: File,
736 }
737 
738 impl crosvm_io_event {
739     // Clippy: we use ptr::read_unaligned to read from pointers that may be
740     // underaligned. Dereferencing such a pointer is always undefined behavior
741     // in Rust.
742     //
743     // Lint can be unsuppressed once Clippy recognizes this pattern as correct.
744     // https://github.com/rust-lang/rust-clippy/issues/2881
745     #[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>746     unsafe fn create(
747         crosvm: &mut crosvm,
748         space: u32,
749         addr: u64,
750         length: u32,
751         datamatch: *const u8,
752     ) -> result::Result<crosvm_io_event, c_int> {
753         let datamatch = match length {
754             0 => 0,
755             1 => ptr::read_unaligned(datamatch as *const u8) as u64,
756             2 => ptr::read_unaligned(datamatch as *const u16) as u64,
757             4 => ptr::read_unaligned(datamatch as *const u32) as u64,
758             8 => ptr::read_unaligned(datamatch as *const u64),
759             _ => return Err(EINVAL),
760         };
761         Self::safe_create(crosvm, space, addr, length, datamatch)
762     }
763 
safe_create( crosvm: &mut crosvm, space: u32, addr: u64, length: u32, datamatch: u64, ) -> result::Result<crosvm_io_event, c_int>764     fn safe_create(
765         crosvm: &mut crosvm,
766         space: u32,
767         addr: u64,
768         length: u32,
769         datamatch: u64,
770     ) -> result::Result<crosvm_io_event, c_int> {
771         let id = crosvm.get_id_allocator().alloc();
772 
773         let mut r = MainRequest::new();
774         let create: &mut MainRequest_Create = r.mut_create();
775         create.id = id;
776         let io_event: &mut MainRequest_Create_IoEvent = create.mut_io_event();
777         io_event.space = AddressSpace::from_i32(space as i32).ok_or(EINVAL)?;
778         io_event.address = addr;
779         io_event.length = length;
780         io_event.datamatch = datamatch;
781 
782         let ret = match crosvm.main_transaction(&r, &[]) {
783             Ok((_, mut files)) => match files.pop() {
784                 Some(evt) => return Ok(crosvm_io_event { id, evt }),
785                 None => EPROTO,
786             },
787             Err(e) => e,
788         };
789         crosvm.get_id_allocator().free(id);
790         Err(ret)
791     }
792 }
793 
794 impl_ctor_dtor!(
795     crosvm_io_event,
796     crosvm_create_io_event(space: u32, addr: u64, len: u32, datamatch: *const u8),
797     crosvm_destroy_io_event,
798 );
799 
800 #[no_mangle]
crosvm_io_event_fd(this: *mut crosvm_io_event) -> c_int801 pub unsafe extern "C" fn crosvm_io_event_fd(this: *mut crosvm_io_event) -> c_int {
802     let _u = record(Stat::IoEvent);
803     (*this).evt.as_raw_fd()
804 }
805 
806 pub struct crosvm_memory {
807     id: u32,
808     length: u64,
809 }
810 
811 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>812     fn create(
813         crosvm: &mut crosvm,
814         fd: c_int,
815         offset: u64,
816         length: u64,
817         start: u64,
818         read_only: bool,
819         dirty_log: bool,
820     ) -> result::Result<crosvm_memory, c_int> {
821         const PAGE_MASK: u64 = 0x0fff;
822         if offset & PAGE_MASK != 0 || length & PAGE_MASK != 0 {
823             return Err(EINVAL);
824         }
825         let id = crosvm.get_id_allocator().alloc();
826 
827         let mut r = MainRequest::new();
828         let create: &mut MainRequest_Create = r.mut_create();
829         create.id = id;
830         let memory: &mut MainRequest_Create_Memory = create.mut_memory();
831         memory.offset = offset;
832         memory.start = start;
833         memory.length = length;
834         memory.read_only = read_only;
835         memory.dirty_log = dirty_log;
836 
837         let ret = match crosvm.main_transaction(&r, &[fd]) {
838             Ok(_) => return Ok(crosvm_memory { id, length }),
839             Err(e) => e,
840         };
841         crosvm.get_id_allocator().free(id);
842         Err(ret)
843     }
844 
get_dirty_log(&mut self, crosvm: &mut crosvm) -> result::Result<Vec<u8>, c_int>845     fn get_dirty_log(&mut self, crosvm: &mut crosvm) -> result::Result<Vec<u8>, c_int> {
846         let mut r = MainRequest::new();
847         r.mut_dirty_log().id = self.id;
848         let (mut response, _) = crosvm.main_transaction(&r, &[])?;
849         if !response.has_dirty_log() {
850             return Err(EPROTO);
851         }
852         Ok(response.take_dirty_log().bitmap)
853     }
854 }
855 
856 impl_ctor_dtor!(
857     crosvm_memory,
858     crosvm_create_memory(
859         fd: c_int,
860         offset: u64,
861         length: u64,
862         start: u64,
863         read_only: bool,
864         dirty_log: bool
865     ),
866     crosvm_destroy_memory,
867 );
868 
869 #[no_mangle]
crosvm_memory_get_dirty_log( crosvm: *mut crosvm, this: *mut crosvm_memory, log: *mut u8, ) -> c_int870 pub unsafe extern "C" fn crosvm_memory_get_dirty_log(
871     crosvm: *mut crosvm,
872     this: *mut crosvm_memory,
873     log: *mut u8,
874 ) -> c_int {
875     let _u = record(Stat::MemoryGetDirtyLog);
876     let crosvm = &mut *crosvm;
877     let this = &mut *this;
878     let log_slice = slice::from_raw_parts_mut(log, dirty_log_bitmap_size(this.length as usize));
879     match this.get_dirty_log(crosvm) {
880         Ok(bitmap) => {
881             if bitmap.len() == log_slice.len() {
882                 log_slice.copy_from_slice(&bitmap);
883                 0
884             } else {
885                 -EPROTO
886             }
887         }
888         Err(e) => -e,
889     }
890 }
891 
892 pub struct crosvm_irq_event {
893     id: u32,
894     trigger_evt: File,
895     resample_evt: File,
896 }
897 
898 impl crosvm_irq_event {
create(crosvm: &mut crosvm, irq_id: u32) -> result::Result<crosvm_irq_event, c_int>899     fn create(crosvm: &mut crosvm, irq_id: u32) -> result::Result<crosvm_irq_event, c_int> {
900         let id = crosvm.get_id_allocator().alloc();
901 
902         let mut r = MainRequest::new();
903         let create: &mut MainRequest_Create = r.mut_create();
904         create.id = id;
905         let irq_event: &mut MainRequest_Create_IrqEvent = create.mut_irq_event();
906         irq_event.irq_id = irq_id;
907         irq_event.resample = true;
908 
909         let ret = match crosvm.main_transaction(&r, &[]) {
910             Ok((_, mut files)) => {
911                 if files.len() >= 2 {
912                     let resample_evt = files.pop().unwrap();
913                     let trigger_evt = files.pop().unwrap();
914                     return Ok(crosvm_irq_event {
915                         id,
916                         trigger_evt,
917                         resample_evt,
918                     });
919                 }
920                 EPROTO
921             }
922             Err(e) => e,
923         };
924         crosvm.get_id_allocator().free(id);
925         Err(ret)
926     }
927 }
928 
929 impl_ctor_dtor!(
930     crosvm_irq_event,
931     crosvm_create_irq_event(irq_id: u32),
932     crosvm_destroy_irq_event,
933 );
934 
935 #[no_mangle]
crosvm_irq_event_get_fd(this: *mut crosvm_irq_event) -> c_int936 pub unsafe extern "C" fn crosvm_irq_event_get_fd(this: *mut crosvm_irq_event) -> c_int {
937     let _u = record(Stat::IrqEventGetFd);
938     (*this).trigger_evt.as_raw_fd()
939 }
940 
941 #[no_mangle]
crosvm_irq_event_get_resample_fd(this: *mut crosvm_irq_event) -> c_int942 pub unsafe extern "C" fn crosvm_irq_event_get_resample_fd(this: *mut crosvm_irq_event) -> c_int {
943     let _u = record(Stat::IrqEventGetResampleFd);
944     (*this).resample_evt.as_raw_fd()
945 }
946 
947 #[allow(dead_code)]
948 #[derive(Copy, Clone)]
949 #[repr(C)]
950 struct anon_io_access {
951     address_space: u32,
952     __reserved0: [u8; 4],
953     address: u64,
954     data: *mut u8,
955     length: u32,
956     is_write: u8,
957     no_resume: u8,
958     __reserved1: [u8; 2],
959 }
960 
961 #[derive(Copy, Clone)]
962 #[repr(C)]
963 struct anon_hyperv_call {
964     input: u64,
965     result: *mut u8,
966     params: [u64; 2],
967 }
968 
969 #[derive(Copy, Clone)]
970 #[repr(C)]
971 struct anon_hyperv_synic {
972     msr: u32,
973     reserved: u32,
974     control: u64,
975     evt_page: u64,
976     msg_page: u64,
977 }
978 
979 #[repr(C)]
980 union anon_vcpu_event {
981     io_access: anon_io_access,
982     user: *mut c_void,
983     hyperv_call: anon_hyperv_call,
984     hyperv_synic: anon_hyperv_synic,
985     #[allow(dead_code)]
986     __reserved: [u8; 64],
987 }
988 
989 #[repr(C)]
990 pub struct crosvm_vcpu_event {
991     kind: u32,
992     __reserved: [u8; 4],
993     event: anon_vcpu_event,
994 }
995 
996 // |get| tracks if the |cache| contains a cached value that can service get()
997 // requests.  A set() call will populate |cache| and |set| to true to record
998 // that the next resume() should apply the state.  We've got two choices on
999 // what to do about |get| on a set(): 1) leave it as true, or 2) clear it and
1000 // have any call to get() first apply any pending set.  Currently #2 is used
1001 // to favor correctness over performance (it gives KVM a chance to
1002 // modify/massage the values input to the set call). A plugin will rarely
1003 // (if ever) issue a get() after a set() on the same vcpu exit, so opting for
1004 // #1 is unlikely to provide a tangible performance gain.
1005 pub struct crosvm_vcpu_reg_cache {
1006     get: bool,
1007     set: bool,
1008     cache: Vec<u8>,
1009 }
1010 
1011 pub struct crosvm_vcpu {
1012     read_pipe: File,
1013     write_pipe: File,
1014     send_init: bool,
1015     request_buffer: Vec<u8>,
1016     response_buffer: Vec<u8>,
1017     response_base: usize,
1018     response_length: usize,
1019     resume_data: Vec<u8>,
1020 
1021     regs: crosvm_vcpu_reg_cache,
1022     sregs: crosvm_vcpu_reg_cache,
1023     debugregs: crosvm_vcpu_reg_cache,
1024 }
1025 
read_varint32(data: &[u8]) -> (u32, usize)1026 fn read_varint32(data: &[u8]) -> (u32, usize) {
1027     let mut value: u32 = 0;
1028     let mut shift: u32 = 0;
1029     for (i, &b) in data.iter().enumerate() {
1030         if b < 0x80 {
1031             return match (b as u32).checked_shl(shift) {
1032                 None => (0, 0),
1033                 Some(b) => (value | b, i + 1),
1034             };
1035         }
1036         match ((b as u32) & 0x7F).checked_shl(shift) {
1037             None => return (0, 0),
1038             Some(b) => value |= b,
1039         }
1040         shift += 7;
1041     }
1042     (0, 0)
1043 }
1044 
1045 impl crosvm_vcpu {
new(read_pipe: File, write_pipe: File) -> crosvm_vcpu1046     fn new(read_pipe: File, write_pipe: File) -> crosvm_vcpu {
1047         crosvm_vcpu {
1048             read_pipe,
1049             write_pipe,
1050             send_init: true,
1051             request_buffer: Vec::new(),
1052             response_buffer: vec![0; MAX_DATAGRAM_SIZE],
1053             response_base: 0,
1054             response_length: 0,
1055             resume_data: Vec::new(),
1056             regs: crosvm_vcpu_reg_cache {
1057                 get: false,
1058                 set: false,
1059                 cache: vec![],
1060             },
1061             sregs: crosvm_vcpu_reg_cache {
1062                 get: false,
1063                 set: false,
1064                 cache: vec![],
1065             },
1066             debugregs: crosvm_vcpu_reg_cache {
1067                 get: false,
1068                 set: false,
1069                 cache: vec![],
1070             },
1071         }
1072     }
vcpu_send(&mut self, request: &VcpuRequest) -> result::Result<(), c_int>1073     fn vcpu_send(&mut self, request: &VcpuRequest) -> result::Result<(), c_int> {
1074         self.request_buffer.clear();
1075         request
1076             .write_to_vec(&mut self.request_buffer)
1077             .map_err(proto_error_to_int)?;
1078         self.write_pipe
1079             .write(self.request_buffer.as_slice())
1080             .map_err(|e| -e.raw_os_error().unwrap_or(EINVAL))?;
1081         Ok(())
1082     }
1083 
vcpu_recv(&mut self) -> result::Result<VcpuResponse, c_int>1084     fn vcpu_recv(&mut self) -> result::Result<VcpuResponse, c_int> {
1085         if self.response_length == 0 {
1086             let msg_size = self
1087                 .read_pipe
1088                 .read(&mut self.response_buffer)
1089                 .map_err(|e| -e.raw_os_error().unwrap_or(EINVAL))?;
1090             self.response_base = 0;
1091             self.response_length = msg_size;
1092         }
1093         if self.response_length == 0 {
1094             return Err(EINVAL);
1095         }
1096         let (value, bytes) = read_varint32(
1097             &self.response_buffer[self.response_base..self.response_base + self.response_length],
1098         );
1099         let total_size: usize = bytes + value as usize;
1100         if bytes == 0 || total_size > self.response_length {
1101             return Err(EINVAL);
1102         }
1103         let response: VcpuResponse = Message::parse_from_bytes(
1104             &self.response_buffer[self.response_base + bytes..self.response_base + total_size],
1105         )
1106         .map_err(proto_error_to_int)?;
1107         self.response_base += total_size;
1108         self.response_length -= total_size;
1109         if response.errno != 0 {
1110             return Err(response.errno);
1111         }
1112         Ok(response)
1113     }
1114 
vcpu_transaction(&mut self, request: &VcpuRequest) -> result::Result<VcpuResponse, c_int>1115     fn vcpu_transaction(&mut self, request: &VcpuRequest) -> result::Result<VcpuResponse, c_int> {
1116         self.vcpu_send(request)?;
1117         let response: VcpuResponse = self.vcpu_recv()?;
1118         Ok(response)
1119     }
1120 
wait(&mut self, event: &mut crosvm_vcpu_event) -> result::Result<(), c_int>1121     fn wait(&mut self, event: &mut crosvm_vcpu_event) -> result::Result<(), c_int> {
1122         if self.send_init {
1123             self.send_init = false;
1124             let mut r = VcpuRequest::new();
1125             r.mut_wait();
1126             self.vcpu_send(&r)?;
1127         }
1128         let mut response: VcpuResponse = self.vcpu_recv()?;
1129         if !response.has_wait() {
1130             return Err(EPROTO);
1131         }
1132         let wait: &mut VcpuResponse_Wait = response.mut_wait();
1133         if wait.has_init() {
1134             event.kind = CROSVM_VCPU_EVENT_KIND_INIT;
1135             self.regs.get = false;
1136             self.sregs.get = false;
1137             self.debugregs.get = false;
1138             Ok(())
1139         } else if wait.has_io() {
1140             let mut io: VcpuResponse_Wait_Io = wait.take_io();
1141             event.kind = CROSVM_VCPU_EVENT_KIND_IO_ACCESS;
1142             event.event.io_access = anon_io_access {
1143                 address_space: io.space.value() as u32,
1144                 __reserved0: Default::default(),
1145                 address: io.address,
1146                 data: io.data.as_mut_ptr(),
1147                 length: io.data.len() as u32,
1148                 is_write: io.is_write as u8,
1149                 no_resume: io.no_resume as u8,
1150                 __reserved1: Default::default(),
1151             };
1152             self.resume_data = io.data;
1153             self.regs.get = !io.regs.is_empty();
1154             if self.regs.get {
1155                 swap(&mut self.regs.cache, &mut io.regs);
1156             }
1157             self.sregs.get = !io.sregs.is_empty();
1158             if self.sregs.get {
1159                 swap(&mut self.sregs.cache, &mut io.sregs);
1160             }
1161             self.debugregs.get = !io.debugregs.is_empty();
1162             if self.debugregs.get {
1163                 swap(&mut self.debugregs.cache, &mut io.debugregs);
1164             }
1165             Ok(())
1166         } else if wait.has_user() {
1167             let user: &VcpuResponse_Wait_User = wait.get_user();
1168             event.kind = CROSVM_VCPU_EVENT_KIND_PAUSED;
1169             event.event.user = user.user as *mut c_void;
1170             self.regs.get = false;
1171             self.sregs.get = false;
1172             self.debugregs.get = false;
1173             Ok(())
1174         } else if wait.has_hyperv_call() {
1175             let hv: &VcpuResponse_Wait_HypervCall = wait.get_hyperv_call();
1176             event.kind = CROSVM_VCPU_EVENT_KIND_HYPERV_HCALL;
1177             self.resume_data = vec![0; 8];
1178             event.event.hyperv_call = anon_hyperv_call {
1179                 input: hv.input,
1180                 result: self.resume_data.as_mut_ptr(),
1181                 params: [hv.params0, hv.params1],
1182             };
1183             self.regs.get = false;
1184             self.sregs.get = false;
1185             self.debugregs.get = false;
1186             Ok(())
1187         } else if wait.has_hyperv_synic() {
1188             let hv: &VcpuResponse_Wait_HypervSynic = wait.get_hyperv_synic();
1189             event.kind = CROSVM_VCPU_EVENT_KIND_HYPERV_SYNIC;
1190             event.event.hyperv_synic = anon_hyperv_synic {
1191                 msr: hv.msr,
1192                 reserved: 0,
1193                 control: hv.control,
1194                 evt_page: hv.evt_page,
1195                 msg_page: hv.msg_page,
1196             };
1197             self.regs.get = false;
1198             self.sregs.get = false;
1199             self.debugregs.get = false;
1200             Ok(())
1201         } else {
1202             Err(EPROTO)
1203         }
1204     }
1205 
resume(&mut self) -> result::Result<(), c_int>1206     fn resume(&mut self) -> result::Result<(), c_int> {
1207         let mut r = VcpuRequest::new();
1208         let resume: &mut VcpuRequest_Resume = r.mut_resume();
1209         swap(&mut resume.data, &mut self.resume_data);
1210 
1211         if self.regs.set {
1212             swap(&mut resume.regs, &mut self.regs.cache);
1213             self.regs.set = false;
1214         }
1215         if self.sregs.set {
1216             swap(&mut resume.sregs, &mut self.sregs.cache);
1217             self.sregs.set = false;
1218         }
1219         if self.debugregs.set {
1220             swap(&mut resume.debugregs, &mut self.debugregs.cache);
1221             self.debugregs.set = false;
1222         }
1223 
1224         self.vcpu_send(&r)?;
1225         Ok(())
1226     }
1227 
get_state( &mut self, state_set: VcpuRequest_StateSet, out: &mut [u8], ) -> result::Result<(), c_int>1228     fn get_state(
1229         &mut self,
1230         state_set: VcpuRequest_StateSet,
1231         out: &mut [u8],
1232     ) -> result::Result<(), c_int> {
1233         let mut r = VcpuRequest::new();
1234         r.mut_get_state().set = state_set;
1235         let response = self.vcpu_transaction(&r)?;
1236         if !response.has_get_state() {
1237             return Err(EPROTO);
1238         }
1239         let get_state: &VcpuResponse_GetState = response.get_get_state();
1240         if get_state.state.len() != out.len() {
1241             return Err(EPROTO);
1242         }
1243         out.copy_from_slice(&get_state.state);
1244         Ok(())
1245     }
1246 
set_state( &mut self, state_set: VcpuRequest_StateSet, new_state: &[u8], ) -> result::Result<(), c_int>1247     fn set_state(
1248         &mut self,
1249         state_set: VcpuRequest_StateSet,
1250         new_state: &[u8],
1251     ) -> result::Result<(), c_int> {
1252         let mut r = VcpuRequest::new();
1253         let set_state: &mut VcpuRequest_SetState = r.mut_set_state();
1254         set_state.set = state_set;
1255         set_state.state = new_state.to_vec();
1256 
1257         self.vcpu_transaction(&r)?;
1258         Ok(())
1259     }
1260 
set_state_from_cache( &mut self, state_set: VcpuRequest_StateSet, ) -> result::Result<(), c_int>1261     fn set_state_from_cache(
1262         &mut self,
1263         state_set: VcpuRequest_StateSet,
1264     ) -> result::Result<(), c_int> {
1265         let mut r = VcpuRequest::new();
1266         let set_state: &mut VcpuRequest_SetState = r.mut_set_state();
1267         set_state.set = state_set;
1268         match state_set {
1269             VcpuRequest_StateSet::REGS => {
1270                 swap(&mut set_state.state, &mut self.regs.cache);
1271                 self.regs.set = false;
1272             }
1273             VcpuRequest_StateSet::SREGS => {
1274                 swap(&mut set_state.state, &mut self.sregs.cache);
1275                 self.sregs.set = false;
1276             }
1277             VcpuRequest_StateSet::DEBUGREGS => {
1278                 swap(&mut set_state.state, &mut self.debugregs.cache);
1279                 self.debugregs.set = false;
1280             }
1281             _ => return Err(EINVAL),
1282         }
1283 
1284         self.vcpu_transaction(&r)?;
1285         Ok(())
1286     }
1287 
get_hyperv_cpuid( &mut self, cpuid_entries: &mut [kvm_cpuid_entry2], cpuid_count: &mut usize, ) -> result::Result<(), c_int>1288     fn get_hyperv_cpuid(
1289         &mut self,
1290         cpuid_entries: &mut [kvm_cpuid_entry2],
1291         cpuid_count: &mut usize,
1292     ) -> result::Result<(), c_int> {
1293         *cpuid_count = 0;
1294 
1295         let mut r = VcpuRequest::new();
1296         r.mut_get_hyperv_cpuid();
1297 
1298         let response = self.vcpu_transaction(&r)?;
1299         if !response.has_get_hyperv_cpuid() {
1300             return Err(EPROTO);
1301         }
1302 
1303         let hyperv_cpuids: &VcpuResponse_CpuidResponse = response.get_get_hyperv_cpuid();
1304 
1305         *cpuid_count = hyperv_cpuids.get_entries().len();
1306         if *cpuid_count > cpuid_entries.len() {
1307             return Err(E2BIG);
1308         }
1309 
1310         for (proto_entry, kvm_entry) in hyperv_cpuids
1311             .get_entries()
1312             .iter()
1313             .zip(cpuid_entries.iter_mut())
1314         {
1315             *kvm_entry = cpuid_proto_to_kvm(proto_entry);
1316         }
1317 
1318         Ok(())
1319     }
1320 
get_msrs( &mut self, msr_entries: &mut [kvm_msr_entry], msr_count: &mut usize, ) -> result::Result<(), c_int>1321     fn get_msrs(
1322         &mut self,
1323         msr_entries: &mut [kvm_msr_entry],
1324         msr_count: &mut usize,
1325     ) -> result::Result<(), c_int> {
1326         *msr_count = 0;
1327 
1328         let mut r = VcpuRequest::new();
1329         let entry_indices: &mut Vec<u32> = r.mut_get_msrs().mut_entry_indices();
1330         for entry in msr_entries.iter() {
1331             entry_indices.push(entry.index);
1332         }
1333 
1334         let response = self.vcpu_transaction(&r)?;
1335         if !response.has_get_msrs() {
1336             return Err(EPROTO);
1337         }
1338         let get_msrs: &VcpuResponse_GetMsrs = response.get_get_msrs();
1339         *msr_count = get_msrs.get_entry_data().len();
1340         if *msr_count > msr_entries.len() {
1341             return Err(E2BIG);
1342         }
1343         for (&msr_data, msr_entry) in get_msrs.get_entry_data().iter().zip(msr_entries) {
1344             msr_entry.data = msr_data;
1345         }
1346         Ok(())
1347     }
1348 
set_msrs(&mut self, msr_entries: &[kvm_msr_entry]) -> result::Result<(), c_int>1349     fn set_msrs(&mut self, msr_entries: &[kvm_msr_entry]) -> result::Result<(), c_int> {
1350         let mut r = VcpuRequest::new();
1351         let set_msrs_entries: &mut RepeatedField<VcpuRequest_MsrEntry> =
1352             r.mut_set_msrs().mut_entries();
1353         for msr_entry in msr_entries {
1354             let mut entry = VcpuRequest_MsrEntry::new();
1355             entry.index = msr_entry.index;
1356             entry.data = msr_entry.data;
1357             set_msrs_entries.push(entry);
1358         }
1359 
1360         self.vcpu_transaction(&r)?;
1361         Ok(())
1362     }
1363 
set_cpuid(&mut self, cpuid_entries: &[kvm_cpuid_entry2]) -> result::Result<(), c_int>1364     fn set_cpuid(&mut self, cpuid_entries: &[kvm_cpuid_entry2]) -> result::Result<(), c_int> {
1365         let mut r = VcpuRequest::new();
1366         let set_cpuid_entries: &mut RepeatedField<CpuidEntry> = r.mut_set_cpuid().mut_entries();
1367         for cpuid_entry in cpuid_entries {
1368             set_cpuid_entries.push(cpuid_kvm_to_proto(cpuid_entry));
1369         }
1370 
1371         self.vcpu_transaction(&r)?;
1372         Ok(())
1373     }
1374 
enable_capability(&mut self, capability: u32) -> result::Result<(), c_int>1375     fn enable_capability(&mut self, capability: u32) -> result::Result<(), c_int> {
1376         let mut r = VcpuRequest::new();
1377         r.mut_enable_capability().capability = capability;
1378         self.vcpu_transaction(&r)?;
1379         Ok(())
1380     }
1381 }
1382 
1383 // crosvm API signals success as 0 and errors as negative values
1384 // derived from `errno`.
to_crosvm_rc<T>(r: result::Result<T, c_int>) -> c_int1385 fn to_crosvm_rc<T>(r: result::Result<T, c_int>) -> c_int {
1386     match r {
1387         Ok(_) => 0,
1388         Err(e) => -e,
1389     }
1390 }
1391 
1392 #[no_mangle]
crosvm_connect(out: *mut *mut crosvm) -> c_int1393 pub unsafe extern "C" fn crosvm_connect(out: *mut *mut crosvm) -> c_int {
1394     let _u = record(Stat::Connect);
1395     let socket_name = match env::var(CROSVM_SOCKET_ENV) {
1396         Ok(v) => v,
1397         _ => return -ENOTCONN,
1398     };
1399 
1400     let socket = match socket_name.parse() {
1401         Ok(v) if v < 0 => return -EINVAL,
1402         Ok(v) => v,
1403         _ => return -EINVAL,
1404     };
1405 
1406     let socket = UnixDatagram::from_raw_fd(socket);
1407     let crosvm = match crosvm::from_connection(socket) {
1408         Ok(c) => c,
1409         Err(e) => return -e,
1410     };
1411     *out = Box::into_raw(Box::new(crosvm));
1412     0
1413 }
1414 
1415 #[no_mangle]
crosvm_new_connection(self_: *mut crosvm, out: *mut *mut crosvm) -> c_int1416 pub unsafe extern "C" fn crosvm_new_connection(self_: *mut crosvm, out: *mut *mut crosvm) -> c_int {
1417     let _u = record(Stat::NewConnection);
1418     let self_ = &mut (*self_);
1419     match self_.try_clone() {
1420         Ok(cloned) => {
1421             *out = Box::into_raw(Box::new(cloned));
1422             0
1423         }
1424         Err(e) => -e,
1425     }
1426 }
1427 
1428 #[no_mangle]
crosvm_destroy_connection(self_: *mut *mut crosvm) -> c_int1429 pub unsafe extern "C" fn crosvm_destroy_connection(self_: *mut *mut crosvm) -> c_int {
1430     let _u = record(Stat::DestroyConnection);
1431     drop(Box::from_raw(*self_));
1432     *self_ = null_mut();
1433     0
1434 }
1435 
1436 #[no_mangle]
crosvm_get_shutdown_eventfd(self_: *mut crosvm) -> c_int1437 pub unsafe extern "C" fn crosvm_get_shutdown_eventfd(self_: *mut crosvm) -> c_int {
1438     let _u = record(Stat::GetShutdownEvent);
1439     let self_ = &mut (*self_);
1440     match self_.get_shutdown_event() {
1441         Ok(f) => f.into_raw_fd(),
1442         Err(e) => -e,
1443     }
1444 }
1445 
1446 #[no_mangle]
crosvm_check_extension( self_: *mut crosvm, extension: u32, has_extension: *mut bool, ) -> c_int1447 pub unsafe extern "C" fn crosvm_check_extension(
1448     self_: *mut crosvm,
1449     extension: u32,
1450     has_extension: *mut bool,
1451 ) -> c_int {
1452     let _u = record(Stat::CheckExtentsion);
1453     let self_ = &mut (*self_);
1454     let ret = self_.check_extension(extension);
1455 
1456     if let Ok(supported) = ret {
1457         *has_extension = supported;
1458     }
1459     to_crosvm_rc(ret)
1460 }
1461 
1462 #[no_mangle]
crosvm_enable_capability( _self_: *mut crosvm, _capability: u32, _flags: u32, _args: *const u64, ) -> c_int1463 pub unsafe extern "C" fn crosvm_enable_capability(
1464     _self_: *mut crosvm,
1465     _capability: u32,
1466     _flags: u32,
1467     _args: *const u64,
1468 ) -> c_int {
1469     let _u = record(Stat::EnableVmCapability);
1470     -EINVAL
1471 }
1472 
1473 #[no_mangle]
crosvm_get_supported_cpuid( this: *mut crosvm, entry_count: u32, cpuid_entries: *mut kvm_cpuid_entry2, out_count: *mut u32, ) -> c_int1474 pub unsafe extern "C" fn crosvm_get_supported_cpuid(
1475     this: *mut crosvm,
1476     entry_count: u32,
1477     cpuid_entries: *mut kvm_cpuid_entry2,
1478     out_count: *mut u32,
1479 ) -> c_int {
1480     let _u = record(Stat::GetSupportedCpuid);
1481     let this = &mut *this;
1482     let cpuid_entries = from_raw_parts_mut(cpuid_entries, entry_count as usize);
1483     let mut cpuid_count: usize = 0;
1484     let ret = this.get_supported_cpuid(cpuid_entries, &mut cpuid_count);
1485     *out_count = cpuid_count as u32;
1486     to_crosvm_rc(ret)
1487 }
1488 
1489 #[no_mangle]
crosvm_get_emulated_cpuid( this: *mut crosvm, entry_count: u32, cpuid_entries: *mut kvm_cpuid_entry2, out_count: *mut u32, ) -> c_int1490 pub unsafe extern "C" fn crosvm_get_emulated_cpuid(
1491     this: *mut crosvm,
1492     entry_count: u32,
1493     cpuid_entries: *mut kvm_cpuid_entry2,
1494     out_count: *mut u32,
1495 ) -> c_int {
1496     let _u = record(Stat::GetEmulatedCpuid);
1497     let this = &mut *this;
1498     let cpuid_entries = from_raw_parts_mut(cpuid_entries, entry_count as usize);
1499     let mut cpuid_count: usize = 0;
1500     let ret = this.get_emulated_cpuid(cpuid_entries, &mut cpuid_count);
1501     *out_count = cpuid_count as u32;
1502     to_crosvm_rc(ret)
1503 }
1504 
1505 #[no_mangle]
crosvm_get_msr_index_list( this: *mut crosvm, entry_count: u32, msr_indices: *mut u32, out_count: *mut u32, ) -> c_int1506 pub unsafe extern "C" fn crosvm_get_msr_index_list(
1507     this: *mut crosvm,
1508     entry_count: u32,
1509     msr_indices: *mut u32,
1510     out_count: *mut u32,
1511 ) -> c_int {
1512     let _u = record(Stat::GetMsrIndexList);
1513     let this = &mut *this;
1514     let msr_indices = from_raw_parts_mut(msr_indices, entry_count as usize);
1515     let mut msr_count: usize = 0;
1516     let ret = this.get_msr_index_list(msr_indices, &mut msr_count);
1517     *out_count = msr_count as u32;
1518     to_crosvm_rc(ret)
1519 }
1520 
1521 #[no_mangle]
crosvm_net_get_config( self_: *mut crosvm, config: *mut crosvm_net_config, ) -> c_int1522 pub unsafe extern "C" fn crosvm_net_get_config(
1523     self_: *mut crosvm,
1524     config: *mut crosvm_net_config,
1525 ) -> c_int {
1526     let _u = record(Stat::NetGetConfig);
1527     let self_ = &mut (*self_);
1528     let ret = self_.get_net_config();
1529 
1530     if let Ok(c) = ret {
1531         *config = c;
1532     }
1533 
1534     to_crosvm_rc(ret)
1535 }
1536 
1537 #[no_mangle]
crosvm_reserve_range( self_: *mut crosvm, space: u32, start: u64, length: u64, ) -> c_int1538 pub unsafe extern "C" fn crosvm_reserve_range(
1539     self_: *mut crosvm,
1540     space: u32,
1541     start: u64,
1542     length: u64,
1543 ) -> c_int {
1544     let _u = record(Stat::ReserveRange);
1545     let self_ = &mut (*self_);
1546     let ret = self_.reserve_range(space, start, length, false);
1547     to_crosvm_rc(ret)
1548 }
1549 
1550 #[no_mangle]
crosvm_reserve_async_write_range( self_: *mut crosvm, space: u32, start: u64, length: u64, ) -> c_int1551 pub unsafe extern "C" fn crosvm_reserve_async_write_range(
1552     self_: *mut crosvm,
1553     space: u32,
1554     start: u64,
1555     length: u64,
1556 ) -> c_int {
1557     let _u = record(Stat::ReserveAsyncWriteRange);
1558     let self_ = &mut (*self_);
1559     let ret = self_.reserve_range(space, start, length, true);
1560     to_crosvm_rc(ret)
1561 }
1562 
1563 #[no_mangle]
crosvm_set_irq(self_: *mut crosvm, irq_id: u32, active: bool) -> c_int1564 pub unsafe extern "C" fn crosvm_set_irq(self_: *mut crosvm, irq_id: u32, active: bool) -> c_int {
1565     let _u = record(Stat::SetIrq);
1566     let self_ = &mut (*self_);
1567     let ret = self_.set_irq(irq_id, active);
1568     to_crosvm_rc(ret)
1569 }
1570 
1571 #[no_mangle]
crosvm_set_irq_routing( self_: *mut crosvm, route_count: u32, routes: *const crosvm_irq_route, ) -> c_int1572 pub unsafe extern "C" fn crosvm_set_irq_routing(
1573     self_: *mut crosvm,
1574     route_count: u32,
1575     routes: *const crosvm_irq_route,
1576 ) -> c_int {
1577     let _u = record(Stat::SetIrqRouting);
1578     let self_ = &mut (*self_);
1579     let ret = self_.set_irq_routing(slice::from_raw_parts(routes, route_count as usize));
1580     to_crosvm_rc(ret)
1581 }
1582 
1583 #[no_mangle]
crosvm_set_hypercall_hint( self_: *mut crosvm, hints_count: u32, hints: *const crosvm_hint, ) -> c_int1584 pub unsafe extern "C" fn crosvm_set_hypercall_hint(
1585     self_: *mut crosvm,
1586     hints_count: u32,
1587     hints: *const crosvm_hint,
1588 ) -> c_int {
1589     let _u = record(Stat::SetHypercallHint);
1590     let self_ = &mut (*self_);
1591 
1592     if hints_count < 1 {
1593         let ret = self_.set_hint(0, 0, false, &[]);
1594         return to_crosvm_rc(ret);
1595     }
1596     if hints_count > CROSVM_MAX_HINT_COUNT {
1597         return -EINVAL;
1598     }
1599     let hints = slice::from_raw_parts(hints, hints_count as usize);
1600     let hint = &hints[0];
1601     if hint.hint_version != 0
1602         || hint.reserved != 0
1603         || hint.address == 0
1604         || (hint.address_flags != 0 && hint.address_flags != CROSVM_HINT_ON_WRITE)
1605         || hint.details_count > CROSVM_MAX_HINT_DETAIL_COUNT as u16
1606     {
1607         return -EINVAL;
1608     }
1609     let ret = self_.set_hint(
1610         hint.address_space,
1611         hint.address,
1612         hint.address_flags == CROSVM_HINT_ON_WRITE,
1613         slice::from_raw_parts(hint.details, hint.details_count as usize),
1614     );
1615     to_crosvm_rc(ret)
1616 }
1617 
1618 #[no_mangle]
crosvm_get_pic_state( this: *mut crosvm, primary: bool, state: *mut kvm_pic_state, ) -> c_int1619 pub unsafe extern "C" fn crosvm_get_pic_state(
1620     this: *mut crosvm,
1621     primary: bool,
1622     state: *mut kvm_pic_state,
1623 ) -> c_int {
1624     let _u = record(Stat::GetPicState);
1625     let this = &mut *this;
1626     let state_set = if primary {
1627         MainRequest_StateSet::PIC0
1628     } else {
1629         MainRequest_StateSet::PIC1
1630     };
1631     let state = from_raw_parts_mut(state as *mut u8, size_of::<kvm_pic_state>());
1632     let ret = this.get_state(state_set, state);
1633     to_crosvm_rc(ret)
1634 }
1635 
1636 #[no_mangle]
crosvm_set_pic_state( this: *mut crosvm, primary: bool, state: *mut kvm_pic_state, ) -> c_int1637 pub unsafe extern "C" fn crosvm_set_pic_state(
1638     this: *mut crosvm,
1639     primary: bool,
1640     state: *mut kvm_pic_state,
1641 ) -> c_int {
1642     let _u = record(Stat::SetPicState);
1643     let this = &mut *this;
1644     let state_set = if primary {
1645         MainRequest_StateSet::PIC0
1646     } else {
1647         MainRequest_StateSet::PIC1
1648     };
1649     let state = from_raw_parts(state as *mut u8, size_of::<kvm_pic_state>());
1650     let ret = this.set_state(state_set, state);
1651     to_crosvm_rc(ret)
1652 }
1653 
1654 #[no_mangle]
crosvm_get_ioapic_state( this: *mut crosvm, state: *mut kvm_ioapic_state, ) -> c_int1655 pub unsafe extern "C" fn crosvm_get_ioapic_state(
1656     this: *mut crosvm,
1657     state: *mut kvm_ioapic_state,
1658 ) -> c_int {
1659     let _u = record(Stat::GetIoapicState);
1660     let this = &mut *this;
1661     let state = from_raw_parts_mut(state as *mut u8, size_of::<kvm_ioapic_state>());
1662     let ret = this.get_state(MainRequest_StateSet::IOAPIC, state);
1663     to_crosvm_rc(ret)
1664 }
1665 
1666 #[no_mangle]
crosvm_set_ioapic_state( this: *mut crosvm, state: *const kvm_ioapic_state, ) -> c_int1667 pub unsafe extern "C" fn crosvm_set_ioapic_state(
1668     this: *mut crosvm,
1669     state: *const kvm_ioapic_state,
1670 ) -> c_int {
1671     let _u = record(Stat::SetIoapicState);
1672     let this = &mut *this;
1673     let state = from_raw_parts(state as *mut u8, size_of::<kvm_ioapic_state>());
1674     let ret = this.set_state(MainRequest_StateSet::IOAPIC, state);
1675     to_crosvm_rc(ret)
1676 }
1677 
1678 #[no_mangle]
crosvm_get_pit_state( this: *mut crosvm, state: *mut kvm_pit_state2, ) -> c_int1679 pub unsafe extern "C" fn crosvm_get_pit_state(
1680     this: *mut crosvm,
1681     state: *mut kvm_pit_state2,
1682 ) -> c_int {
1683     let _u = record(Stat::GetPitState);
1684     let this = &mut *this;
1685     let state = from_raw_parts_mut(state as *mut u8, size_of::<kvm_pit_state2>());
1686     let ret = this.get_state(MainRequest_StateSet::PIT, state);
1687     to_crosvm_rc(ret)
1688 }
1689 
1690 #[no_mangle]
crosvm_set_pit_state( this: *mut crosvm, state: *const kvm_pit_state2, ) -> c_int1691 pub unsafe extern "C" fn crosvm_set_pit_state(
1692     this: *mut crosvm,
1693     state: *const kvm_pit_state2,
1694 ) -> c_int {
1695     let _u = record(Stat::SetPitState);
1696     let this = &mut *this;
1697     let state = from_raw_parts(state as *mut u8, size_of::<kvm_pit_state2>());
1698     let ret = this.set_state(MainRequest_StateSet::PIT, state);
1699     to_crosvm_rc(ret)
1700 }
1701 
1702 #[no_mangle]
crosvm_get_clock( this: *mut crosvm, clock_data: *mut kvm_clock_data, ) -> c_int1703 pub unsafe extern "C" fn crosvm_get_clock(
1704     this: *mut crosvm,
1705     clock_data: *mut kvm_clock_data,
1706 ) -> c_int {
1707     let _u = record(Stat::GetClock);
1708     let this = &mut *this;
1709     let state = from_raw_parts_mut(clock_data as *mut u8, size_of::<kvm_clock_data>());
1710     let ret = this.get_state(MainRequest_StateSet::CLOCK, state);
1711     to_crosvm_rc(ret)
1712 }
1713 
1714 #[no_mangle]
crosvm_set_clock( this: *mut crosvm, clock_data: *const kvm_clock_data, ) -> c_int1715 pub unsafe extern "C" fn crosvm_set_clock(
1716     this: *mut crosvm,
1717     clock_data: *const kvm_clock_data,
1718 ) -> c_int {
1719     let _u = record(Stat::SetClock);
1720     let this = &mut *this;
1721     let state = from_raw_parts(clock_data as *mut u8, size_of::<kvm_clock_data>());
1722     let ret = this.set_state(MainRequest_StateSet::CLOCK, state);
1723     to_crosvm_rc(ret)
1724 }
1725 
1726 #[no_mangle]
crosvm_set_identity_map_addr(self_: *mut crosvm, addr: u32) -> c_int1727 pub unsafe extern "C" fn crosvm_set_identity_map_addr(self_: *mut crosvm, addr: u32) -> c_int {
1728     let _u = record(Stat::SetIdentityMapAddr);
1729     let self_ = &mut (*self_);
1730     let ret = self_.set_identity_map_addr(addr);
1731     to_crosvm_rc(ret)
1732 }
1733 
1734 #[no_mangle]
crosvm_pause_vcpus( self_: *mut crosvm, cpu_mask: u64, user: *mut c_void, ) -> c_int1735 pub unsafe extern "C" fn crosvm_pause_vcpus(
1736     self_: *mut crosvm,
1737     cpu_mask: u64,
1738     user: *mut c_void,
1739 ) -> c_int {
1740     let _u = record(Stat::PauseVcpus);
1741     let self_ = &mut (*self_);
1742     let ret = self_.pause_vcpus(cpu_mask, user);
1743     to_crosvm_rc(ret)
1744 }
1745 
1746 #[no_mangle]
crosvm_start(self_: *mut crosvm) -> c_int1747 pub unsafe extern "C" fn crosvm_start(self_: *mut crosvm) -> c_int {
1748     let _u = record(Stat::Start);
1749     let self_ = &mut (*self_);
1750     let ret = self_.start();
1751     to_crosvm_rc(ret)
1752 }
1753 
1754 #[no_mangle]
crosvm_get_vcpu( self_: *mut crosvm, cpu_id: u32, out: *mut *mut crosvm_vcpu, ) -> c_int1755 pub unsafe extern "C" fn crosvm_get_vcpu(
1756     self_: *mut crosvm,
1757     cpu_id: u32,
1758     out: *mut *mut crosvm_vcpu,
1759 ) -> c_int {
1760     let _u = record(Stat::GetVcpu);
1761     let self_ = &mut (*self_);
1762     let ret = self_.get_vcpu(cpu_id);
1763 
1764     if let Ok(vcpu) = ret {
1765         *out = vcpu;
1766     }
1767     to_crosvm_rc(ret)
1768 }
1769 
1770 #[no_mangle]
crosvm_vcpu_wait( this: *mut crosvm_vcpu, event: *mut crosvm_vcpu_event, ) -> c_int1771 pub unsafe extern "C" fn crosvm_vcpu_wait(
1772     this: *mut crosvm_vcpu,
1773     event: *mut crosvm_vcpu_event,
1774 ) -> c_int {
1775     let _u = record(Stat::VcpuWait);
1776     let this = &mut *this;
1777     let event = &mut *event;
1778     let ret = this.wait(event);
1779     to_crosvm_rc(ret)
1780 }
1781 
1782 #[no_mangle]
crosvm_vcpu_resume(this: *mut crosvm_vcpu) -> c_int1783 pub unsafe extern "C" fn crosvm_vcpu_resume(this: *mut crosvm_vcpu) -> c_int {
1784     let _u = record(Stat::VcpuResume);
1785     let this = &mut *this;
1786     let ret = this.resume();
1787     to_crosvm_rc(ret)
1788 }
1789 
1790 #[no_mangle]
crosvm_vcpu_get_regs( this: *mut crosvm_vcpu, regs: *mut kvm_regs, ) -> c_int1791 pub unsafe extern "C" fn crosvm_vcpu_get_regs(
1792     this: *mut crosvm_vcpu,
1793     regs: *mut kvm_regs,
1794 ) -> c_int {
1795     let _u = record(Stat::VcpuGetRegs);
1796     let this = &mut *this;
1797     if this.regs.set {
1798         if let Err(e) = this.set_state_from_cache(VcpuRequest_StateSet::REGS) {
1799             return -e;
1800         }
1801     }
1802     let regs = from_raw_parts_mut(regs as *mut u8, size_of::<kvm_regs>());
1803     if this.regs.get {
1804         regs.copy_from_slice(&this.regs.cache);
1805         0
1806     } else {
1807         let ret = this.get_state(VcpuRequest_StateSet::REGS, regs);
1808         to_crosvm_rc(ret)
1809     }
1810 }
1811 
1812 #[no_mangle]
crosvm_vcpu_set_regs( this: *mut crosvm_vcpu, regs: *const kvm_regs, ) -> c_int1813 pub unsafe extern "C" fn crosvm_vcpu_set_regs(
1814     this: *mut crosvm_vcpu,
1815     regs: *const kvm_regs,
1816 ) -> c_int {
1817     let _u = record(Stat::VcpuSetRegs);
1818     let this = &mut *this;
1819     this.regs.get = false;
1820     let regs = from_raw_parts(regs as *mut u8, size_of::<kvm_regs>());
1821     this.regs.set = true;
1822     this.regs.cache = regs.to_vec();
1823     0
1824 }
1825 
1826 #[no_mangle]
crosvm_vcpu_get_sregs( this: *mut crosvm_vcpu, sregs: *mut kvm_sregs, ) -> c_int1827 pub unsafe extern "C" fn crosvm_vcpu_get_sregs(
1828     this: *mut crosvm_vcpu,
1829     sregs: *mut kvm_sregs,
1830 ) -> c_int {
1831     let _u = record(Stat::VcpuGetSregs);
1832     let this = &mut *this;
1833     if this.sregs.set {
1834         if let Err(e) = this.set_state_from_cache(VcpuRequest_StateSet::SREGS) {
1835             return -e;
1836         }
1837     }
1838     let sregs = from_raw_parts_mut(sregs as *mut u8, size_of::<kvm_sregs>());
1839     if this.sregs.get {
1840         sregs.copy_from_slice(&this.sregs.cache);
1841         0
1842     } else {
1843         let ret = this.get_state(VcpuRequest_StateSet::SREGS, sregs);
1844         to_crosvm_rc(ret)
1845     }
1846 }
1847 
1848 #[no_mangle]
crosvm_vcpu_set_sregs( this: *mut crosvm_vcpu, sregs: *const kvm_sregs, ) -> c_int1849 pub unsafe extern "C" fn crosvm_vcpu_set_sregs(
1850     this: *mut crosvm_vcpu,
1851     sregs: *const kvm_sregs,
1852 ) -> c_int {
1853     let _u = record(Stat::VcpuSetSregs);
1854     let this = &mut *this;
1855     this.sregs.get = false;
1856     let sregs = from_raw_parts(sregs as *mut u8, size_of::<kvm_sregs>());
1857     this.sregs.set = true;
1858     this.sregs.cache = sregs.to_vec();
1859     0
1860 }
1861 
1862 #[no_mangle]
crosvm_vcpu_get_fpu(this: *mut crosvm_vcpu, fpu: *mut kvm_fpu) -> c_int1863 pub unsafe extern "C" fn crosvm_vcpu_get_fpu(this: *mut crosvm_vcpu, fpu: *mut kvm_fpu) -> c_int {
1864     let _u = record(Stat::GetFpu);
1865     let this = &mut *this;
1866     let fpu = from_raw_parts_mut(fpu as *mut u8, size_of::<kvm_fpu>());
1867     let ret = this.get_state(VcpuRequest_StateSet::FPU, fpu);
1868     to_crosvm_rc(ret)
1869 }
1870 
1871 #[no_mangle]
crosvm_vcpu_set_fpu(this: *mut crosvm_vcpu, fpu: *const kvm_fpu) -> c_int1872 pub unsafe extern "C" fn crosvm_vcpu_set_fpu(this: *mut crosvm_vcpu, fpu: *const kvm_fpu) -> c_int {
1873     let _u = record(Stat::SetFpu);
1874     let this = &mut *this;
1875     let fpu = from_raw_parts(fpu as *mut u8, size_of::<kvm_fpu>());
1876     let ret = this.set_state(VcpuRequest_StateSet::FPU, fpu);
1877     to_crosvm_rc(ret)
1878 }
1879 
1880 #[no_mangle]
crosvm_vcpu_get_debugregs( this: *mut crosvm_vcpu, dregs: *mut kvm_debugregs, ) -> c_int1881 pub unsafe extern "C" fn crosvm_vcpu_get_debugregs(
1882     this: *mut crosvm_vcpu,
1883     dregs: *mut kvm_debugregs,
1884 ) -> c_int {
1885     let _u = record(Stat::GetDebugRegs);
1886     let this = &mut *this;
1887     if this.debugregs.set {
1888         if let Err(e) = this.set_state_from_cache(VcpuRequest_StateSet::DEBUGREGS) {
1889             return -e;
1890         }
1891     }
1892     let dregs = from_raw_parts_mut(dregs as *mut u8, size_of::<kvm_debugregs>());
1893     if this.debugregs.get {
1894         dregs.copy_from_slice(&this.debugregs.cache);
1895         0
1896     } else {
1897         let ret = this.get_state(VcpuRequest_StateSet::DEBUGREGS, dregs);
1898         to_crosvm_rc(ret)
1899     }
1900 }
1901 
1902 #[no_mangle]
crosvm_vcpu_set_debugregs( this: *mut crosvm_vcpu, dregs: *const kvm_debugregs, ) -> c_int1903 pub unsafe extern "C" fn crosvm_vcpu_set_debugregs(
1904     this: *mut crosvm_vcpu,
1905     dregs: *const kvm_debugregs,
1906 ) -> c_int {
1907     let _u = record(Stat::SetDebugRegs);
1908     let this = &mut *this;
1909     this.debugregs.get = false;
1910     let dregs = from_raw_parts(dregs as *mut u8, size_of::<kvm_debugregs>());
1911     this.debugregs.set = true;
1912     this.debugregs.cache = dregs.to_vec();
1913     0
1914 }
1915 
1916 #[no_mangle]
crosvm_vcpu_get_xcrs( this: *mut crosvm_vcpu, xcrs: *mut kvm_xcrs, ) -> c_int1917 pub unsafe extern "C" fn crosvm_vcpu_get_xcrs(
1918     this: *mut crosvm_vcpu,
1919     xcrs: *mut kvm_xcrs,
1920 ) -> c_int {
1921     let _u = record(Stat::GetXCRegs);
1922     let this = &mut *this;
1923     let xcrs = from_raw_parts_mut(xcrs as *mut u8, size_of::<kvm_xcrs>());
1924     let ret = this.get_state(VcpuRequest_StateSet::XCREGS, xcrs);
1925     to_crosvm_rc(ret)
1926 }
1927 
1928 #[no_mangle]
crosvm_vcpu_set_xcrs( this: *mut crosvm_vcpu, xcrs: *const kvm_xcrs, ) -> c_int1929 pub unsafe extern "C" fn crosvm_vcpu_set_xcrs(
1930     this: *mut crosvm_vcpu,
1931     xcrs: *const kvm_xcrs,
1932 ) -> c_int {
1933     let _u = record(Stat::SetXCRegs);
1934     let this = &mut *this;
1935     let xcrs = from_raw_parts(xcrs as *mut u8, size_of::<kvm_xcrs>());
1936     let ret = this.set_state(VcpuRequest_StateSet::XCREGS, xcrs);
1937     to_crosvm_rc(ret)
1938 }
1939 
1940 #[no_mangle]
crosvm_get_hyperv_cpuid( this: *mut crosvm_vcpu, entry_count: u32, cpuid_entries: *mut kvm_cpuid_entry2, out_count: *mut u32, ) -> c_int1941 pub unsafe extern "C" fn crosvm_get_hyperv_cpuid(
1942     this: *mut crosvm_vcpu,
1943     entry_count: u32,
1944     cpuid_entries: *mut kvm_cpuid_entry2,
1945     out_count: *mut u32,
1946 ) -> c_int {
1947     let _u = record(Stat::GetHypervCpuid);
1948     let this = &mut *this;
1949     let cpuid_entries = from_raw_parts_mut(cpuid_entries, entry_count as usize);
1950     let mut cpuid_count: usize = 0;
1951     let ret = this.get_hyperv_cpuid(cpuid_entries, &mut cpuid_count);
1952     *out_count = cpuid_count as u32;
1953     to_crosvm_rc(ret)
1954 }
1955 
1956 #[no_mangle]
crosvm_vcpu_get_msrs( this: *mut crosvm_vcpu, msr_count: u32, msr_entries: *mut kvm_msr_entry, out_count: *mut u32, ) -> c_int1957 pub unsafe extern "C" fn crosvm_vcpu_get_msrs(
1958     this: *mut crosvm_vcpu,
1959     msr_count: u32,
1960     msr_entries: *mut kvm_msr_entry,
1961     out_count: *mut u32,
1962 ) -> c_int {
1963     let _u = record(Stat::VcpuGetMsrs);
1964     let this = &mut *this;
1965     let msr_entries = from_raw_parts_mut(msr_entries, msr_count as usize);
1966     let mut count: usize = 0;
1967     let ret = this.get_msrs(msr_entries, &mut count);
1968     *out_count = count as u32;
1969     to_crosvm_rc(ret)
1970 }
1971 
1972 #[no_mangle]
crosvm_vcpu_set_msrs( this: *mut crosvm_vcpu, msr_count: u32, msr_entries: *const kvm_msr_entry, ) -> c_int1973 pub unsafe extern "C" fn crosvm_vcpu_set_msrs(
1974     this: *mut crosvm_vcpu,
1975     msr_count: u32,
1976     msr_entries: *const kvm_msr_entry,
1977 ) -> c_int {
1978     let _u = record(Stat::VcpuSetMsrs);
1979     let this = &mut *this;
1980     let msr_entries = from_raw_parts(msr_entries, msr_count as usize);
1981     let ret = this.set_msrs(msr_entries);
1982     to_crosvm_rc(ret)
1983 }
1984 
1985 #[no_mangle]
crosvm_vcpu_set_cpuid( this: *mut crosvm_vcpu, cpuid_count: u32, cpuid_entries: *const kvm_cpuid_entry2, ) -> c_int1986 pub unsafe extern "C" fn crosvm_vcpu_set_cpuid(
1987     this: *mut crosvm_vcpu,
1988     cpuid_count: u32,
1989     cpuid_entries: *const kvm_cpuid_entry2,
1990 ) -> c_int {
1991     let _u = record(Stat::VcpuSetCpuid);
1992     let this = &mut *this;
1993     let cpuid_entries = from_raw_parts(cpuid_entries, cpuid_count as usize);
1994     let ret = this.set_cpuid(cpuid_entries);
1995     to_crosvm_rc(ret)
1996 }
1997 
1998 #[no_mangle]
crosvm_vcpu_enable_capability( this: *mut crosvm_vcpu, capability: u32, flags: u32, args: *const u64, ) -> c_int1999 pub unsafe extern "C" fn crosvm_vcpu_enable_capability(
2000     this: *mut crosvm_vcpu,
2001     capability: u32,
2002     flags: u32,
2003     args: *const u64,
2004 ) -> c_int {
2005     let _u = record(Stat::EnableVcpuCapability);
2006     let this = &mut *this;
2007     let args = slice::from_raw_parts(args, 4);
2008 
2009     if flags != 0 || args.iter().any(|v| *v != 0) {
2010         return -EINVAL;
2011     }
2012 
2013     let ret = this.enable_capability(capability);
2014     to_crosvm_rc(ret)
2015 }
2016 
2017 #[no_mangle]
crosvm_vcpu_get_lapic_state( this: *mut crosvm_vcpu, state: *mut kvm_lapic_state, ) -> c_int2018 pub unsafe extern "C" fn crosvm_vcpu_get_lapic_state(
2019     this: *mut crosvm_vcpu,
2020     state: *mut kvm_lapic_state,
2021 ) -> c_int {
2022     let _u = record(Stat::VcpuGetLapicState);
2023     let this = &mut *this;
2024     let state = from_raw_parts_mut(state as *mut u8, size_of::<kvm_lapic_state>());
2025     let ret = this.get_state(VcpuRequest_StateSet::LAPIC, state);
2026     to_crosvm_rc(ret)
2027 }
2028 
2029 #[no_mangle]
crosvm_vcpu_set_lapic_state( this: *mut crosvm_vcpu, state: *const kvm_lapic_state, ) -> c_int2030 pub unsafe extern "C" fn crosvm_vcpu_set_lapic_state(
2031     this: *mut crosvm_vcpu,
2032     state: *const kvm_lapic_state,
2033 ) -> c_int {
2034     let _u = record(Stat::VcpuSetLapicState);
2035     let this = &mut *this;
2036     let state = from_raw_parts(state as *mut u8, size_of::<kvm_lapic_state>());
2037     let ret = this.set_state(VcpuRequest_StateSet::LAPIC, state);
2038     to_crosvm_rc(ret)
2039 }
2040 
2041 #[no_mangle]
crosvm_vcpu_get_mp_state( this: *mut crosvm_vcpu, state: *mut kvm_mp_state, ) -> c_int2042 pub unsafe extern "C" fn crosvm_vcpu_get_mp_state(
2043     this: *mut crosvm_vcpu,
2044     state: *mut kvm_mp_state,
2045 ) -> c_int {
2046     let _u = record(Stat::VcpuGetMpState);
2047     let this = &mut *this;
2048     let state = from_raw_parts_mut(state as *mut u8, size_of::<kvm_mp_state>());
2049     let ret = this.get_state(VcpuRequest_StateSet::MP, state);
2050     to_crosvm_rc(ret)
2051 }
2052 
2053 #[no_mangle]
crosvm_vcpu_set_mp_state( this: *mut crosvm_vcpu, state: *const kvm_mp_state, ) -> c_int2054 pub unsafe extern "C" fn crosvm_vcpu_set_mp_state(
2055     this: *mut crosvm_vcpu,
2056     state: *const kvm_mp_state,
2057 ) -> c_int {
2058     let _u = record(Stat::VcpuSetMpState);
2059     let this = &mut *this;
2060     let state = from_raw_parts(state as *mut u8, size_of::<kvm_mp_state>());
2061     let ret = this.set_state(VcpuRequest_StateSet::MP, state);
2062     to_crosvm_rc(ret)
2063 }
2064 
2065 #[no_mangle]
crosvm_vcpu_get_vcpu_events( this: *mut crosvm_vcpu, events: *mut kvm_vcpu_events, ) -> c_int2066 pub unsafe extern "C" fn crosvm_vcpu_get_vcpu_events(
2067     this: *mut crosvm_vcpu,
2068     events: *mut kvm_vcpu_events,
2069 ) -> c_int {
2070     let _u = record(Stat::VcpuGetVcpuEvents);
2071     let this = &mut *this;
2072     let events = from_raw_parts_mut(events as *mut u8, size_of::<kvm_vcpu_events>());
2073     let ret = this.get_state(VcpuRequest_StateSet::EVENTS, events);
2074     to_crosvm_rc(ret)
2075 }
2076 
2077 #[no_mangle]
crosvm_vcpu_set_vcpu_events( this: *mut crosvm_vcpu, events: *const kvm_vcpu_events, ) -> c_int2078 pub unsafe extern "C" fn crosvm_vcpu_set_vcpu_events(
2079     this: *mut crosvm_vcpu,
2080     events: *const kvm_vcpu_events,
2081 ) -> c_int {
2082     let _u = record(Stat::VcpuSetVcpuEvents);
2083     let this = &mut *this;
2084     let events = from_raw_parts(events as *mut u8, size_of::<kvm_vcpu_events>());
2085     let ret = this.set_state(VcpuRequest_StateSet::EVENTS, events);
2086     to_crosvm_rc(ret)
2087 }
2088