vm-virtio: Implement userspace_mappings() for virtio-pmem

When hot-unplugging the virtio-pmem from the VM, we don't remove the
associated userspace mapping. This patch will let us fix this in a
following patch. For now, it simply adapts the code so that the Pmem
device knows about the mapping associated with it. By knowing about it,
it can expose it to the caller through the new userspace_mappings()
function.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2020-04-20 16:30:36 +02:00 committed by Rob Bradford
parent b0353992d6
commit fbcf3a7a7a
2 changed files with 22 additions and 6 deletions

View File

@ -8,8 +8,8 @@
use super::Error as DeviceError;
use super::{
ActivateError, ActivateResult, DescriptorChain, DeviceEventT, Queue, VirtioDevice,
VirtioDeviceType, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_VERSION_1,
ActivateError, ActivateResult, DescriptorChain, DeviceEventT, Queue, UserspaceMapping,
VirtioDevice, VirtioDeviceType, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_VERSION_1,
};
use crate::{VirtioInterrupt, VirtioInterruptType};
use epoll;
@ -322,6 +322,7 @@ pub struct Pmem {
interrupt_cb: Option<Arc<dyn VirtioInterrupt>>,
epoll_threads: Option<Vec<thread::JoinHandle<result::Result<(), DeviceError>>>>,
paused: Arc<AtomicBool>,
mapping: UserspaceMapping,
// Hold ownership of the memory that is allocated for the device
// which will be automatically dropped when the device is dropped
@ -332,6 +333,7 @@ impl Pmem {
pub fn new(
disk: File,
addr: GuestAddress,
mapping: UserspaceMapping,
_region: MmapRegion,
iommu: bool,
) -> io::Result<Pmem> {
@ -357,6 +359,7 @@ impl Pmem {
interrupt_cb: None,
epoll_threads: None,
paused: Arc::new(AtomicBool::new(false)),
mapping,
_region,
})
}
@ -513,6 +516,10 @@ impl VirtioDevice for Pmem {
self.queue_evts.take().unwrap(),
))
}
fn userspace_mappings(&self) -> Vec<UserspaceMapping> {
vec![self.mapping.clone()]
}
}
virtio_pausable!(Pmem);

View File

@ -1569,22 +1569,31 @@ impl DeviceManager {
},
)
.map_err(DeviceManagerError::NewMmapRegion)?;
let addr: u64 = mmap_region.as_ptr() as u64;
let host_addr: u64 = mmap_region.as_ptr() as u64;
self.memory_manager
let mem_slot = self
.memory_manager
.lock()
.unwrap()
.create_userspace_mapping(
pmem_guest_addr.raw_value(),
size,
addr,
host_addr,
pmem_cfg.mergeable,
pmem_cfg.discard_writes,
)
.map_err(DeviceManagerError::MemoryManager)?;
let mapping = vm_virtio::UserspaceMapping {
host_addr,
mem_slot,
addr: pmem_guest_addr,
len: size,
mergeable: pmem_cfg.mergeable,
};
let virtio_pmem_device = Arc::new(Mutex::new(
vm_virtio::Pmem::new(file, pmem_guest_addr, mmap_region, pmem_cfg.iommu)
vm_virtio::Pmem::new(file, pmem_guest_addr, mapping, mmap_region, pmem_cfg.iommu)
.map_err(DeviceManagerError::CreateVirtioPmem)?,
));