1 // Copyright © 2019 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause 4 // 5 // Copyright © 2020, Microsoft Corporation 6 // 7 // Copyright 2018-2019 CrowdStrike, Inc. 8 // 9 // 10 11 //! A generic abstraction around hypervisor functionality 12 //! 13 //! This crate offers a trait abstraction for underlying hypervisors 14 //! 15 //! # Platform support 16 //! 17 //! - x86_64 18 //! - arm64 19 //! 20 21 #[macro_use] 22 extern crate anyhow; 23 #[cfg(target_arch = "x86_64")] 24 #[macro_use] 25 extern crate log; 26 27 /// Architecture specific definitions 28 #[macro_use] 29 pub mod arch; 30 31 #[cfg(feature = "kvm")] 32 /// KVM implementation module 33 pub mod kvm; 34 35 /// Microsoft Hypervisor implementation module 36 #[cfg(all(feature = "mshv", target_arch = "x86_64"))] 37 pub mod mshv; 38 39 /// Hypevisor related module 40 pub mod hypervisor; 41 42 /// Vm related module 43 pub mod vm; 44 45 /// CPU related module 46 mod cpu; 47 48 /// Device related module 49 mod device; 50 51 pub use crate::hypervisor::{Hypervisor, HypervisorError}; 52 pub use cpu::{HypervisorCpuError, Vcpu, VmExit}; 53 pub use device::{Device, HypervisorDeviceError}; 54 #[cfg(feature = "kvm")] 55 pub use kvm::*; 56 #[cfg(all(feature = "mshv", target_arch = "x86_64"))] 57 pub use mshv::*; 58 pub use vm::{DataMatch, HypervisorVmError, Vm}; 59 60 use std::sync::Arc; 61 62 pub fn new() -> std::result::Result<Arc<dyn Hypervisor>, HypervisorError> { 63 #[cfg(feature = "kvm")] 64 let hv = kvm::KvmHypervisor::new()?; 65 66 #[cfg(feature = "mshv")] 67 let hv = mshv::MshvHypervisor::new()?; 68 69 Ok(Arc::new(hv)) 70 } 71 72 // Returns a `Vec<T>` with a size in bytes at least as large as `size_in_bytes`. 73 fn vec_with_size_in_bytes<T: Default>(size_in_bytes: usize) -> Vec<T> { 74 let rounded_size = (size_in_bytes + size_of::<T>() - 1) / size_of::<T>(); 75 let mut v = Vec::with_capacity(rounded_size); 76 v.resize_with(rounded_size, T::default); 77 v 78 } 79 80 // The kvm API has many structs that resemble the following `Foo` structure: 81 // 82 // ``` 83 // #[repr(C)] 84 // struct Foo { 85 // some_data: u32 86 // entries: __IncompleteArrayField<__u32>, 87 // } 88 // ``` 89 // 90 // In order to allocate such a structure, `size_of::<Foo>()` would be too small because it would not 91 // include any space for `entries`. To make the allocation large enough while still being aligned 92 // for `Foo`, a `Vec<Foo>` is created. Only the first element of `Vec<Foo>` would actually be used 93 // as a `Foo`. The remaining memory in the `Vec<Foo>` is for `entries`, which must be contiguous 94 // with `Foo`. This function is used to make the `Vec<Foo>` with enough space for `count` entries. 95 use std::mem::size_of; 96 pub fn vec_with_array_field<T: Default, F>(count: usize) -> Vec<T> { 97 let element_space = count * size_of::<F>(); 98 let vec_size_bytes = size_of::<T>() + element_space; 99 vec_with_size_in_bytes(vec_size_bytes) 100 } 101