mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-22 11:22:26 +00:00
vm-virtio: Fix FS_IO callback for virtio-fs
FS_IO is part of the actions a vhost-user-fs daemon can ask the VMM to perform on its behalf. It is meant to read/write the content from a file descriptor directly into a guest memory region. This region can either be a RAM region or the dedicated cache region for virtio-fs. The way FS_IO was implemented, it was only expecting the guest physical address provided through the "cache_offset" field to refer to the cache region. Unfortunately, this was only implementing FS_IO partially. This patch extends the existing FS_IO implementation by checking the GPA against the cache region as a first step, but if it is not part of the cache region address range, then we fallback onto searching for a RAM region that could match. If there is a matching RAM region, we retrieve the corresponding host address to let the VMM read/write from/to it. Fixes: #1054 Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com> Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
This commit is contained in:
parent
df14a68e87
commit
3eaeba4b55
@ -27,8 +27,8 @@ use vhost_rs::vhost_user::{
|
|||||||
};
|
};
|
||||||
use vhost_rs::VhostBackend;
|
use vhost_rs::VhostBackend;
|
||||||
use vm_memory::{
|
use vm_memory::{
|
||||||
Address, ByteValued, GuestAddress, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap,
|
Address, ByteValued, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic,
|
||||||
MmapRegion,
|
GuestMemoryMmap, MmapRegion,
|
||||||
};
|
};
|
||||||
use vm_migration::{Migratable, MigratableError, Pausable, Snapshottable, Transportable};
|
use vm_migration::{Migratable, MigratableError, Pausable, Snapshottable, Transportable};
|
||||||
use vmm_sys_util::eventfd::EventFd;
|
use vmm_sys_util::eventfd::EventFd;
|
||||||
@ -39,6 +39,7 @@ struct SlaveReqHandler {
|
|||||||
cache_offset: GuestAddress,
|
cache_offset: GuestAddress,
|
||||||
cache_size: u64,
|
cache_size: u64,
|
||||||
mmap_cache_addr: u64,
|
mmap_cache_addr: u64,
|
||||||
|
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SlaveReqHandler {
|
impl SlaveReqHandler {
|
||||||
@ -183,18 +184,32 @@ impl VhostUserMasterReqHandler for SlaveReqHandler {
|
|||||||
let cache_end = self.cache_offset.raw_value() + self.cache_size;
|
let cache_end = self.cache_offset.raw_value() + self.cache_size;
|
||||||
let efault = libc::EFAULT;
|
let efault = libc::EFAULT;
|
||||||
|
|
||||||
let offset = gpa
|
let mut ptr = if gpa >= self.cache_offset.raw_value() && gpa < cache_end {
|
||||||
.checked_sub(self.cache_offset.raw_value())
|
let offset = gpa
|
||||||
.ok_or_else(|| io::Error::from_raw_os_error(efault))?;
|
.checked_sub(self.cache_offset.raw_value())
|
||||||
let end = gpa
|
.ok_or_else(|| io::Error::from_raw_os_error(efault))?;
|
||||||
.checked_add(fs.len[i])
|
let end = gpa
|
||||||
.ok_or_else(|| io::Error::from_raw_os_error(efault))?;
|
.checked_add(fs.len[i])
|
||||||
|
.ok_or_else(|| io::Error::from_raw_os_error(efault))?;
|
||||||
|
|
||||||
if gpa < self.cache_offset.raw_value() || gpa >= cache_end || end >= cache_end {
|
if end >= cache_end {
|
||||||
return Err(io::Error::from_raw_os_error(efault));
|
return Err(io::Error::from_raw_os_error(efault));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.mmap_cache_addr + offset
|
||||||
|
} else {
|
||||||
|
self.mem
|
||||||
|
.memory()
|
||||||
|
.get_host_address(GuestAddress(gpa))
|
||||||
|
.map_err(|e| {
|
||||||
|
error!(
|
||||||
|
"Failed to find RAM region associated with guest physical address 0x{:x}: {:?}",
|
||||||
|
gpa, e
|
||||||
|
);
|
||||||
|
io::Error::from_raw_os_error(efault)
|
||||||
|
})? as u64
|
||||||
|
};
|
||||||
|
|
||||||
let mut ptr = self.mmap_cache_addr + offset;
|
|
||||||
while len > 0 {
|
while len > 0 {
|
||||||
let ret = if (fs.flags[i] & VhostUserFSSlaveMsgFlags::MAP_W)
|
let ret = if (fs.flags[i] & VhostUserFSSlaveMsgFlags::MAP_W)
|
||||||
== VhostUserFSSlaveMsgFlags::MAP_W
|
== VhostUserFSSlaveMsgFlags::MAP_W
|
||||||
@ -479,6 +494,7 @@ impl VirtioDevice for Fs {
|
|||||||
cache_offset: cache.0.addr,
|
cache_offset: cache.0.addr,
|
||||||
cache_size: cache.0.len,
|
cache_size: cache.0.len,
|
||||||
mmap_cache_addr: cache.0.host_addr,
|
mmap_cache_addr: cache.0.host_addr,
|
||||||
|
mem,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let req_handler = MasterReqHandler::new(vu_master_req_handler).map_err(|e| {
|
let req_handler = MasterReqHandler::new(vu_master_req_handler).map_err(|e| {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user