mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vfio: VFIO API wrappers and helpers
The Virtual Function I/O (VFIO) kernel subsystem exposes a vast and relatively complex userspace API. This commit abstracts and simplifies this API into both an internal and external API. The external API is to be consumed by VFIO device implementation through the VfioDevice structure. A VfioDevice instance can: - Enable and disable all interrupts (INTX, MSI and MSI-X) on the underlying VFIO device. - Read and write all of the VFIO device memory regions. - Set the system's IOMMU tables for the underlying device. Signed-off-by: Zhang, Xiong Y <xiong.y.zhang@intel.com> Signed-off-by: Chao Peng <chao.p.peng@linux.intel.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
// 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;
|
||||
extern crate kvm_bindings;
|
||||
extern crate kvm_ioctls;
|
||||
extern crate log;
|
||||
extern crate vfio_bindings;
|
||||
extern crate vm_memory;
|
||||
#[macro_use]
|
||||
extern crate vmm_sys_util;
|
||||
|
||||
mod vfio_device;
|
||||
mod vfio_ioctls;
|
||||
|
||||
use std::mem::size_of;
|
||||
|
||||
pub use vfio_device::{VfioDevice, VfioError};
|
||||
|
||||
// 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)
|
||||
}
|
||||
Reference in New Issue
Block a user