diff options
author | Xiong Zhang <xiong.y.zhang@intel.corp-partner.google.com> | 2019-04-23 17:15:00 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-10-17 00:17:07 +0000 |
commit | bed8b0017d2cb283c20dc50241adb4f5b2668489 (patch) | |
tree | 7a76e936a9e1aede56c08c112ca7d436ab8d9e98 /kvm | |
parent | 04a82c7be173b2068c4254ed4a129e24e9e3a2e4 (diff) | |
download | crosvm-bed8b0017d2cb283c20dc50241adb4f5b2668489.tar crosvm-bed8b0017d2cb283c20dc50241adb4f5b2668489.tar.gz crosvm-bed8b0017d2cb283c20dc50241adb4f5b2668489.tar.bz2 crosvm-bed8b0017d2cb283c20dc50241adb4f5b2668489.tar.lz crosvm-bed8b0017d2cb283c20dc50241adb4f5b2668489.tar.xz crosvm-bed8b0017d2cb283c20dc50241adb4f5b2668489.tar.zst crosvm-bed8b0017d2cb283c20dc50241adb4f5b2668489.zip |
vfio: Add msi support
crosvm doesn't support MSI/MSI-x, but kvmgt vgpu support MSI only through cfg msi capability. This is a simple msi implementation, it detects msi capability and track msi control, data and address info, then call vfio kernel to enable / disable msi interrupt. Currently it supports one vetor per MSI. It could extend to multi vetors and MSI-x. BUG=chromium:992270 TEST=none Change-Id: I04fc95f23a07f9698237c014d9f909d011f447ef Signed-off-by: Xiong Zhang <xiong.y.zhang@intel.corp-partner.google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1581142 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Diffstat (limited to 'kvm')
-rw-r--r-- | kvm/src/lib.rs | 35 |
1 files changed, 2 insertions, 33 deletions
diff --git a/kvm/src/lib.rs b/kvm/src/lib.rs index bafc79d..b8475d3 100644 --- a/kvm/src/lib.rs +++ b/kvm/src/lib.rs @@ -23,8 +23,8 @@ use msg_socket::MsgOnSocket; #[allow(unused_imports)] use sys_util::{ ioctl, ioctl_with_mut_ptr, ioctl_with_mut_ref, ioctl_with_ptr, ioctl_with_ref, ioctl_with_val, - pagesize, signal, warn, Error, EventFd, GuestAddress, GuestMemory, MemoryMapping, - MemoryMappingArena, Result, + pagesize, signal, vec_with_array_field, warn, Error, EventFd, GuestAddress, GuestMemory, + MemoryMapping, MemoryMappingArena, Result, }; pub use crate::cap::*; @@ -33,37 +33,6 @@ fn errno_result<T>() -> Result<T> { Err(Error::last()) } -// Returns a `Vec<T>` with a size in ytes 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. -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) -} - unsafe fn set_user_memory_region<F: AsRawFd>( fd: &F, slot: u32, |