// 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` 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); 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::()` 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. 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) }