mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-11 06:01:40 +00:00
b2589d4f3f
This allows us to change the memory map that is being used by the devices via an atomic swap (by replacing the map with another one). The ArcSwap provides the mechanism for atomically swapping from to another whilst still giving good read performace. It is inside an Arc so that we can use a single ArcSwap for all users. Not covered by this change is replacing the GuestMemoryMmap itself. This change also removes some vertical whitespace from use blocks in the files that this commit also changed. Vertical whitespace was being used inconsistently and broke rustfmt's behaviour of ordering the imports as it would only do it within the block. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
62 lines
1.9 KiB
Rust
62 lines
1.9 KiB
Rust
// Copyright © 2019 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
|
|
//
|
|
|
|
//#![deny(missing_docs)]
|
|
//! Virtual Function I/O (VFIO) API
|
|
extern crate arc_swap;
|
|
extern crate byteorder;
|
|
extern crate devices;
|
|
extern crate kvm_bindings;
|
|
extern crate kvm_ioctls;
|
|
#[macro_use]
|
|
extern crate log;
|
|
extern crate pci;
|
|
extern crate vfio_bindings;
|
|
extern crate vm_allocator;
|
|
extern crate vm_device;
|
|
extern crate vm_memory;
|
|
#[macro_use]
|
|
extern crate vmm_sys_util;
|
|
|
|
mod vfio_device;
|
|
mod vfio_ioctls;
|
|
mod vfio_pci;
|
|
|
|
use std::mem::size_of;
|
|
|
|
pub use vfio_device::{VfioContainer, VfioDevice, VfioDmaMapping, VfioError};
|
|
pub use vfio_pci::{VfioPciDevice, VfioPciError};
|
|
|
|
// 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);
|
|
for _ in 0..rounded_size {
|
|
v.push(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.
|
|
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)
|
|
}
|