diff options
author | Alyssa Ross <hi@alyssa.is> | 2020-08-11 10:49:38 +0000 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2021-05-11 12:19:50 +0000 |
commit | fe5750a3854c98635755cd9d0ceb05de896c0e67 (patch) | |
tree | 28955f2094e0903a268e4f99eb684d27f1d521fe /vhost_rs/src/lib.rs | |
parent | 8a7e4e902a4950b060ea23b40c0dfce7bfa1b2cb (diff) | |
download | crosvm-fe5750a3854c98635755cd9d0ceb05de896c0e67.tar crosvm-fe5750a3854c98635755cd9d0ceb05de896c0e67.tar.gz crosvm-fe5750a3854c98635755cd9d0ceb05de896c0e67.tar.bz2 crosvm-fe5750a3854c98635755cd9d0ceb05de896c0e67.tar.lz crosvm-fe5750a3854c98635755cd9d0ceb05de896c0e67.tar.xz crosvm-fe5750a3854c98635755cd9d0ceb05de896c0e67.tar.zst crosvm-fe5750a3854c98635755cd9d0ceb05de896c0e67.zip |
devices: port vhost-user-net from cloud-hypervisor
This is the cloud-hypervisor vhost-user-net code, modified just enough to compile as part of crosvm. There is currently no way to run crosvm with a vhost-user-net device, and even if there were, it wouldn't work without some further fixes.
Diffstat (limited to 'vhost_rs/src/lib.rs')
-rw-r--r-- | vhost_rs/src/lib.rs | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/vhost_rs/src/lib.rs b/vhost_rs/src/lib.rs new file mode 100644 index 0000000..2a73aaf --- /dev/null +++ b/vhost_rs/src/lib.rs @@ -0,0 +1,122 @@ +// Copyright (C) 2019 Alibaba Cloud Computing. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause +// +// Portions 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 file. + +//! Virtio Vhost Backend Drivers +//! +//! Virtio devices use virtqueues to transport data efficiently. Virtqueue is a set of three +//! different single-producer, single-consumer ring structures designed to store generic +//! scatter-gather I/O. +//! +//! Vhost is a mechanism to improve performance of Virtio devices by delegate data plane operations +//! to dedicated IO service processes. Only the configuration, I/O submission notification, and I/O +//! completion interruption are piped through the hypervisor. +//! It uses the same virtqueue layout as Virtio to allow Vhost devices to be mapped directly to +//! Virtio devices. This allows a Vhost device to be accessed directly by a guest OS inside a +//! hypervisor process with an existing Virtio (PCI) driver. +//! +//! The initial vhost implementation is a part of the Linux kernel and uses ioctl interface to +//! communicate with userspace applications. Dedicated kernel worker threads are created to handle +//! IO requests from the guest. +//! +//! Later Vhost-user protocol is introduced to complement the ioctl interface used to control the +//! vhost implementation in the Linux kernel. It implements the control plane needed to establish +//! virtqueues sharing with a user space process on the same host. It uses communication over a +//! Unix domain socket to share file descriptors in the ancillary data of the message. +//! The protocol defines 2 sides of the communication, master and slave. Master is the application +//! that shares its virtqueues. Slave is the consumer of the virtqueues. Master and slave can be +//! either a client (i.e. connecting) or server (listening) in the socket communication. + +#![deny(missing_docs)] + +#[cfg_attr( + any(feature = "vhost-user-master", feature = "vhost-user-slave"), + macro_use +)] +extern crate bitflags; +extern crate libc; +#[cfg_attr(feature = "vhost-kern", macro_use)] +extern crate sys_util; +#[cfg(feature = "vhost-kern")] +extern crate vm_memory; +#[cfg_attr(feature = "vhost-kern", macro_use)] +extern crate vmm_sys_util; + +mod backend; +pub use backend::*; + +#[cfg(feature = "vhost-kern")] +pub mod vhost_kern; +#[cfg(any(feature = "vhost-user-master", feature = "vhost-user-slave"))] +pub mod vhost_user; +#[cfg(feature = "vhost-vsock")] +pub mod vsock; + +/// Error codes for vhost operations +#[derive(Debug)] +pub enum Error { + /// Invalid operations. + InvalidOperation, + /// Invalid guest memory. + InvalidGuestMemory, + /// Invalid guest memory region. + InvalidGuestMemoryRegion, + /// Invalid queue. + InvalidQueue, + /// Invalid descriptor table address. + DescriptorTableAddress, + /// Invalid used address. + UsedAddress, + /// Invalid available address. + AvailAddress, + /// Invalid log address. + LogAddress, + #[cfg(feature = "vhost-kern")] + /// Error opening the vhost backend driver. + VhostOpen(std::io::Error), + #[cfg(feature = "vhost-kern")] + /// Error while running ioctl. + IoctlError(std::io::Error), + /// Error from IO subsystem. + IOError(std::io::Error), + #[cfg(any(feature = "vhost-user-master", feature = "vhost-user-slave"))] + /// Error from the vhost-user subsystem. + VhostUserProtocol(vhost_user::Error), +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Error::InvalidOperation => write!(f, "invalid vhost operations"), + Error::InvalidGuestMemory => write!(f, "invalid guest memory object"), + Error::InvalidGuestMemoryRegion => write!(f, "invalid guest memory region"), + Error::InvalidQueue => write!(f, "invalid virtque"), + Error::DescriptorTableAddress => write!(f, "invalid virtque descriptor talbe address"), + Error::UsedAddress => write!(f, "invalid virtque used talbe address"), + Error::AvailAddress => write!(f, "invalid virtque available talbe address"), + Error::LogAddress => write!(f, "invalid virtque log address"), + Error::IOError(e) => write!(f, "IO error: {}", e), + #[cfg(feature = "vhost-kern")] + Error::VhostOpen(e) => write!(f, "failure in opening vhost file: {}", e), + #[cfg(feature = "vhost-kern")] + Error::IoctlError(e) => write!(f, "failure in vhost ioctl: {}", e), + #[cfg(any(feature = "vhost-user-master", feature = "vhost-user-slave"))] + Error::VhostUserProtocol(e) => write!(f, "vhost-user: {}", e), + } + } +} + +#[cfg(any(feature = "vhost-user-master", feature = "vhost-user-slave"))] +impl std::convert::From<vhost_user::Error> for Error { + fn from(err: vhost_user::Error) -> Self { + Error::VhostUserProtocol(err) + } +} + +/// Result of vhost operations +pub type Result<T> = std::result::Result<T, Error>; |