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,45 +164,44 @@ impl VfioUserPciDevice {
prot |= libc::PROT_WRITE; prot |= libc::PROT_WRITE;
} }
let host_addr = unsafe { let mmaps = if sparse_areas.is_empty() {
libc::mmap( vec![vfio_region_sparse_mmap_area {
null_mut(), offset: 0,
mmio_region.length as usize, size: mmio_region.length,
prot, }]
libc::MAP_SHARED, } else {
file_offset.as_ref().unwrap().file().as_raw_fd(), sparse_areas
file_offset.as_ref().unwrap().start() as libc::off_t,
)
}; };
if host_addr == libc::MAP_FAILED {
error!(
"Could not mmap regions, error:{}",
std::io::Error::last_os_error()
);
continue;
}
let mut user_memory_regions = Vec::new(); let mut user_memory_regions = Vec::new();
if sparse_areas.is_empty() { for s in mmaps.iter() {
user_memory_regions.push(UserMemoryRegion { let host_addr = unsafe {
slot: mem_slot(), libc::mmap(
start: mmio_region.start.0, null_mut(),
size: mmio_region.length as u64, s.size as usize,
host_addr: host_addr as u64, prot,
}) libc::MAP_SHARED,
} else { file_offset.as_ref().unwrap().file().as_raw_fd(),
for s in sparse_areas.iter() { file_offset.as_ref().unwrap().start() as libc::off_t
user_memory_regions.push(UserMemoryRegion { + s.offset as libc::off_t,
slot: mem_slot(), )
start: mmio_region.start.0 + s.offset, };
size: s.size,
host_addr: host_addr as u64 + s.offset, if host_addr == libc::MAP_FAILED {
}); error!(
} "Could not mmap regions, error:{}",
}; std::io::Error::last_os_error()
);
continue;
}
let user_memory_region = UserMemoryRegion {
slot: mem_slot(),
start: mmio_region.start.0 + s.offset,
size: s.size,
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:{}",