2020-06-08 00:50:38 +00:00
|
|
|
// Copyright © 2019 Intel Corporation
|
|
|
|
//
|
2020-06-26 00:06:14 +00:00
|
|
|
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
|
2020-06-08 00:50:38 +00:00
|
|
|
//
|
2020-06-28 16:32:56 +00:00
|
|
|
// Copyright © 2020, Microsoft Corporation
|
2020-06-08 00:50:38 +00:00
|
|
|
//
|
|
|
|
// Copyright 2018-2019 CrowdStrike, Inc.
|
|
|
|
//
|
2020-06-03 19:23:56 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
//! A generic abstraction around hypervisor functionality
|
|
|
|
//!
|
|
|
|
//! This crate offers a trait abstraction for underlying hypervisors
|
|
|
|
//!
|
|
|
|
//! # Platform support
|
|
|
|
//!
|
|
|
|
//! - x86_64
|
|
|
|
//! - arm64
|
|
|
|
//!
|
|
|
|
|
2020-08-05 10:00:56 +00:00
|
|
|
#[macro_use]
|
|
|
|
extern crate anyhow;
|
2020-08-30 08:44:39 +00:00
|
|
|
#[cfg(target_arch = "x86_64")]
|
2020-08-05 10:00:56 +00:00
|
|
|
#[macro_use]
|
|
|
|
extern crate log;
|
2020-06-02 21:24:33 +00:00
|
|
|
|
2020-12-10 21:24:19 +00:00
|
|
|
/// Architecture specific definitions
|
|
|
|
#[macro_use]
|
|
|
|
pub mod arch;
|
|
|
|
|
2020-12-04 23:35:29 +00:00
|
|
|
#[cfg(feature = "kvm")]
|
2020-06-03 19:23:56 +00:00
|
|
|
/// KVM implementation module
|
|
|
|
pub mod kvm;
|
|
|
|
|
2020-12-03 22:14:04 +00:00
|
|
|
/// Microsoft Hypervisor implementation module
|
|
|
|
#[cfg(all(feature = "mshv", target_arch = "x86_64"))]
|
|
|
|
pub mod mshv;
|
|
|
|
|
2020-06-03 19:59:49 +00:00
|
|
|
/// Hypevisor related module
|
|
|
|
pub mod hypervisor;
|
|
|
|
|
2020-06-03 19:58:00 +00:00
|
|
|
/// Vm related module
|
|
|
|
pub mod vm;
|
|
|
|
|
2020-06-03 19:23:56 +00:00
|
|
|
/// CPU related module
|
|
|
|
mod cpu;
|
|
|
|
|
2020-07-16 14:50:36 +00:00
|
|
|
/// Device related module
|
|
|
|
mod device;
|
|
|
|
|
2020-06-03 19:59:49 +00:00
|
|
|
pub use crate::hypervisor::{Hypervisor, HypervisorError};
|
2020-07-03 14:27:53 +00:00
|
|
|
pub use cpu::{HypervisorCpuError, Vcpu, VmExit};
|
2020-07-16 14:50:36 +00:00
|
|
|
pub use device::{Device, HypervisorDeviceError};
|
2020-12-04 23:35:29 +00:00
|
|
|
#[cfg(feature = "kvm")]
|
2020-06-03 19:23:56 +00:00
|
|
|
pub use kvm::*;
|
2020-12-03 23:24:57 +00:00
|
|
|
#[cfg(all(feature = "mshv", target_arch = "x86_64"))]
|
|
|
|
pub use mshv::*;
|
2020-06-03 20:09:39 +00:00
|
|
|
pub use vm::{DataMatch, HypervisorVmError, Vm};
|
2020-07-14 11:34:42 +00:00
|
|
|
|
|
|
|
use std::sync::Arc;
|
2020-08-21 20:00:37 +00:00
|
|
|
|
2020-07-14 11:34:42 +00:00
|
|
|
pub fn new() -> std::result::Result<Arc<dyn Hypervisor>, HypervisorError> {
|
|
|
|
#[cfg(feature = "kvm")]
|
|
|
|
let hv = kvm::KvmHypervisor::new()?;
|
|
|
|
|
2020-12-03 23:24:57 +00:00
|
|
|
#[cfg(feature = "mshv")]
|
|
|
|
let hv = mshv::MshvHypervisor::new()?;
|
|
|
|
|
2020-07-14 11:34:42 +00:00
|
|
|
Ok(Arc::new(hv))
|
|
|
|
}
|
2021-03-10 21:26:30 +00:00
|
|
|
|
|
|
|
// Returns a `Vec<T>` with a size in bytes at least as large as `size_in_bytes`.
|
|
|
|
fn vec_with_size_in_bytes<T: Default>(size_in_bytes: usize) -> Vec<T> {
|
|
|
|
let rounded_size = (size_in_bytes + size_of::<T>() - 1) / size_of::<T>();
|
|
|
|
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::<Foo>()` 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<Foo>` is created. Only the first element of `Vec<Foo>` would actually be used
|
|
|
|
// as a `Foo`. The remaining memory in the `Vec<Foo>` is for `entries`, which must be contiguous
|
|
|
|
// with `Foo`. This function is used to make the `Vec<Foo>` with enough space for `count` entries.
|
|
|
|
use std::mem::size_of;
|
|
|
|
pub fn vec_with_array_field<T: Default, F>(count: usize) -> Vec<T> {
|
|
|
|
let element_space = count * size_of::<F>();
|
|
|
|
let vec_size_bytes = size_of::<T>() + element_space;
|
|
|
|
vec_with_size_in_bytes(vec_size_bytes)
|
|
|
|
}
|