2019-06-13 20:13:35 +00:00
|
|
|
// 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 byteorder;
|
2019-07-15 07:50:55 +00:00
|
|
|
extern crate devices;
|
2019-06-13 20:13:35 +00:00
|
|
|
extern crate kvm_bindings;
|
|
|
|
extern crate kvm_ioctls;
|
2019-09-02 09:44:52 +00:00
|
|
|
#[macro_use]
|
2019-06-13 20:13:35 +00:00
|
|
|
extern crate log;
|
2019-07-15 07:50:55 +00:00
|
|
|
extern crate pci;
|
2019-06-13 20:13:35 +00:00
|
|
|
extern crate vfio_bindings;
|
2019-07-15 07:50:55 +00:00
|
|
|
extern crate vm_allocator;
|
2019-06-13 20:13:35 +00:00
|
|
|
extern crate vm_memory;
|
|
|
|
#[macro_use]
|
|
|
|
extern crate vmm_sys_util;
|
|
|
|
|
|
|
|
mod vfio_device;
|
|
|
|
mod vfio_ioctls;
|
2019-07-15 07:50:55 +00:00
|
|
|
mod vfio_pci;
|
2019-06-13 20:13:35 +00:00
|
|
|
|
|
|
|
use std::mem::size_of;
|
|
|
|
|
|
|
|
pub use vfio_device::{VfioDevice, VfioError};
|
2019-07-15 08:48:37 +00:00
|
|
|
pub use vfio_pci::{VfioPciDevice, VfioPciError};
|
2019-06-13 20:13:35 +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);
|
|
|
|
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)
|
|
|
|
}
|