summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--data_model/src/flexible_array.rs39
-rw-r--r--data_model/src/lib.rs3
-rw-r--r--devices/src/vfio.rs5
-rw-r--r--kvm/Cargo.toml1
-rw-r--r--kvm/src/lib.rs6
-rw-r--r--sys_util/src/struct_util.rs31
-rw-r--r--usb_util/src/device.rs3
8 files changed, 53 insertions, 36 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e525db3..9536949 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -257,6 +257,7 @@ dependencies = [
 name = "kvm"
 version = "0.1.0"
 dependencies = [
+ "data_model 0.1.0",
  "kvm_sys 0.1.0",
  "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg_socket 0.1.0",
diff --git a/data_model/src/flexible_array.rs b/data_model/src/flexible_array.rs
new file mode 100644
index 0000000..35ac15a
--- /dev/null
+++ b/data_model/src/flexible_array.rs
@@ -0,0 +1,39 @@
+// Copyright 2019 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! A wrapper for structures that contain flexible arrays.
+
+use std::mem::size_of;
+
+// 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 kernel API has many structs that resemble the following `Foo` structure:
+///
+/// ```ignore
+/// #[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)
+}
diff --git a/data_model/src/lib.rs b/data_model/src/lib.rs
index dcca108..3f75377 100644
--- a/data_model/src/lib.rs
+++ b/data_model/src/lib.rs
@@ -180,3 +180,6 @@ pub use crate::endian::*;
 
 pub mod volatile_memory;
 pub use crate::volatile_memory::*;
+
+mod flexible_array;
+pub use flexible_array::vec_with_array_field;
diff --git a/devices/src/vfio.rs b/devices/src/vfio.rs
index c42c622..f8c15c8 100644
--- a/devices/src/vfio.rs
+++ b/devices/src/vfio.rs
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+use data_model::vec_with_array_field;
 use std::ffi::CString;
 use std::fmt;
 use std::fs::{File, OpenOptions};
@@ -14,8 +15,8 @@ use std::u32;
 
 use kvm::Vm;
 use sys_util::{
-    ioctl, ioctl_with_mut_ref, ioctl_with_ptr, ioctl_with_ref, ioctl_with_val,
-    vec_with_array_field, warn, Error, EventFd, GuestMemory,
+    ioctl, ioctl_with_mut_ref, ioctl_with_ptr, ioctl_with_ref, ioctl_with_val, warn, Error,
+    EventFd, GuestMemory,
 };
 
 use vfio_sys::*;
diff --git a/kvm/Cargo.toml b/kvm/Cargo.toml
index d12aa76..f784ae7 100644
--- a/kvm/Cargo.toml
+++ b/kvm/Cargo.toml
@@ -5,6 +5,7 @@ authors = ["The Chromium OS Authors"]
 edition = "2018"
 
 [dependencies]
+data_model = { path = "../data_model" }
 kvm_sys = { path = "../kvm_sys" }
 libc = "*"
 msg_socket = { path = "../msg_socket" }
diff --git a/kvm/src/lib.rs b/kvm/src/lib.rs
index 06f5915..bc1abad 100644
--- a/kvm/src/lib.rs
+++ b/kvm/src/lib.rs
@@ -16,6 +16,8 @@ use std::os::raw::*;
 use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
 use std::ptr::copy_nonoverlapping;
 
+use data_model::vec_with_array_field;
+
 use libc::sigset_t;
 use libc::{open, EBUSY, EINVAL, ENOENT, ENOSPC, EOVERFLOW, O_CLOEXEC, O_RDWR};
 
@@ -25,8 +27,8 @@ use msg_socket::MsgOnSocket;
 #[allow(unused_imports)]
 use sys_util::{
     block_signal, ioctl, ioctl_with_mut_ptr, ioctl_with_mut_ref, ioctl_with_ptr, ioctl_with_ref,
-    ioctl_with_val, pagesize, signal, unblock_signal, vec_with_array_field, warn, Error, EventFd,
-    GuestAddress, GuestMemory, MemoryMapping, MemoryMappingArena, Result, SIGRTMIN,
+    ioctl_with_val, pagesize, signal, unblock_signal, warn, Error, EventFd, GuestAddress,
+    GuestMemory, MemoryMapping, MemoryMappingArena, Result, SIGRTMIN,
 };
 
 pub use crate::cap::*;
diff --git a/sys_util/src/struct_util.rs b/sys_util/src/struct_util.rs
index d77dd96..551204e 100644
--- a/sys_util/src/struct_util.rs
+++ b/sys_util/src/struct_util.rs
@@ -6,37 +6,6 @@ use std;
 use std::io::Read;
 use std::mem::size_of;
 
-// 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:
-///
-/// ```ignore
-/// #[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)
-}
-
 #[derive(Debug)]
 pub enum Error {
     ReadStruct,
diff --git a/usb_util/src/device.rs b/usb_util/src/device.rs
index b6aed6a..aad77db 100644
--- a/usb_util/src/device.rs
+++ b/usb_util/src/device.rs
@@ -7,6 +7,7 @@ use crate::{
     ControlRequestDataPhaseTransferDirection, ControlRequestRecipient, ControlRequestType,
     DeviceDescriptor, DeviceDescriptorTree, Error, Result, StandardControlRequest,
 };
+use data_model::vec_with_array_field;
 use libc::{EAGAIN, ENODEV, ENOENT};
 use std::convert::TryInto;
 use std::fs::File;
@@ -14,7 +15,7 @@ use std::io::{Seek, SeekFrom};
 use std::mem::size_of_val;
 use std::os::raw::{c_int, c_uint, c_ulong, c_void};
 use std::sync::Arc;
-use sys_util::{handle_eintr_errno, vec_with_array_field};
+use sys_util::handle_eintr_errno;
 
 /// Device represents a USB device.
 pub struct Device {