Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion vhost-user-backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ where
V: VringT<GM<B>> + Clone + Send + Sync + 'static,
B: Bitmap + 'static,
{
pub fn new(name: String, backend: S, atomic_mem: GuestMemoryAtomic<GuestMemoryMmap<B>>) -> Result<Self>;
pub fn new(name: String, backend: S, atomic_mem: GM<B>) -> Result<Self>;
pub fn start(&mut self, listener: Listener) -> Result<()>;
pub fn wait(&mut self) -> Result<()>;
pub fn get_epoll_handlers(&self) -> Vec<Arc<VringEpollHandler<S, V, B>>>;
Expand Down
2 changes: 1 addition & 1 deletion vhost-user-backend/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ pub mod tests {
Ok(())
}

fn update_memory(&mut self, _atomic_mem: GuestMemoryAtomic<GuestMemoryMmap>) -> Result<()> {
fn update_memory(&mut self, _atomic_mem: GM) -> Result<()> {
Ok(())
}

Expand Down
18 changes: 4 additions & 14 deletions vhost-user-backend/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use vhost::vhost_user::{
use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
use virtio_queue::{Error as VirtQueError, QueueT};
use vm_memory::mmap::NewBitmap;
use vm_memory::{GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryMmap, GuestRegionMmap};
use vm_memory::{GuestAddress, GuestAddressSpace, GuestMemory, GuestRegionCollection};
use vmm_sys_util::epoll::EventSet;

use super::backend::VhostUserBackend;
Expand Down Expand Up @@ -314,11 +314,7 @@ where
let mut mappings: Vec<AddrMapping> = Vec::new();

for (region, file) in ctx.iter().zip(files) {
let guest_region = GuestRegionMmap::new(
region.mmap_region(file)?,
GuestAddress(region.guest_phys_addr),
)
.map_err(|e| VhostUserError::ReqHandlerError(io::Error::other(e)))?;
let guest_region = region.memory_region(file)?;
mappings.push(AddrMapping {
#[cfg(feature = "postcopy")]
local_addr: guest_region.as_ptr() as u64,
Expand All @@ -329,7 +325,7 @@ where
regions.push(guest_region);
}

let mem = GuestMemoryMmap::from_regions(regions)
let mem = GuestRegionCollection::from_regions(regions)
.map_err(|e| VhostUserError::ReqHandlerError(io::Error::other(e)))?;

// Updating the inner GuestMemory object here will cause all our vrings to
Expand Down Expand Up @@ -601,13 +597,7 @@ where
region: &VhostUserSingleMemoryRegion,
file: File,
) -> VhostUserResult<()> {
let guest_region = Arc::new(
GuestRegionMmap::new(
region.mmap_region(file)?,
GuestAddress(region.guest_phys_addr),
)
.map_err(|e| VhostUserError::ReqHandlerError(io::Error::other(e)))?,
);
let guest_region = Arc::new(region.memory_region(file)?);

let addr_mapping = AddrMapping {
#[cfg(feature = "postcopy")]
Expand Down
14 changes: 5 additions & 9 deletions vhost-user-backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ use std::path::Path;
use std::sync::{Arc, Mutex};
use std::thread;

use self::handler::VhostUserHandler;
use vhost::vhost_user::{BackendListener, BackendReqHandler, Error as VhostUserError, Listener};
use vhost::MemoryRegion;
use vm_memory::mmap::NewBitmap;
use vm_memory::{GuestMemoryAtomic, GuestMemoryMmap};

use self::handler::VhostUserHandler;
use vm_memory::{GuestMemoryAtomic, GuestRegionCollection};

mod backend;
pub use self::backend::{VhostUserBackend, VhostUserBackendMut};
Expand All @@ -43,7 +43,7 @@ pub use self::vring::{
compile_error!("Both `postcopy` and `xen` features can not be enabled at the same time.");

/// An alias for `GuestMemoryAtomic<GuestMemoryMmap<B>>` to simplify code.
type GM<B> = GuestMemoryAtomic<GuestMemoryMmap<B>>;
type GM<B = ()> = GuestMemoryAtomic<GuestRegionCollection<MemoryRegion<B>>>;

#[derive(Debug)]
/// Errors related to vhost-user daemon.
Expand Down Expand Up @@ -106,11 +106,7 @@ where
/// Under the hood, this will start a dedicated thread responsible for listening onto
/// registered event. Those events can be vring events or custom events from the backend,
/// but they get to be registered later during the sequence.
pub fn new(
name: String,
backend: T,
atomic_mem: GuestMemoryAtomic<GuestMemoryMmap<T::Bitmap>>,
) -> Result<Self> {
pub fn new(name: String, backend: T, atomic_mem: GM<T::Bitmap>) -> Result<Self> {
let handler = Arc::new(Mutex::new(
VhostUserHandler::new(backend, atomic_mem).map_err(Error::NewVhostUserHandler)?,
));
Expand Down
9 changes: 5 additions & 4 deletions vhost-user-backend/src/vring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ use std::result::Result;
use std::sync::atomic::Ordering;
use std::sync::{Arc, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};

use crate::GM;
use virtio_queue::{Error as VirtQueError, Queue, QueueT};
use vm_memory::{GuestAddress, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap};
use vm_memory::{GuestAddress, GuestAddressSpace};
use vmm_sys_util::event::{EventConsumer, EventNotifier};

/// Trait for objects returned by `VringT::get_ref()`.
Expand Down Expand Up @@ -107,7 +108,7 @@ pub trait VringT<M: GuestAddressSpace>:
///
/// This struct maintains all information of a virito queue, and could be used as an `VringT`
/// object for single-threaded context.
pub struct VringState<M: GuestAddressSpace = GuestMemoryAtomic<GuestMemoryMmap>> {
pub struct VringState<M: GuestAddressSpace = GM> {
queue: Queue,
kick: Option<EventConsumer>,
call: Option<EventNotifier>,
Expand Down Expand Up @@ -269,7 +270,7 @@ impl<M: GuestAddressSpace> VringState<M> {

/// A `VringState` object protected by Mutex for multi-threading context.
#[derive(Clone)]
pub struct VringMutex<M: GuestAddressSpace = GuestMemoryAtomic<GuestMemoryMmap>> {
pub struct VringMutex<M: GuestAddressSpace = GM> {
state: Arc<Mutex<VringState<M>>>,
}

Expand Down Expand Up @@ -384,7 +385,7 @@ impl<M: 'static + GuestAddressSpace> VringT<M> for VringMutex<M> {

/// A `VringState` object protected by RwLock for multi-threading context.
#[derive(Clone)]
pub struct VringRwLock<M: GuestAddressSpace = GuestMemoryAtomic<GuestMemoryMmap>> {
pub struct VringRwLock<M: GuestAddressSpace = GM> {
state: Arc<RwLock<VringState<M>>>,
}

Expand Down
2 changes: 1 addition & 1 deletion vhost-user-backend/tests/vhost-user-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl VhostUserBackendMut for MockVhostBackend {
Ok(())
}

fn update_memory(&mut self, atomic_mem: GuestMemoryAtomic<GuestMemoryMmap>) -> Result<()> {
fn update_memory(&mut self, atomic_mem: GM) -> Result<()> {
let mem = atomic_mem.memory();
let region = mem.find_region(GuestAddress(0x100000)).unwrap();
assert_eq!(region.size(), 0x100000);
Expand Down
84 changes: 46 additions & 38 deletions vhost/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ use std::os::unix::io::AsRawFd;
use std::os::unix::io::RawFd;
use std::sync::RwLock;

#[cfg(feature = "xen")]
use vm_memory::GuestRegionXen;
use vm_memory::{bitmap::Bitmap, Address, GuestMemoryRegion, GuestRegionMmap};
use vmm_sys_util::eventfd::EventFd;

Expand Down Expand Up @@ -86,61 +88,67 @@ pub struct VhostUserMemoryRegionInfo {
pub xen_mmap_data: u32,
}

impl VhostUserMemoryRegionInfo {
/// Creates Self from GuestRegionMmap.
pub fn from_guest_region<B: Bitmap>(region: &GuestRegionMmap<B>) -> Result<Self> {
#[cfg(feature = "vhost-user")]
impl From<&VhostUserMemoryRegionInfo> for VhostUserMemoryRegion {
fn from(region: &VhostUserMemoryRegionInfo) -> Self {
VhostUserMemoryRegion {
guest_phys_addr: region.guest_phys_addr,
memory_size: region.memory_size,
user_addr: region.userspace_addr,
mmap_offset: region.mmap_offset,
#[cfg(feature = "xen")]
xen_mmap_flags: region.xen_mmap_flags,
#[cfg(feature = "xen")]
xen_mmap_data: region.xen_mmap_data,
}
}
}

impl<B: Bitmap> TryFrom<&GuestRegionMmap<B>> for VhostUserMemoryRegionInfo {
type Error = Error;

fn try_from(region: &GuestRegionMmap<B>) -> Result<Self> {
let file_offset = region
.file_offset()
.ok_or(Error::InvalidGuestMemoryRegion)?;

Ok(Self {
Ok(VhostUserMemoryRegionInfo {
guest_phys_addr: region.start_addr().raw_value(),
memory_size: region.len(),
userspace_addr: region.as_ptr() as u64,
mmap_offset: file_offset.start(),
mmap_handle: file_offset.file().as_raw_fd(),
#[cfg(feature = "xen")]
xen_mmap_flags: region.xen_mmap_flags(),
#[cfg(feature = "xen")]
xen_mmap_data: region.xen_mmap_data(),
..Default::default()
})
}
}

/// Creates VhostUserMemoryRegion from Self.
#[cfg(feature = "vhost-user")]
pub fn to_region(&self) -> VhostUserMemoryRegion {
#[cfg(not(feature = "xen"))]
return VhostUserMemoryRegion::new(
self.guest_phys_addr,
self.memory_size,
self.userspace_addr,
self.mmap_offset,
);

#[cfg(feature = "xen")]
VhostUserMemoryRegion::with_xen(
self.guest_phys_addr,
self.memory_size,
self.userspace_addr,
self.mmap_offset,
self.xen_mmap_flags,
self.xen_mmap_data,
)
#[cfg(feature = "xen")]
impl<B: Bitmap> TryFrom<&GuestRegionXen<B>> for VhostUserMemoryRegionInfo {
type Error = Error;

fn try_from(region: &GuestRegionXen<B>) -> std::result::Result<Self, Self::Error> {
let file_offset = region
.file_offset()
.ok_or(Error::InvalidGuestMemoryRegion)?;

Ok(VhostUserMemoryRegionInfo {
guest_phys_addr: region.start_addr().raw_value(),
memory_size: region.len(),
userspace_addr: region.as_ptr() as u64,
mmap_offset: file_offset.start(),
mmap_handle: file_offset.file().as_raw_fd(),
xen_mmap_flags: region.xen_mmap_flags(),
xen_mmap_data: region.xen_mmap_data(),
})
}
}

impl VhostUserMemoryRegionInfo {
/// Creates VhostUserSingleMemoryRegion from Self.
#[cfg(feature = "vhost-user")]
pub fn to_single_region(&self) -> VhostUserSingleMemoryRegion {
VhostUserSingleMemoryRegion::new(
self.guest_phys_addr,
self.memory_size,
self.userspace_addr,
self.mmap_offset,
#[cfg(feature = "xen")]
self.xen_mmap_flags,
#[cfg(feature = "xen")]
self.xen_mmap_data,
)
self.into()
}
}

Expand Down
81 changes: 79 additions & 2 deletions vhost/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,23 @@
//! that shares its virtqueues. Backend is the consumer of the virtqueues. Frontend and backend can be
//! either a client (i.e. connecting) or server (listening) in the socket communication.

#![deny(missing_docs)]

#[cfg_attr(feature = "vhost-user", macro_use)]
extern crate bitflags;
#[cfg_attr(feature = "vhost-kern", macro_use)]
extern crate vmm_sys_util;

mod backend;

use std::ops::Deref;

pub use backend::*;
use vm_memory::bitmap::{Bitmap, BS};
#[cfg(feature = "xen")]
use vm_memory::GuestRegionXen;
use vm_memory::{
GuestAddress, GuestMemoryRegion, GuestMemoryRegionBytes, GuestRegionMmap, GuestUsize,
MemoryRegionAddress, VolatileSlice,
};

#[cfg(feature = "vhost-net")]
pub mod net;
Expand Down Expand Up @@ -128,6 +136,75 @@ impl std::convert::From<vhost_user::Error> for Error {
/// Result of vhost operations
pub type Result<T> = std::result::Result<T, Error>;

pub enum MemoryRegion<B> {
Unix(GuestRegionMmap<B>),
#[cfg(feature = "xen")]
Xen(GuestRegionXen<B>),
}

impl<B: Bitmap> MemoryRegion<B> {
pub fn bitmap(&self) -> &B {
match self {
MemoryRegion::Unix(r) => (*r).deref().bitmap(),
#[cfg(feature = "xen")]
MemoryRegion::Xen(r) => r.bitmap(),
}
}
}

impl<B: Bitmap> GuestMemoryRegion for MemoryRegion<B> {
type B = B;

fn len(&self) -> GuestUsize {
match self {
MemoryRegion::Unix(r) => r.len(),
#[cfg(feature = "xen")]
MemoryRegion::Xen(r) => r.len(),
}
}

fn start_addr(&self) -> GuestAddress {
match self {
MemoryRegion::Unix(r) => r.start_addr(),
#[cfg(feature = "xen")]
MemoryRegion::Xen(r) => r.start_addr(),
}
}

fn bitmap(&self) -> BS<'_, Self::B> {
match self {
MemoryRegion::Unix(r) => r.bitmap(),
#[cfg(feature = "xen")]
MemoryRegion::Xen(r) => <GuestRegionXen<B> as GuestMemoryRegion>::bitmap(r),
}
}

fn get_host_address(
&self,
addr: MemoryRegionAddress,
) -> vm_memory::guest_memory::Result<*mut u8> {
match self {
MemoryRegion::Unix(r) => r.get_host_address(addr),
#[cfg(feature = "xen")]
MemoryRegion::Xen(r) => r.get_host_address(addr),
}
}

fn get_slice(
&self,
offset: MemoryRegionAddress,
count: usize,
) -> vm_memory::guest_memory::Result<VolatileSlice<BS<Self::B>>> {
match self {
MemoryRegion::Unix(r) => r.get_slice(offset, count),
#[cfg(feature = "xen")]
MemoryRegion::Xen(r) => r.get_slice(offset, count),
}
}
}

impl<B: Bitmap> GuestMemoryRegionBytes for MemoryRegion<B> {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
2 changes: 1 addition & 1 deletion vhost/src/vhost_user/frontend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ impl VhostBackend for Frontend {
return error_code(VhostUserError::InvalidParam);
}

ctx.append(&region.to_region(), region.mmap_handle);
ctx.append(&region.into(), region.mmap_handle);
}

let mut node = self.node();
Expand Down
Loading