vm-virtio, virtio-devices: Split device implementation from virt queues

Split the generic virtio code (queues and device type) from the
VirtioDevice trait, transport and device implementations.

This also simplifies the feature handling in vhost_user_backend as the
vm-virtio crate is no longer has any features.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2020-07-02 13:25:19 +01:00
parent 9a628edfcf
commit 2a6eb31d5b
51 changed files with 301 additions and 245 deletions

54
Cargo.lock generated
View File

@ -205,6 +205,7 @@ dependencies = [
"vhost_user_fs",
"vhost_user_net",
"virtio-bindings",
"virtio-devices",
"vm-device",
"vm-memory",
"vm-virtio",
@ -896,7 +897,7 @@ dependencies = [
"log 0.4.8",
"remain",
"tempfile",
"vm-virtio",
"virtio-devices",
"vmm-sys-util",
]
@ -1448,8 +1449,8 @@ dependencies = [
"vhost",
"vhost_user_backend",
"virtio-bindings",
"virtio-devices",
"vm-memory",
"vm-virtio",
"vmm",
"vmm-sys-util",
]
@ -1464,6 +1465,7 @@ dependencies = [
"seccomp",
"tempdir",
"vhost",
"virtio-devices",
"vm-memory",
"vm-virtio",
]
@ -1480,8 +1482,8 @@ dependencies = [
"vhost",
"vhost_user_backend",
"virtio-bindings",
"virtio-devices",
"vm-memory",
"vm-virtio",
"vmm",
"vmm-sys-util",
]
@ -1492,6 +1494,35 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ff512178285488516ed85f15b5d0113a7cdb89e9e8a760b269ae4f02b84bd6b"
[[package]]
name = "virtio-devices"
version = "0.1.0"
dependencies = [
"anyhow",
"arc-swap",
"byteorder",
"devices",
"epoll",
"libc",
"log 0.4.8",
"net_gen",
"net_util",
"pci",
"serde",
"serde_derive",
"serde_json",
"tempfile",
"vfio-ioctls",
"vhost",
"virtio-bindings",
"vm-allocator",
"vm-device",
"vm-memory",
"vm-migration",
"vm-virtio",
"vmm-sys-util",
]
[[package]]
name = "vm-allocator"
version = "0.1.0"
@ -1539,28 +1570,12 @@ dependencies = [
name = "vm-virtio"
version = "0.1.0"
dependencies = [
"anyhow",
"arc-swap",
"byteorder",
"devices",
"epoll",
"libc",
"log 0.4.8",
"net_gen",
"net_util",
"pci",
"serde",
"serde_derive",
"serde_json",
"tempfile",
"vfio-ioctls",
"vhost",
"virtio-bindings",
"vm-allocator",
"vm-device",
"vm-memory",
"vm-migration",
"vmm-sys-util",
]
[[package]]
@ -1592,6 +1607,7 @@ dependencies = [
"tempfile",
"url",
"vfio-ioctls",
"virtio-devices",
"vm-allocator",
"vm-device",
"vm-memory",

View File

@ -25,12 +25,13 @@ vhost_user_block = { path = "vhost_user_block"}
vhost_user_fs = { path = "vhost_user_fs"}
vhost_user_net = { path = "vhost_user_net"}
virtio-bindings = { version = "0.1", features = ["virtio-v5_0_0"]}
virtio-devices = { path = "virtio-devices" }
vhost_rs = { git = "https://github.com/cloud-hypervisor/vhost", branch = "dragonball", package = "vhost", features = ["vhost-user-slave"] }
vmm = { path = "vmm" }
vmm-sys-util = "0.6.1"
vm-device = { path = "vm-device" }
vm-memory = "0.2.1"
vmm-sys-util = "0.6.1"
vm-virtio = { path = "vm-virtio" }
vhost_rs = { git = "https://github.com/cloud-hypervisor/vhost", branch = "dragonball", package = "vhost", features = ["vhost-user-slave"] }
[patch.crates-io]
vm-memory = { git = "https://github.com/cloud-hypervisor/vm-memory", branch = "ch" }
@ -62,6 +63,7 @@ members = [
"devices",
"qcow",
"pci",
"virtio-devices",
"vmm",
"vm-virtio",
"vm-device",

View File

@ -14,7 +14,7 @@ libc = "0.2.71"
log = "0.4.8"
remain = "0.2.2"
vmm-sys-util = ">=0.3.1"
vm-virtio = { path = "../vm-virtio" }
virtio-devices = { path = "../virtio-devices" }
[dev-dependencies]
tempfile = "3.1.0"

View File

@ -12,7 +12,7 @@ mod vec_cache;
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use libc::{EINVAL, ENOSPC, ENOTSUP};
use remain::sorted;
use vm_virtio::RawFile;
use virtio_devices::RawFile;
use vmm_sys_util::{
file_traits::FileSetLen, file_traits::FileSync, seek_hole::SeekHole, write_zeroes::PunchHole,
write_zeroes::WriteZeroes,
@ -367,7 +367,7 @@ fn max_refcount_clusters(refcount_order: u32, cluster_size: u32, num_clusters: u
///
/// ```
/// # use std::io::{Read, Seek, SeekFrom};
/// # use vm_virtio::RawFile;
/// # use virtio_devices::RawFile;
/// # use qcow::{self, QcowFile};
/// # fn test(file: std::fs::File) -> std::io::Result<()> {
/// let mut raw_img = RawFile::new(file, false);
@ -1703,7 +1703,7 @@ mod tests {
use super::*;
use std::io::{Read, Seek, SeekFrom, Write};
use tempfile::tempfile;
use vm_virtio::RawFile;
use virtio_devices::RawFile;
fn valid_header_v3() -> Vec<u8> {
vec![

View File

@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io::{self, BufWriter, Seek, SeekFrom};
use std::mem::size_of;
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use vm_virtio::RawFile;
use virtio_devices::RawFile;
use vmm_sys_util::write_zeroes::WriteZeroes;
/// A qcow file. Allows reading/writing clusters and appending clusters.

View File

@ -7,7 +7,7 @@ extern crate clap;
extern crate log;
extern crate vhost_rs;
extern crate vhost_user_backend;
extern crate vm_virtio;
extern crate virtio_devices;
use clap::{App, Arg};
use futures::executor::{ThreadPool, ThreadPoolBuilder};

View File

@ -6,8 +6,6 @@ edition = "2018"
[features]
default = []
pci_support = ["vm-virtio/pci_support"]
mmio_support = ["vm-virtio/mmio_support"]
[dependencies]
epoll = ">=4.0.1"

View File

@ -13,7 +13,7 @@ qcow = { path = "../qcow" }
vhost_user_backend = { path = "../vhost_user_backend" }
vhost_rs = { git = "https://github.com/cloud-hypervisor/vhost", branch = "dragonball", package = "vhost", features = ["vhost-user-slave"] }
virtio-bindings = "0.1.0"
virtio-devices = { path = "../virtio-devices" }
vm-memory = "0.2.1"
vm-virtio = { path = "../vm-virtio" }
vmm = { path = "../vmm" }
vmm-sys-util = ">=0.3.1"

View File

@ -11,7 +11,7 @@
extern crate log;
extern crate vhost_rs;
extern crate vhost_user_backend;
extern crate vm_virtio;
extern crate virtio_devices;
use libc::EFD_NONBLOCK;
use log::*;
@ -36,10 +36,10 @@ use vhost_rs::vhost_user::Listener;
use vhost_user_backend::{VhostUserBackend, VhostUserDaemon, Vring};
use virtio_bindings::bindings::virtio_blk::*;
use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
use virtio_devices::block::{build_disk_image_id, Request};
use virtio_devices::VirtioBlockConfig;
use vm_memory::ByteValued;
use vm_memory::{Bytes, GuestMemoryMmap};
use vm_virtio::block::{build_disk_image_id, Request};
use vm_virtio::VirtioBlockConfig;
use vmm::config::{OptionParser, OptionParserError, Toggle};
use vmm_sys_util::eventfd::EventFd;
@ -207,7 +207,7 @@ impl VhostUserBlkBackend {
options.custom_flags(libc::O_DIRECT);
}
let image: File = options.open(&image_path).unwrap();
let mut raw_img: vm_virtio::RawFile = vm_virtio::RawFile::new(image, direct);
let mut raw_img: virtio_devices::RawFile = virtio_devices::RawFile::new(image, direct);
let image_id = build_disk_image_id(&PathBuf::from(&image_path));
let image_type = qcow::detect_image_type(&mut raw_img).unwrap();

View File

@ -11,6 +11,7 @@ log = "0.4.8"
# Match the version in vmm
seccomp = { git = "https://github.com/firecracker-microvm/firecracker", tag = "v0.21.1" }
tempdir= "0.3.7"
virtio-devices = { path = "../virtio-devices" }
vm-memory = "0.2.1"
vm-virtio = { path = "../vm-virtio" }
vhost_rs = { git = "https://github.com/cloud-hypervisor/vhost", branch = "dragonball", package = "vhost", features = ["vhost-user-slave"] }

View File

@ -13,7 +13,7 @@ net_util = { path = "../net_util" }
vhost_user_backend = { path = "../vhost_user_backend" }
vhost_rs = { git = "https://github.com/cloud-hypervisor/vhost", branch = "dragonball", package = "vhost", features = ["vhost-user-slave"] }
virtio-bindings = "0.1.0"
virtio-devices = { path = "../virtio-devices" }
vm-memory = "0.2.1"
vm-virtio = { path = "../vm-virtio" }
vmm = { path = "../vmm" }
vmm-sys-util = ">=0.3.1"

View File

@ -10,7 +10,7 @@ extern crate log;
extern crate net_util;
extern crate vhost_rs;
extern crate vhost_user_backend;
extern crate vm_virtio;
extern crate virtio_devices;
extern crate vmm;
use libc::{self, EFD_NONBLOCK};
@ -28,9 +28,9 @@ use vhost_rs::vhost_user::{Error as VhostUserError, Listener};
use vhost_user_backend::{VhostUserBackend, VhostUserDaemon, Vring, VringWorker};
use virtio_bindings::bindings::virtio_net::*;
use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
use virtio_devices::net_util::{open_tap, RxVirtio, TxVirtio};
use virtio_devices::{NetCounters, NetQueuePair};
use vm_memory::{GuestMemoryAtomic, GuestMemoryMmap};
use vm_virtio::net_util::{open_tap, RxVirtio, TxVirtio};
use vm_virtio::{NetCounters, NetQueuePair};
use vmm::config::{OptionParser, OptionParserError};
use vmm_sys_util::eventfd::EventFd;
@ -67,11 +67,11 @@ pub enum Error {
/// No memory configured.
NoMemoryConfigured,
/// Open tap device failed.
OpenTap(vm_virtio::net_util::Error),
OpenTap(virtio_devices::net_util::Error),
/// No socket provided
SocketParameterMissing,
/// Underlying QueuePair error
NetQueuePair(vm_virtio::Error),
NetQueuePair(virtio_devices::Error),
}
pub const SYNTAX: &str = "vhost-user-net backend parameters \

36
virtio-devices/Cargo.toml Normal file
View File

@ -0,0 +1,36 @@
[package]
name = "virtio-devices"
version = "0.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
[features]
default = []
pci_support = ["pci"]
mmio_support = []
[dependencies]
anyhow = "1.0"
arc-swap = ">=0.4.4"
byteorder = "1.3.4"
devices = { path = "../devices" }
epoll = ">=4.0.1"
libc = "0.2.71"
log = "0.4.8"
net_gen = { path = "../net_gen" }
net_util = { path = "../net_util" }
pci = { path = "../pci", optional = true }
serde = ">=1.0.27"
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
tempfile = "3.1.0"
vfio-ioctls = { git = "https://github.com/cloud-hypervisor/vfio-ioctls", branch = "ch" }
vhost_rs = { git = "https://github.com/cloud-hypervisor/vhost", branch = "dragonball", package = "vhost", features = ["vhost-user-master", "vhost-user-slave"] }
virtio-bindings = { version = "0.1", features = ["virtio-v5_0_0"]}
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = { version = "0.2.1", features = ["backend-mmap", "backend-atomic"] }
vm-migration = { path = "../vm-migration" }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = ">=0.3.1"

View File

@ -33,9 +33,6 @@ pub trait VirtioInterrupt: Send + Sync {
}
}
pub type VirtioIommuRemapping =
Box<dyn Fn(u64) -> std::result::Result<u64, std::io::Error> + Send + Sync>;
#[derive(Clone)]
pub struct UserspaceMapping {
pub host_addr: u64,

123
virtio-devices/src/lib.rs Normal file
View File

@ -0,0 +1,123 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Portions Copyright 2017 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-BSD-3-Clause file.
//
// Copyright © 2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
//! Implements virtio devices, queues, and transport mechanisms.
extern crate arc_swap;
extern crate epoll;
#[macro_use]
extern crate log;
#[cfg(feature = "pci_support")]
extern crate pci;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate vhost_rs;
extern crate virtio_bindings;
extern crate vm_device;
extern crate vm_memory;
use std::io;
#[macro_use]
mod device;
pub mod block;
mod console;
mod iommu;
pub mod mem;
pub mod net;
pub mod net_util;
mod pmem;
mod rng;
pub mod transport;
pub mod vhost_user;
pub mod vsock;
pub use self::block::*;
pub use self::console::*;
pub use self::device::*;
pub use self::iommu::*;
pub use self::mem::*;
pub use self::net::*;
pub use self::net_util::*;
pub use self::pmem::*;
pub use self::rng::*;
pub use self::vsock::*;
use vm_virtio::{queue::*, VirtioDeviceType};
const DEVICE_INIT: u32 = 0x00;
const DEVICE_ACKNOWLEDGE: u32 = 0x01;
const DEVICE_DRIVER: u32 = 0x02;
const DEVICE_DRIVER_OK: u32 = 0x04;
const DEVICE_FEATURES_OK: u32 = 0x08;
const DEVICE_FAILED: u32 = 0x80;
const VIRTIO_F_VERSION_1: u32 = 32;
const VIRTIO_F_IOMMU_PLATFORM: u32 = 33;
const VIRTIO_F_IN_ORDER: u32 = 35;
#[allow(dead_code)]
const INTERRUPT_STATUS_USED_RING: u32 = 0x1;
#[allow(dead_code)]
const INTERRUPT_STATUS_CONFIG_CHANGED: u32 = 0x2;
#[cfg(feature = "pci_support")]
const VIRTIO_MSI_NO_VECTOR: u16 = 0xffff;
#[derive(Debug)]
pub enum ActivateError {
EpollCtl(std::io::Error),
BadActivate,
/// Queue number is not correct
BadQueueNum,
/// Failed to clone Kill event
CloneKillEventFd,
/// Failed to create Vhost-user interrupt eventfd
VhostIrqCreate,
/// Failed to setup vhost-user daemon.
VhostUserSetup(vhost_user::Error),
/// Failed to setup vhost-user daemon.
VhostUserNetSetup(vhost_user::Error),
/// Failed to setup vhost-user daemon.
VhostUserBlkSetup(vhost_user::Error),
/// Failed to reset vhost-user daemon.
VhostUserReset(vhost_user::Error),
}
pub type ActivateResult = std::result::Result<(), ActivateError>;
pub type DeviceEventT = u16;
#[derive(Debug)]
pub enum Error {
FailedReadingQueue {
event_type: &'static str,
underlying: io::Error,
},
FailedReadTap,
FailedSignalingUsedQueue(io::Error),
PayloadExpected,
UnknownEvent {
device: &'static str,
event: DeviceEventT,
},
IoError(io::Error),
RegisterListener(io::Error),
UnregisterListener(io::Error),
EpollCreateFd(io::Error),
EpollCtl(io::Error),
EpollWait(io::Error),
FailedSignalingDriver(io::Error),
VhostUserUpdateMemory(vhost_user::Error),
EventfdError(io::Error),
SetShmRegionsNotSupported,
EpollHander(String),
NoMemoryConfigured,
}

View File

@ -22,6 +22,7 @@ use vm_migration::{
Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable,
Transportable,
};
use vm_virtio::queue;
use vmm_sys_util::{errno::Result, eventfd::EventFd};
const VENDOR_ID: u32 = 0;
@ -32,7 +33,7 @@ const MMIO_VERSION: u32 = 2;
#[derive(Debug)]
enum Error {
/// Failed to retrieve queue ring's index.
QueueRingIndex(crate::queue::Error),
QueueRingIndex(queue::Error),
}
pub struct VirtioInterruptIntx {

View File

@ -17,8 +17,8 @@ use super::VirtioPciCommonConfig;
use crate::transport::VirtioTransport;
use crate::{
Queue, VirtioDevice, VirtioDeviceType, VirtioInterrupt, VirtioInterruptType,
VirtioIommuRemapping, DEVICE_ACKNOWLEDGE, DEVICE_DRIVER, DEVICE_DRIVER_OK, DEVICE_FAILED,
DEVICE_FEATURES_OK, DEVICE_INIT, VIRTIO_MSI_NO_VECTOR,
DEVICE_ACKNOWLEDGE, DEVICE_DRIVER, DEVICE_DRIVER_OK, DEVICE_FAILED, DEVICE_FEATURES_OK,
DEVICE_INIT, VIRTIO_MSI_NO_VECTOR,
};
use anyhow::anyhow;
use devices::BusDevice;
@ -47,12 +47,13 @@ use vm_migration::{
Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable,
Transportable,
};
use vm_virtio::{queue, VirtioIommuRemapping};
use vmm_sys_util::{errno::Result, eventfd::EventFd};
#[derive(Debug)]
enum Error {
/// Failed to retrieve queue ring's index.
QueueRingIndex(crate::queue::Error),
QueueRingIndex(queue::Error),
}
#[allow(clippy::enum_variant_names)]

View File

@ -1,9 +1,8 @@
// Copyright 2019 Intel Corporation. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use super::super::Queue;
use super::super::{Descriptor, Queue};
use super::{Error, Result};
use crate::queue::Descriptor;
use crate::{VirtioInterrupt, VirtioInterruptType};
use libc::EFD_NONBLOCK;
use std::convert::TryInto;

View File

@ -161,15 +161,15 @@ mod tests {
use super::packet::VSOCK_PKT_HDR_SIZE;
use super::*;
use crate::device::{VirtioInterrupt, VirtioInterruptType};
use crate::queue::tests::VirtQueue as GuestQ;
use crate::queue::Queue;
use crate::{VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE};
use libc::EFD_NONBLOCK;
use std::os::unix::io::AsRawFd;
use std::path::PathBuf;
use std::sync::atomic::AtomicBool;
use std::sync::{Arc, RwLock};
use vm_memory::{GuestAddress, GuestMemoryAtomic, GuestMemoryMmap};
use vm_virtio::queue::testing::VirtQueue as GuestQ;
use vm_virtio::queue::Queue;
use vm_virtio::queue::{VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE};
use vmm_sys_util::eventfd::EventFd;
pub struct NoopVirtioInterrupt {}

View File

@ -340,14 +340,12 @@ impl VsockPacket {
#[cfg(test)]
mod tests {
use vm_memory::{GuestAddress, GuestMemoryMmap};
use super::super::tests::TestContext;
use super::*;
use crate::queue::tests::VirtqDesc as GuestQDesc;
use crate::vsock::defs::MAX_PKT_BUF_SIZE;
use crate::VIRTQ_DESC_F_WRITE;
use vm_memory::{GuestAddress, GuestMemoryMmap};
use vm_virtio::queue::testing::VirtqDesc as GuestQDesc;
use vm_virtio::queue::VIRTQ_DESC_F_WRITE;
macro_rules! create_context {
($test_ctx:ident, $handler_ctx:ident) => {

View File

@ -1,34 +1,16 @@
[package]
name = "vm-virtio"
version = "0.1.0"
authors = ["Samuel Ortiz <sameo@linux.intel.com>"]
authors = ["The Cloud Hypervisor Authors"]
edition = "2018"
[features]
default = []
pci_support = ["pci"]
mmio_support = []
[dependencies]
anyhow = "1.0"
arc-swap = ">=0.4.4"
byteorder = "1.3.4"
devices = { path = "../devices" }
epoll = ">=4.0.1"
libc = "0.2.71"
log = "0.4.8"
net_gen = { path = "../net_gen" }
net_util = { path = "../net_util" }
pci = { path = "../pci", optional = true }
serde = ">=1.0.27"
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
tempfile = "3.1.0"
virtio-bindings = { version = "0.1", features = ["virtio-v5_0_0"]}
vfio-ioctls = { git = "https://github.com/cloud-hypervisor/vfio-ioctls", branch = "ch" }
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = { version = "0.2.1", features = ["backend-mmap", "backend-atomic"] }
vm-migration = { path = "../vm-migration" }
vmm-sys-util = ">=0.3.1"
vhost_rs = { git = "https://github.com/cloud-hypervisor/vhost", branch = "dragonball", package = "vhost", features = ["vhost-user-master", "vhost-user-slave"] }
vm-memory = { version = "0.2.1", features = ["backend-mmap", "backend-atomic"] }

View File

@ -8,64 +8,20 @@
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
//! Implements virtio devices, queues, and transport mechanisms.
//! Implements virtio queues
extern crate arc_swap;
extern crate epoll;
#[macro_use]
extern crate log;
#[cfg(feature = "pci_support")]
extern crate pci;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate vhost_rs;
extern crate virtio_bindings;
extern crate vm_device;
extern crate vm_memory;
use std::fmt;
use std::io;
#[macro_use]
mod device;
pub mod block;
mod console;
mod iommu;
pub mod mem;
pub mod net;
pub mod net_util;
mod pmem;
pub mod queue;
mod rng;
pub mod vsock;
pub use queue::*;
pub mod transport;
pub mod vhost_user;
pub use self::block::*;
pub use self::console::*;
pub use self::device::*;
pub use self::iommu::*;
pub use self::mem::*;
pub use self::net::*;
pub use self::net_util::*;
pub use self::pmem::*;
pub use self::queue::*;
pub use self::rng::*;
pub use self::vsock::*;
const DEVICE_INIT: u32 = 0x00;
const DEVICE_ACKNOWLEDGE: u32 = 0x01;
const DEVICE_DRIVER: u32 = 0x02;
const DEVICE_DRIVER_OK: u32 = 0x04;
const DEVICE_FEATURES_OK: u32 = 0x08;
const DEVICE_FAILED: u32 = 0x80;
const VIRTIO_F_VERSION_1: u32 = 32;
const VIRTIO_F_IOMMU_PLATFORM: u32 = 33;
const VIRTIO_F_IN_ORDER: u32 = 35;
pub type VirtioIommuRemapping =
Box<dyn Fn(u64) -> std::result::Result<u64, std::io::Error> + Send + Sync>;
// Types taken from linux/virtio_ids.h
#[derive(Copy, Clone, Debug)]
@ -134,61 +90,3 @@ impl fmt::Display for VirtioDeviceType {
write!(f, "{}", output)
}
}
#[allow(dead_code)]
const INTERRUPT_STATUS_USED_RING: u32 = 0x1;
#[allow(dead_code)]
const INTERRUPT_STATUS_CONFIG_CHANGED: u32 = 0x2;
#[cfg(feature = "pci_support")]
const VIRTIO_MSI_NO_VECTOR: u16 = 0xffff;
#[derive(Debug)]
pub enum ActivateError {
EpollCtl(std::io::Error),
BadActivate,
/// Queue number is not correct
BadQueueNum,
/// Failed to clone Kill event
CloneKillEventFd,
/// Failed to create Vhost-user interrupt eventfd
VhostIrqCreate,
/// Failed to setup vhost-user daemon.
VhostUserSetup(vhost_user::Error),
/// Failed to setup vhost-user daemon.
VhostUserNetSetup(vhost_user::Error),
/// Failed to setup vhost-user daemon.
VhostUserBlkSetup(vhost_user::Error),
/// Failed to reset vhost-user daemon.
VhostUserReset(vhost_user::Error),
}
pub type ActivateResult = std::result::Result<(), ActivateError>;
pub type DeviceEventT = u16;
#[derive(Debug)]
pub enum Error {
FailedReadingQueue {
event_type: &'static str,
underlying: io::Error,
},
FailedReadTap,
FailedSignalingUsedQueue(io::Error),
PayloadExpected,
UnknownEvent {
device: &'static str,
event: DeviceEventT,
},
IoError(io::Error),
RegisterListener(io::Error),
UnregisterListener(io::Error),
EpollCreateFd(io::Error),
EpollCtl(io::Error),
EpollWait(io::Error),
FailedSignalingDriver(io::Error),
VhostUserUpdateMemory(vhost_user::Error),
EventfdError(io::Error),
SetShmRegionsNotSupported,
EpollHander(String),
NoMemoryConfigured,
}

View File

@ -8,22 +8,21 @@
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use crate::VirtioIommuRemapping;
use std::cmp::min;
use std::convert::TryInto;
use std::fmt::{self, Display};
use std::num::Wrapping;
use std::sync::atomic::{fence, Ordering};
use std::sync::Arc;
use crate::device::VirtioIommuRemapping;
use vm_memory::{
Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap,
GuestUsize,
};
pub(super) const VIRTQ_DESC_F_NEXT: u16 = 0x1;
pub(super) const VIRTQ_DESC_F_WRITE: u16 = 0x2;
pub(super) const VIRTQ_DESC_F_INDIRECT: u16 = 0x4;
pub const VIRTQ_DESC_F_NEXT: u16 = 0x1;
pub const VIRTQ_DESC_F_WRITE: u16 = 0x2;
pub const VIRTQ_DESC_F_INDIRECT: u16 = 0x4;
#[derive(Debug)]
pub enum Error {
@ -718,15 +717,12 @@ impl Queue {
}
}
#[cfg(test)]
pub(crate) mod tests {
extern crate vm_memory;
pub mod testing {
use super::*;
use std::marker::PhantomData;
use std::mem;
pub use super::*;
use vm_memory::{GuestAddress, GuestMemoryMmap, GuestUsize};
use vm_memory::Bytes;
use vm_memory::{Address, GuestAddress, GuestMemoryMmap, GuestUsize};
// Represents a location in GuestMemoryMmap which holds a given type.
pub struct SomeplaceInMemory<'a, T> {
@ -790,7 +786,7 @@ pub(crate) mod tests {
}
impl<'a> VirtqDesc<'a> {
fn new(start: GuestAddress, mem: &'a GuestMemoryMmap) -> Self {
pub fn new(start: GuestAddress, mem: &'a GuestMemoryMmap) -> Self {
assert_eq!(start.0 & 0xf, 0);
let addr = SomeplaceInMemory::new(start, mem);
@ -930,15 +926,15 @@ pub(crate) mod tests {
self.dtable.len() as u16
}
fn dtable_start(&self) -> GuestAddress {
pub fn dtable_start(&self) -> GuestAddress {
self.dtable.first().unwrap().start()
}
fn avail_start(&self) -> GuestAddress {
pub fn avail_start(&self) -> GuestAddress {
self.avail.flags.location
}
fn used_start(&self) -> GuestAddress {
pub fn used_start(&self) -> GuestAddress {
self.used.flags.location
}
@ -963,6 +959,15 @@ pub(crate) mod tests {
self.used.end()
}
}
}
#[cfg(test)]
pub mod tests {
extern crate vm_memory;
use super::testing::*;
pub use super::*;
use vm_memory::{GuestAddress, GuestMemoryMmap};
#[test]
fn test_checked_new_descriptor_chain() {

View File

@ -7,8 +7,8 @@ edition = "2018"
[features]
default = []
acpi = ["acpi_tables","devices/acpi", "arch/acpi"]
pci_support = ["pci", "vfio-ioctls", "vm-virtio/pci_support"]
mmio_support = ["vm-virtio/mmio_support"]
pci_support = ["pci", "vfio-ioctls", "virtio-devices/pci_support"]
mmio_support = ["virtio-devices/mmio_support"]
cmos = ["devices/cmos"]
fwdebug = ["devices/fwdebug"]
@ -34,6 +34,7 @@ serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
url = "2.1.1"
vfio-ioctls = { git = "https://github.com/cloud-hypervisor/vfio-ioctls", branch = "ch", optional = true }
virtio-devices = {path = "../virtio-devices"}
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-memory = { version = "0.2.1", features = ["backend-mmap", "backend-atomic"] }

View File

@ -3,8 +3,6 @@
// SPDX-License-Identifier: Apache-2.0
//
extern crate vm_virtio;
use clap::ArgMatches;
use net_util::MacAddr;
use std::collections::HashMap;

View File

@ -63,6 +63,13 @@ use std::sync::{Arc, Mutex};
use tempfile::NamedTempFile;
#[cfg(feature = "pci_support")]
use vfio_ioctls::{VfioContainer, VfioDevice, VfioDmaMapping};
#[cfg(feature = "pci_support")]
use virtio_devices::transport::VirtioPciDevice;
use virtio_devices::transport::VirtioTransport;
use virtio_devices::vhost_user::VhostUserConfig;
#[cfg(feature = "pci_support")]
use virtio_devices::{DmaRemapping, IommuMapping};
use virtio_devices::{VirtioSharedMemory, VirtioSharedMemoryList};
use vm_allocator::SystemAllocator;
use vm_device::interrupt::{
InterruptIndex, InterruptManager, LegacyIrqGroupConfig, MsiIrqGroupConfig,
@ -77,12 +84,7 @@ use vm_migration::{
Transportable,
};
#[cfg(feature = "pci_support")]
use vm_virtio::transport::VirtioPciDevice;
use vm_virtio::transport::VirtioTransport;
use vm_virtio::vhost_user::VhostUserConfig;
#[cfg(feature = "pci_support")]
use vm_virtio::{DmaRemapping, IommuMapping, VirtioDeviceType, VirtioIommuRemapping};
use vm_virtio::{VirtioSharedMemory, VirtioSharedMemoryList};
use vm_virtio::{VirtioDeviceType, VirtioIommuRemapping};
use vmm_sys_util::eventfd::EventFd;
#[cfg(feature = "mmio_support")]
@ -125,13 +127,13 @@ pub enum DeviceManagerError {
Disk(io::Error),
/// Cannot create vhost-user-net device
CreateVhostUserNet(vm_virtio::vhost_user::Error),
CreateVhostUserNet(virtio_devices::vhost_user::Error),
/// Cannot create virtio-blk device
CreateVirtioBlock(io::Error),
/// Cannot create virtio-net device
CreateVirtioNet(vm_virtio::net::Error),
CreateVirtioNet(virtio_devices::net::Error),
/// Cannot create virtio-console device
CreateVirtioConsole(io::Error),
@ -140,13 +142,13 @@ pub enum DeviceManagerError {
CreateVirtioRng(io::Error),
/// Cannot create virtio-fs device
CreateVirtioFs(vm_virtio::vhost_user::Error),
CreateVirtioFs(virtio_devices::vhost_user::Error),
/// Virtio-fs device was created without a socket.
NoVirtioFsSock,
/// Cannot create vhost-user-blk device
CreateVhostUserBlk(vm_virtio::vhost_user::Error),
CreateVhostUserBlk(virtio_devices::vhost_user::Error),
/// Cannot create virtio-pmem device
CreateVirtioPmem(io::Error),
@ -158,7 +160,7 @@ pub enum DeviceManagerError {
CreateVsockConvertPath,
/// Cannot create virtio-vsock backend
CreateVsockBackend(vm_virtio::vsock::VsockUnixError),
CreateVsockBackend(virtio_devices::vsock::VsockUnixError),
/// Cannot create virtio-iommu device
CreateVirtioIommu(io::Error),
@ -321,13 +323,13 @@ pub enum DeviceManagerError {
NoDiskPath,
/// Failed updating guest memory for virtio device.
UpdateMemoryForVirtioDevice(vm_virtio::Error),
UpdateMemoryForVirtioDevice(virtio_devices::Error),
/// Cannot create virtio-mem device
CreateVirtioMem(io::Error),
/// Cannot try Clone virtio-mem resize
TryCloneVirtioMemResize(vm_virtio::mem::Error),
TryCloneVirtioMemResize(virtio_devices::mem::Error),
/// Cannot find a memory range for virtio-mem memory
VirtioMemRangeAllocation,
@ -366,7 +368,7 @@ pub enum DeviceManagerError {
}
pub type DeviceManagerResult<T> = result::Result<T, DeviceManagerError>;
type VirtioDeviceArc = Arc<Mutex<dyn vm_virtio::VirtioDevice>>;
type VirtioDeviceArc = Arc<Mutex<dyn virtio_devices::VirtioDevice>>;
pub fn get_win_size() -> (u16, u16) {
#[repr(C)]
@ -390,7 +392,7 @@ pub fn get_win_size() -> (u16, u16) {
pub struct Console {
// Serial port on 0x3f8
serial: Option<Arc<Mutex<Serial>>>,
console_input: Option<Arc<vm_virtio::ConsoleInput>>,
console_input: Option<Arc<virtio_devices::ConsoleInput>>,
input_enabled: bool,
}
@ -728,7 +730,7 @@ pub struct DeviceManager {
// Paravirtualized IOMMU
#[cfg(feature = "pci_support")]
iommu_device: Option<Arc<Mutex<vm_virtio::Iommu>>>,
iommu_device: Option<Arc<Mutex<virtio_devices::Iommu>>>,
// Bitmap of PCI devices to hotplug.
#[cfg(feature = "pci_support")]
@ -962,7 +964,7 @@ impl DeviceManager {
let iommu_id = String::from(IOMMU_DEVICE_NAME);
let (iommu_device, iommu_mapping) = if self.config.lock().unwrap().iommu {
let (device, mapping) = vm_virtio::Iommu::new(iommu_id.clone())
let (device, mapping) = virtio_devices::Iommu::new(iommu_id.clone())
.map_err(DeviceManagerError::CreateVirtioIommu)?;
let device = Arc::new(Mutex::new(device));
self.iommu_device = Some(Arc::clone(&device));
@ -1451,7 +1453,7 @@ impl DeviceManager {
let id = String::from(CONSOLE_DEVICE_NAME);
let (virtio_console_device, console_input) =
vm_virtio::Console::new(id.clone(), writer, col, row, console_config.iommu)
virtio_devices::Console::new(id.clone(), writer, col, row, console_config.iommu)
.map_err(DeviceManagerError::CreateVirtioConsole)?;
let virtio_console_device = Arc::new(Mutex::new(virtio_console_device));
virtio_devices.push((
@ -1560,7 +1562,7 @@ impl DeviceManager {
queue_size: disk_cfg.queue_size,
};
let vhost_user_block_device = Arc::new(Mutex::new(
vm_virtio::vhost_user::Blk::new(id.clone(), vu_cfg)
virtio_devices::vhost_user::Blk::new(id.clone(), vu_cfg)
.map_err(DeviceManagerError::CreateVhostUserBlk)?,
));
@ -1595,13 +1597,13 @@ impl DeviceManager {
)
.map_err(DeviceManagerError::Disk)?;
let mut raw_img = vm_virtio::RawFile::new(image, disk_cfg.direct);
let mut raw_img = virtio_devices::RawFile::new(image, disk_cfg.direct);
let image_type = qcow::detect_image_type(&mut raw_img)
.map_err(DeviceManagerError::DetectImageType)?;
match image_type {
ImageType::Raw => {
let dev = vm_virtio::Block::new(
let dev = virtio_devices::Block::new(
id.clone(),
raw_img,
disk_cfg
@ -1631,7 +1633,7 @@ impl DeviceManager {
ImageType::Qcow2 => {
let qcow_img =
QcowFile::from(raw_img).map_err(DeviceManagerError::QcowDeviceCreate)?;
let dev = vm_virtio::Block::new(
let dev = virtio_devices::Block::new(
id.clone(),
qcow_img,
disk_cfg
@ -1736,7 +1738,7 @@ impl DeviceManager {
queue_size: net_cfg.queue_size,
};
let vhost_user_net_device = Arc::new(Mutex::new(
vm_virtio::vhost_user::Net::new(id.clone(), net_cfg.mac, vu_cfg)
virtio_devices::vhost_user::Net::new(id.clone(), net_cfg.mac, vu_cfg)
.map_err(DeviceManagerError::CreateVhostUserNet)?,
));
@ -1756,7 +1758,7 @@ impl DeviceManager {
} else {
let virtio_net_device = if let Some(ref tap_if_name) = net_cfg.tap {
Arc::new(Mutex::new(
vm_virtio::Net::new(
virtio_devices::Net::new(
id.clone(),
Some(tap_if_name),
None,
@ -1771,7 +1773,7 @@ impl DeviceManager {
))
} else {
Arc::new(Mutex::new(
vm_virtio::Net::new(
virtio_devices::Net::new(
id.clone(),
None,
Some(net_cfg.ip),
@ -1829,7 +1831,7 @@ impl DeviceManager {
let id = String::from(RNG_DEVICE_NAME);
let virtio_rng_device = Arc::new(Mutex::new(
vm_virtio::Rng::new(id.clone(), rng_path, rng_config.iommu)
virtio_devices::Rng::new(id.clone(), rng_path, rng_config.iommu)
.map_err(DeviceManagerError::CreateVirtioRng)?,
));
devices.push((
@ -1969,7 +1971,7 @@ impl DeviceManager {
};
let virtio_fs_device = Arc::new(Mutex::new(
vm_virtio::vhost_user::Fs::new(
virtio_devices::vhost_user::Fs::new(
id.clone(),
fs_socket,
&fs_cfg.tag,
@ -2142,7 +2144,7 @@ impl DeviceManager {
)
.map_err(DeviceManagerError::MemoryManager)?;
let mapping = vm_virtio::UserspaceMapping {
let mapping = virtio_devices::UserspaceMapping {
host_addr,
mem_slot,
addr: GuestAddress(region_base),
@ -2151,7 +2153,7 @@ impl DeviceManager {
};
let virtio_pmem_device = Arc::new(Mutex::new(
vm_virtio::Pmem::new(
virtio_devices::Pmem::new(
id.clone(),
file,
GuestAddress(region_base),
@ -2211,11 +2213,11 @@ impl DeviceManager {
.to_str()
.ok_or(DeviceManagerError::CreateVsockConvertPath)?;
let backend =
vm_virtio::vsock::VsockUnixBackend::new(vsock_cfg.cid, socket_path.to_string())
virtio_devices::vsock::VsockUnixBackend::new(vsock_cfg.cid, socket_path.to_string())
.map_err(DeviceManagerError::CreateVsockBackend)?;
let vsock_device = Arc::new(Mutex::new(
vm_virtio::Vsock::new(
virtio_devices::Vsock::new(
id.clone(),
vsock_cfg.cid,
vsock_cfg.socket.clone(),
@ -2265,7 +2267,7 @@ impl DeviceManager {
let id = String::from(MEM_DEVICE_NAME);
let virtio_mem_device = Arc::new(Mutex::new(
vm_virtio::Mem::new(
virtio_devices::Mem::new(
id.clone(),
&region,
resize
@ -2735,7 +2737,7 @@ impl DeviceManager {
let memory = self.memory_manager.lock().unwrap().guest_memory();
let mut mmio_device =
vm_virtio::transport::MmioDevice::new(id.clone(), memory, virtio_device)
virtio_devices::transport::MmioDevice::new(id.clone(), memory, virtio_device)
.map_err(DeviceManagerError::VirtioDevice)?;
for (i, (event, addr)) in mmio_device.ioeventfds(mmio_base).iter().enumerate() {

View File

@ -66,7 +66,7 @@ pub struct MemoryManager {
current_ram: u64,
next_hotplug_slot: usize,
pub virtiomem_region: Option<Arc<GuestRegionMmap>>,
pub virtiomem_resize: Option<vm_virtio::Resize>,
pub virtiomem_resize: Option<virtio_devices::Resize>,
snapshot: Mutex<Option<GuestMemoryLoadGuard<GuestMemoryMmap>>>,
shared: bool,
hugepages: bool,
@ -111,7 +111,7 @@ pub enum Error {
EventfdError(io::Error),
/// Failed to virtio-mem resize
VirtioMemResizeFail(vm_virtio::mem::Error),
VirtioMemResizeFail(virtio_devices::mem::Error),
/// Cannot restore VM
Restore(MigratableError),
@ -271,9 +271,9 @@ impl MemoryManager {
if config.hotplug_method == HotplugMethod::VirtioMem {
// Alignment must be "natural" i.e. same as size of block
let start_addr = GuestAddress(
(start_of_device_area.0 + vm_virtio::VIRTIO_MEM_DEFAULT_BLOCK_SIZE - 1)
/ vm_virtio::VIRTIO_MEM_DEFAULT_BLOCK_SIZE
* vm_virtio::VIRTIO_MEM_DEFAULT_BLOCK_SIZE,
(start_of_device_area.0 + virtio_devices::VIRTIO_MEM_DEFAULT_BLOCK_SIZE - 1)
/ virtio_devices::VIRTIO_MEM_DEFAULT_BLOCK_SIZE
* virtio_devices::VIRTIO_MEM_DEFAULT_BLOCK_SIZE,
);
virtiomem_region = Some(MemoryManager::create_ram_region(
&config.file,
@ -285,7 +285,7 @@ impl MemoryManager {
config.hugepages,
)?);
virtiomem_resize = Some(vm_virtio::Resize::new().map_err(Error::EventFdFail)?);
virtiomem_resize = Some(virtio_devices::Resize::new().map_err(Error::EventFdFail)?);
start_of_device_area = start_addr.unchecked_add(size);
} else {

View File

@ -22,7 +22,6 @@ extern crate signal_hook;
#[cfg(feature = "pci_support")]
extern crate vm_allocator;
extern crate vm_memory;
extern crate vm_virtio;
use crate::config::{
DeviceConfig, DiskConfig, FsConfig, HotplugMethod, NetConfig, PmemConfig, ValidationError,