// Copyright © 2019 Intel Corporation // // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause // // Copyright © 2020, Microsoft Corporation // // Copyright 2018-2019 CrowdStrike, Inc. // // //! A generic abstraction around hypervisor functionality //! //! This crate offers a trait abstraction for underlying hypervisors //! //! # Platform support //! //! - x86_64 //! - arm64 //! #[macro_use] extern crate anyhow; #[cfg(target_arch = "x86_64")] #[macro_use] extern crate log; /// Architecture specific definitions #[macro_use] pub mod arch; #[cfg(feature = "kvm")] /// KVM implementation module pub mod kvm; /// Microsoft Hypervisor implementation module #[cfg(all(feature = "mshv", target_arch = "x86_64"))] pub mod mshv; /// Hypevisor related module pub mod hypervisor; /// Vm related module pub mod vm; /// CPU related module mod cpu; /// Device related module mod device; pub use crate::hypervisor::{Hypervisor, HypervisorError}; pub use cpu::{HypervisorCpuError, Vcpu, VmExit}; pub use device::{Device, HypervisorDeviceError}; #[cfg(feature = "kvm")] pub use kvm::*; #[cfg(all(feature = "mshv", target_arch = "x86_64"))] pub use mshv::*; pub use vm::{DataMatch, HypervisorVmError, Vm}; use std::sync::Arc; pub fn new() -> std::result::Result, HypervisorError> { #[cfg(feature = "kvm")] let hv = kvm::KvmHypervisor::new()?; #[cfg(feature = "mshv")] let hv = mshv::MshvHypervisor::new()?; Ok(Arc::new(hv)) } // Returns a `Vec` with a size in bytes at least as large as `size_in_bytes`. fn vec_with_size_in_bytes(size_in_bytes: usize) -> Vec { let rounded_size = (size_in_bytes + size_of::() - 1) / size_of::(); let mut v = Vec::with_capacity(rounded_size); v.resize_with(rounded_size, T::default); v } // The kvm API has many structs that resemble the following `Foo` structure: // // ``` // #[repr(C)] // struct Foo { // some_data: u32 // entries: __IncompleteArrayField<__u32>, // } // ``` // // In order to allocate such a structure, `size_of::()` would be too small because it would not // include any space for `entries`. To make the allocation large enough while still being aligned // for `Foo`, a `Vec` is created. Only the first element of `Vec` would actually be used // as a `Foo`. The remaining memory in the `Vec` is for `entries`, which must be contiguous // with `Foo`. This function is used to make the `Vec` with enough space for `count` entries. use std::mem::size_of; pub fn vec_with_array_field(count: usize) -> Vec { let element_space = count * size_of::(); let vec_size_bytes = size_of::() + element_space; vec_with_size_in_bytes(vec_size_bytes) }