pci: vfio_user: Simplify 'unmap_mmio_regions()'

Instead of always creating a single large mmap for the MMIO region of a
BAR, we create multiple mmaps for the BARs that need multiple kvm user
memory regions. In this way, we can simplify 'unmap_mmio_regions()' (by
reusing information kept from 'MmioRegion::user_memory_region').

Signed-off-by: Bo Chen <chen.bo@intel.com>
This commit is contained in:
Bo Chen 2022-05-03 14:03:32 -07:00 committed by Sebastien Boeuf
parent c614dcb9f7
commit 5bd7a1f03c

View File

@ -164,14 +164,26 @@ impl VfioUserPciDevice {
prot |= libc::PROT_WRITE; prot |= libc::PROT_WRITE;
} }
let mmaps = if sparse_areas.is_empty() {
vec![vfio_region_sparse_mmap_area {
offset: 0,
size: mmio_region.length,
}]
} else {
sparse_areas
};
let mut user_memory_regions = Vec::new();
for s in mmaps.iter() {
let host_addr = unsafe { let host_addr = unsafe {
libc::mmap( libc::mmap(
null_mut(), null_mut(),
mmio_region.length as usize, s.size as usize,
prot, prot,
libc::MAP_SHARED, libc::MAP_SHARED,
file_offset.as_ref().unwrap().file().as_raw_fd(), file_offset.as_ref().unwrap().file().as_raw_fd(),
file_offset.as_ref().unwrap().start() as libc::off_t, file_offset.as_ref().unwrap().start() as libc::off_t
+ s.offset as libc::off_t,
) )
}; };
@ -183,26 +195,13 @@ impl VfioUserPciDevice {
continue; continue;
} }
let mut user_memory_regions = Vec::new(); let user_memory_region = UserMemoryRegion {
if sparse_areas.is_empty() {
user_memory_regions.push(UserMemoryRegion {
slot: mem_slot(),
start: mmio_region.start.0,
size: mmio_region.length as u64,
host_addr: host_addr as u64,
})
} else {
for s in sparse_areas.iter() {
user_memory_regions.push(UserMemoryRegion {
slot: mem_slot(), slot: mem_slot(),
start: mmio_region.start.0 + s.offset, start: mmio_region.start.0 + s.offset,
size: s.size, size: s.size,
host_addr: host_addr as u64 + s.offset, host_addr: host_addr as u64,
});
}
}; };
for user_memory_region in user_memory_regions.iter() {
let mem_region = vm.make_user_memory_region( let mem_region = vm.make_user_memory_region(
user_memory_region.slot, user_memory_region.slot,
user_memory_region.start, user_memory_region.start,
@ -214,10 +213,10 @@ impl VfioUserPciDevice {
vm.create_user_memory_region(mem_region) vm.create_user_memory_region(mem_region)
.map_err(VfioUserPciDeviceError::MapRegionGuest)?; .map_err(VfioUserPciDeviceError::MapRegionGuest)?;
user_memory_regions.push(user_memory_region);
} }
mmio_region.host_addr = Some(host_addr as u64);
mmio_region.mmap_size = Some(mmio_region.length as usize);
mmio_region.user_memory_regions = user_memory_regions; mmio_region.user_memory_regions = user_memory_regions;
} }
} }
@ -241,12 +240,14 @@ impl VfioUserPciDevice {
if let Err(e) = self.vm.remove_user_memory_region(r) { if let Err(e) = self.vm.remove_user_memory_region(r) {
error!("Could not remove the userspace memory region: {}", e); error!("Could not remove the userspace memory region: {}", e);
} }
}
if let (Some(host_addr), Some(mmap_size)) = // Remove mmaps
(mmio_region.host_addr, mmio_region.mmap_size) let ret = unsafe {
{ libc::munmap(
let ret = unsafe { libc::munmap(host_addr as *mut libc::c_void, mmap_size) }; user_memory_region.host_addr as *mut libc::c_void,
user_memory_region.size as usize,
)
};
if ret != 0 { if ret != 0 {
error!( error!(
"Could not unmap region {}, error:{}", "Could not unmap region {}, error:{}",