mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-11 04:26:38 +00:00
vhost_user_devices: Update VhostUserSlaveReqHandler interface
BUG=b:185089400 TEST=cargo test in /vhost_user_devices TEST=run net device Cq-Depend: chromium:2884020 Change-Id: I0fd2c9e1c6d97635356dc3e43ecfaf721a1fa5b8 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2884021 Reviewed-by: Noah Gold <nkgold@google.com> Reviewed-by: Chirantan Ekbote <chirantan@chromium.org> Commit-Queue: Keiichi Watanabe <keiichiw@chromium.org> Tested-by: Keiichi Watanabe <keiichiw@chromium.org>
This commit is contained in:
parent
0eed9a4ce3
commit
ef55773dd4
1 changed files with 35 additions and 38 deletions
|
@ -46,12 +46,16 @@
|
||||||
// implementation (this is what our devices implement).
|
// implementation (this is what our devices implement).
|
||||||
|
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
use std::fs::File;
|
||||||
use std::num::Wrapping;
|
use std::num::Wrapping;
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
use std::os::unix::io::AsRawFd;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use base::{error, Event, FromRawDescriptor, SafeDescriptor, SharedMemory, SharedMemoryUnix};
|
use base::{
|
||||||
|
error, Event, FromRawDescriptor, IntoRawDescriptor, SafeDescriptor, SharedMemory,
|
||||||
|
SharedMemoryUnix,
|
||||||
|
};
|
||||||
use cros_async::{AsyncError, AsyncWrapper, Executor};
|
use cros_async::{AsyncError, AsyncWrapper, Executor};
|
||||||
use devices::virtio::{Queue, SignalableInterrupt};
|
use devices::virtio::{Queue, SignalableInterrupt};
|
||||||
use remain::sorted;
|
use remain::sorted;
|
||||||
|
@ -60,7 +64,7 @@ use sys_util::clear_fd_flags;
|
||||||
use thiserror::Error as ThisError;
|
use thiserror::Error as ThisError;
|
||||||
use vm_memory::{GuestAddress, GuestMemory, MemoryRegion};
|
use vm_memory::{GuestAddress, GuestMemory, MemoryRegion};
|
||||||
use vmm_vhost::vhost_user::message::{
|
use vmm_vhost::vhost_user::message::{
|
||||||
VhostUserConfigFlags, VhostUserMemoryRegion, VhostUserProtocolFeatures,
|
VhostUserConfigFlags, VhostUserInflight, VhostUserMemoryRegion, VhostUserProtocolFeatures,
|
||||||
VhostUserSingleMemoryRegion, VhostUserVirtioFeatures, VhostUserVringAddrFlags,
|
VhostUserSingleMemoryRegion, VhostUserVirtioFeatures, VhostUserVringAddrFlags,
|
||||||
VhostUserVringState,
|
VhostUserVringState,
|
||||||
};
|
};
|
||||||
|
@ -343,26 +347,19 @@ impl<B: VhostUserBackend> VhostUserSlaveReqHandlerMut for DeviceRequestHandler<B
|
||||||
fn set_mem_table(
|
fn set_mem_table(
|
||||||
&mut self,
|
&mut self,
|
||||||
contexts: &[VhostUserMemoryRegion],
|
contexts: &[VhostUserMemoryRegion],
|
||||||
fds: &[RawFd],
|
files: Vec<File>,
|
||||||
) -> VhostResult<()> {
|
) -> VhostResult<()> {
|
||||||
if fds.len() != contexts.len() {
|
if files.len() != contexts.len() {
|
||||||
return Err(VhostError::InvalidParam);
|
return Err(VhostError::InvalidParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut regions = Vec::with_capacity(fds.len());
|
let mut regions = Vec::with_capacity(files.len());
|
||||||
for (region, &fd) in contexts.iter().zip(fds.iter()) {
|
for (region, file) in contexts.iter().zip(files.into_iter()) {
|
||||||
let rd = base::validate_raw_descriptor(fd).map_err(|e| {
|
|
||||||
error!("invalid fd is given: {}", e);
|
|
||||||
VhostError::InvalidParam
|
|
||||||
})?;
|
|
||||||
// Safe because we verified that we are the unique owner of `rd`.
|
|
||||||
let sd = unsafe { SafeDescriptor::from_raw_descriptor(rd) };
|
|
||||||
|
|
||||||
let region = MemoryRegion::new(
|
let region = MemoryRegion::new(
|
||||||
region.memory_size,
|
region.memory_size,
|
||||||
GuestAddress(region.guest_phys_addr),
|
GuestAddress(region.guest_phys_addr),
|
||||||
region.mmap_offset,
|
region.mmap_offset,
|
||||||
Arc::new(SharedMemory::from_safe_descriptor(sd).unwrap()),
|
Arc::new(SharedMemory::from_safe_descriptor(SafeDescriptor::from(file)).unwrap()),
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error!("failed to create a memory region: {}", e);
|
error!("failed to create a memory region: {}", e);
|
||||||
|
@ -457,7 +454,7 @@ impl<B: VhostUserBackend> VhostUserSlaveReqHandlerMut for DeviceRequestHandler<B
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_vring_kick(&mut self, index: u8, fd: Option<RawFd>) -> VhostResult<()> {
|
fn set_vring_kick(&mut self, index: u8, file: Option<File>) -> VhostResult<()> {
|
||||||
if index as usize >= self.vrings.len() {
|
if index as usize >= self.vrings.len() {
|
||||||
return Err(VhostError::InvalidParam);
|
return Err(VhostError::InvalidParam);
|
||||||
}
|
}
|
||||||
|
@ -468,24 +465,16 @@ impl<B: VhostUserBackend> VhostUserSlaveReqHandlerMut for DeviceRequestHandler<B
|
||||||
return Err(VhostError::InvalidOperation);
|
return Err(VhostError::InvalidOperation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(fd) = fd {
|
if let Some(file) = file {
|
||||||
// TODO(b/186625058): The current code returns an error when `FD_CLOEXEC` is already
|
|
||||||
// set, which is not harmful. Once we update the vhost crate's API to pass around `File`
|
|
||||||
// instead of `RawFd`, we won't need this validation.
|
|
||||||
let rd = base::validate_raw_descriptor(fd).map_err(|e| {
|
|
||||||
error!("invalid fd is given: {}", e);
|
|
||||||
VhostError::InvalidParam
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Remove O_NONBLOCK from kick_fd. Otherwise, uring_executor will fails when we read
|
// Remove O_NONBLOCK from kick_fd. Otherwise, uring_executor will fails when we read
|
||||||
// values via `next_val()` later.
|
// values via `next_val()` later.
|
||||||
if let Err(e) = clear_fd_flags(rd, libc::O_NONBLOCK) {
|
if let Err(e) = clear_fd_flags(file.as_raw_fd(), libc::O_NONBLOCK) {
|
||||||
error!("failed to remove O_NONBLOCK for kick fd: {}", e);
|
error!("failed to remove O_NONBLOCK for kick fd: {}", e);
|
||||||
return Err(VhostError::InvalidParam);
|
return Err(VhostError::InvalidParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safe because the FD is now owned.
|
// Safe because we own the file.
|
||||||
let kick_evt = unsafe { Event::from_raw_descriptor(rd) };
|
let kick_evt = unsafe { Event::from_raw_descriptor(file.into_raw_descriptor()) };
|
||||||
|
|
||||||
let vring = &mut self.vrings[index as usize];
|
let vring = &mut self.vrings[index as usize];
|
||||||
vring.queue.ready = true;
|
vring.queue.ready = true;
|
||||||
|
@ -515,18 +504,15 @@ impl<B: VhostUserBackend> VhostUserSlaveReqHandlerMut for DeviceRequestHandler<B
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_vring_call(&mut self, index: u8, fd: Option<RawFd>) -> VhostResult<()> {
|
fn set_vring_call(&mut self, index: u8, file: Option<File>) -> VhostResult<()> {
|
||||||
if index as usize >= self.vrings.len() {
|
if index as usize >= self.vrings.len() {
|
||||||
return Err(VhostError::InvalidParam);
|
return Err(VhostError::InvalidParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(fd) = fd {
|
if let Some(file) = file {
|
||||||
let rd = base::validate_raw_descriptor(fd).map_err(|e| {
|
// Safe because we own the file.
|
||||||
error!("invalid fd is given: {}", e);
|
let call_evt =
|
||||||
VhostError::InvalidParam
|
CallEvent(unsafe { Event::from_raw_descriptor(file.into_raw_descriptor()) });
|
||||||
})?;
|
|
||||||
// Safe because the FD is now owned.
|
|
||||||
let call_evt = CallEvent(unsafe { Event::from_raw_descriptor(rd) });
|
|
||||||
match &self.vrings[index as usize].call_evt {
|
match &self.vrings[index as usize].call_evt {
|
||||||
None => {
|
None => {
|
||||||
self.vrings[index as usize].call_evt = Some(Arc::new(Mutex::new(call_evt)));
|
self.vrings[index as usize].call_evt = Some(Arc::new(Mutex::new(call_evt)));
|
||||||
|
@ -541,7 +527,7 @@ impl<B: VhostUserBackend> VhostUserSlaveReqHandlerMut for DeviceRequestHandler<B
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_vring_err(&mut self, _index: u8, _fd: Option<RawFd>) -> VhostResult<()> {
|
fn set_vring_err(&mut self, _index: u8, _fd: Option<File>) -> VhostResult<()> {
|
||||||
// TODO
|
// TODO
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -595,6 +581,17 @@ impl<B: VhostUserBackend> VhostUserSlaveReqHandlerMut for DeviceRequestHandler<B
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_inflight_fd(
|
||||||
|
&mut self,
|
||||||
|
_inflight: &VhostUserInflight,
|
||||||
|
) -> VhostResult<(VhostUserInflight, File)> {
|
||||||
|
unimplemented!("get_inflight_fd");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_inflight_fd(&mut self, _inflight: &VhostUserInflight, _file: File) -> VhostResult<()> {
|
||||||
|
unimplemented!("set_inflight_fd");
|
||||||
|
}
|
||||||
|
|
||||||
fn get_max_mem_slots(&mut self) -> VhostResult<u64> {
|
fn get_max_mem_slots(&mut self) -> VhostResult<u64> {
|
||||||
//TODO
|
//TODO
|
||||||
Ok(0)
|
Ok(0)
|
||||||
|
@ -603,7 +600,7 @@ impl<B: VhostUserBackend> VhostUserSlaveReqHandlerMut for DeviceRequestHandler<B
|
||||||
fn add_mem_region(
|
fn add_mem_region(
|
||||||
&mut self,
|
&mut self,
|
||||||
_region: &VhostUserSingleMemoryRegion,
|
_region: &VhostUserSingleMemoryRegion,
|
||||||
_fd: RawFd,
|
_fd: File,
|
||||||
) -> VhostResult<()> {
|
) -> VhostResult<()> {
|
||||||
//TODO
|
//TODO
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in a new issue