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 vm_memory::{
|
||||
Address, ByteValued, GuestAddress, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap,
|
||||
MmapRegion,
|
||||
Address, ByteValued, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic,
|
||||
GuestMemoryMmap, MmapRegion,
|
||||
};
|
||||
use vm_migration::{Migratable, MigratableError, Pausable, Snapshottable, Transportable};
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
@ -39,6 +39,7 @@ struct SlaveReqHandler {
|
||||
cache_offset: GuestAddress,
|
||||
cache_size: u64,
|
||||
mmap_cache_addr: u64,
|
||||
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
}
|
||||
|
||||
impl SlaveReqHandler {
|
||||
@ -183,6 +184,7 @@ impl VhostUserMasterReqHandler for SlaveReqHandler {
|
||||
let cache_end = self.cache_offset.raw_value() + self.cache_size;
|
||||
let efault = libc::EFAULT;
|
||||
|
||||
let mut ptr = if gpa >= self.cache_offset.raw_value() && gpa < cache_end {
|
||||
let offset = gpa
|
||||
.checked_sub(self.cache_offset.raw_value())
|
||||
.ok_or_else(|| io::Error::from_raw_os_error(efault))?;
|
||||
@ -190,11 +192,24 @@ impl VhostUserMasterReqHandler for SlaveReqHandler {
|
||||
.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));
|
||||
}
|
||||
|
||||
let mut ptr = self.mmap_cache_addr + offset;
|
||||
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
|
||||
};
|
||||
|
||||
while len > 0 {
|
||||
let ret = if (fs.flags[i] & VhostUserFSSlaveMsgFlags::MAP_W)
|
||||
== VhostUserFSSlaveMsgFlags::MAP_W
|
||||
@ -479,6 +494,7 @@ impl VirtioDevice for Fs {
|
||||
cache_offset: cache.0.addr,
|
||||
cache_size: cache.0.len,
|
||||
mmap_cache_addr: cache.0.host_addr,
|
||||
mem,
|
||||
}));
|
||||
|
||||
let req_handler = MasterReqHandler::new(vu_master_req_handler).map_err(|e| {
|
||||
|
Loading…
x
Reference in New Issue
Block a user