vmm: Obtain sequential KVM memory slot numbers from MemoryManager

This removes the need to handle a mutable integer and also centralises
the allocation of these slot numbers.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2019-12-20 15:17:49 +00:00
parent 260cebb8cf
commit 61cfe3e72d
3 changed files with 31 additions and 30 deletions

View File

@ -12,6 +12,7 @@
extern crate vm_device; extern crate vm_device;
use crate::config::{ConsoleOutputMode, VmConfig}; use crate::config::{ConsoleOutputMode, VmConfig};
use crate::memory_manager::MemoryManager;
use crate::vm::VmInfo; use crate::vm::VmInfo;
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]
use acpi_tables::{aml, aml::Aml}; use acpi_tables::{aml, aml::Aml};
@ -417,7 +418,7 @@ impl DeviceManager {
pub fn new( pub fn new(
vm_info: &VmInfo, vm_info: &VmInfo,
allocator: Arc<Mutex<SystemAllocator>>, allocator: Arc<Mutex<SystemAllocator>>,
mut mem_slots: u32, memory_manager: Arc<Mutex<MemoryManager>>,
_exit_evt: &EventFd, _exit_evt: &EventFd,
reset_evt: &EventFd, reset_evt: &EventFd,
) -> DeviceManagerResult<Self> { ) -> DeviceManagerResult<Self> {
@ -455,7 +456,7 @@ impl DeviceManager {
virtio_devices.append(&mut DeviceManager::make_virtio_devices( virtio_devices.append(&mut DeviceManager::make_virtio_devices(
vm_info, vm_info,
&address_manager, &address_manager,
&mut mem_slots, &memory_manager,
&mut mmap_regions, &mut mmap_regions,
&mut migratable_devices, &mut migratable_devices,
)?); )?);
@ -479,7 +480,7 @@ impl DeviceManager {
DeviceManager::add_pci_devices( DeviceManager::add_pci_devices(
vm_info, vm_info,
&address_manager, &address_manager,
mem_slots, &memory_manager,
&mut virt_iommu, &mut virt_iommu,
virtio_devices, virtio_devices,
&interrupt_info, &interrupt_info,
@ -520,7 +521,7 @@ impl DeviceManager {
fn add_pci_devices( fn add_pci_devices(
vm_info: &VmInfo, vm_info: &VmInfo,
address_manager: &Arc<AddressManager>, address_manager: &Arc<AddressManager>,
mem_slots: u32, memory_manager: &Arc<Mutex<MemoryManager>>,
virt_iommu: &mut Option<(u32, Vec<u32>)>, virt_iommu: &mut Option<(u32, Vec<u32>)>,
virtio_devices: Vec<(Arc<Mutex<dyn vm_virtio::VirtioDevice>>, bool)>, virtio_devices: Vec<(Arc<Mutex<dyn vm_virtio::VirtioDevice>>, bool)>,
interrupt_info: &InterruptInfo, interrupt_info: &InterruptInfo,
@ -570,7 +571,7 @@ impl DeviceManager {
vm_info, vm_info,
&address_manager, &address_manager,
&mut pci_bus, &mut pci_bus,
mem_slots, memory_manager,
&mut iommu_device, &mut iommu_device,
)?; )?;
@ -848,7 +849,7 @@ impl DeviceManager {
fn make_virtio_devices( fn make_virtio_devices(
vm_info: &VmInfo, vm_info: &VmInfo,
address_manager: &Arc<AddressManager>, address_manager: &Arc<AddressManager>,
mut mem_slots: &mut u32, memory_manager: &Arc<Mutex<MemoryManager>>,
mmap_regions: &mut Vec<(*mut libc::c_void, usize)>, mmap_regions: &mut Vec<(*mut libc::c_void, usize)>,
migratable_devices: &mut Vec<Arc<Mutex<dyn Migratable>>>, migratable_devices: &mut Vec<Arc<Mutex<dyn Migratable>>>,
) -> DeviceManagerResult<Vec<(VirtioDeviceArc, bool)>> { ) -> DeviceManagerResult<Vec<(VirtioDeviceArc, bool)>> {
@ -873,7 +874,7 @@ impl DeviceManager {
devices.append(&mut DeviceManager::make_virtio_fs_devices( devices.append(&mut DeviceManager::make_virtio_fs_devices(
vm_info, vm_info,
&mut allocator, &mut allocator,
&mut mem_slots, memory_manager,
mmap_regions, mmap_regions,
migratable_devices, migratable_devices,
)?); )?);
@ -882,7 +883,7 @@ impl DeviceManager {
devices.append(&mut DeviceManager::make_virtio_pmem_devices( devices.append(&mut DeviceManager::make_virtio_pmem_devices(
vm_info, vm_info,
&mut allocator, &mut allocator,
&mut mem_slots, memory_manager,
mmap_regions, mmap_regions,
migratable_devices, migratable_devices,
)?); )?);
@ -1036,7 +1037,7 @@ impl DeviceManager {
fn make_virtio_fs_devices( fn make_virtio_fs_devices(
vm_info: &VmInfo, vm_info: &VmInfo,
allocator: &mut SystemAllocator, allocator: &mut SystemAllocator,
mem_slots: &mut u32, memory_manager: &Arc<Mutex<MemoryManager>>,
mmap_regions: &mut Vec<(*mut libc::c_void, usize)>, mmap_regions: &mut Vec<(*mut libc::c_void, usize)>,
migratable_devices: &mut Vec<Arc<Mutex<dyn Migratable>>>, migratable_devices: &mut Vec<Arc<Mutex<dyn Migratable>>>,
) -> DeviceManagerResult<Vec<(VirtioDeviceArc, bool)>> { ) -> DeviceManagerResult<Vec<(VirtioDeviceArc, bool)>> {
@ -1074,7 +1075,7 @@ impl DeviceManager {
mmap_regions.push((addr, fs_cache as usize)); mmap_regions.push((addr, fs_cache as usize));
let mem_region = kvm_userspace_memory_region { let mem_region = kvm_userspace_memory_region {
slot: *mem_slots as u32, slot: memory_manager.lock().unwrap().allocate_kvm_memory_slot(),
guest_phys_addr: fs_guest_addr.raw_value(), guest_phys_addr: fs_guest_addr.raw_value(),
memory_size: fs_cache, memory_size: fs_cache,
userspace_addr: addr as u64, userspace_addr: addr as u64,
@ -1083,9 +1084,6 @@ impl DeviceManager {
// Safe because the guest regions are guaranteed not to overlap. // Safe because the guest regions are guaranteed not to overlap.
let _ = unsafe { vm_info.vm_fd.set_user_memory_region(mem_region) }; let _ = unsafe { vm_info.vm_fd.set_user_memory_region(mem_region) };
// Increment the KVM slot number
*mem_slots += 1;
let mut region_list = Vec::new(); let mut region_list = Vec::new();
region_list.push(VirtioSharedMemory { region_list.push(VirtioSharedMemory {
offset: 0, offset: 0,
@ -1132,7 +1130,7 @@ impl DeviceManager {
fn make_virtio_pmem_devices( fn make_virtio_pmem_devices(
vm_info: &VmInfo, vm_info: &VmInfo,
allocator: &mut SystemAllocator, allocator: &mut SystemAllocator,
mem_slots: &mut u32, memory_manager: &Arc<Mutex<MemoryManager>>,
mmap_regions: &mut Vec<(*mut libc::c_void, usize)>, mmap_regions: &mut Vec<(*mut libc::c_void, usize)>,
migratable_devices: &mut Vec<Arc<Mutex<dyn Migratable>>>, migratable_devices: &mut Vec<Arc<Mutex<dyn Migratable>>>,
) -> DeviceManagerResult<Vec<(VirtioDeviceArc, bool)>> { ) -> DeviceManagerResult<Vec<(VirtioDeviceArc, bool)>> {
@ -1180,7 +1178,7 @@ impl DeviceManager {
mmap_regions.push((addr, size as usize)); mmap_regions.push((addr, size as usize));
let mem_region = kvm_userspace_memory_region { let mem_region = kvm_userspace_memory_region {
slot: *mem_slots as u32, slot: memory_manager.lock().unwrap().allocate_kvm_memory_slot(),
guest_phys_addr: pmem_guest_addr.raw_value(), guest_phys_addr: pmem_guest_addr.raw_value(),
memory_size: size, memory_size: size,
userspace_addr: addr as u64, userspace_addr: addr as u64,
@ -1214,9 +1212,6 @@ impl DeviceManager {
} }
} }
// Increment the KVM slot number
*mem_slots += 1;
let virtio_pmem_device = Arc::new(Mutex::new( let virtio_pmem_device = Arc::new(Mutex::new(
vm_virtio::Pmem::new(file, pmem_guest_addr, size as GuestUsize, pmem_cfg.iommu) vm_virtio::Pmem::new(file, pmem_guest_addr, size as GuestUsize, pmem_cfg.iommu)
.map_err(DeviceManagerError::CreateVirtioPmem)?, .map_err(DeviceManagerError::CreateVirtioPmem)?,
@ -1347,10 +1342,10 @@ impl DeviceManager {
vm_info: &VmInfo, vm_info: &VmInfo,
address_manager: &Arc<AddressManager>, address_manager: &Arc<AddressManager>,
pci: &mut PciBus, pci: &mut PciBus,
mem_slots: u32, memory_manager: &Arc<Mutex<MemoryManager>>,
iommu_device: &mut Option<vm_virtio::Iommu>, iommu_device: &mut Option<vm_virtio::Iommu>,
) -> DeviceManagerResult<Vec<u32>> { ) -> DeviceManagerResult<Vec<u32>> {
let mut mem_slot = mem_slots; let mut mem_slot = memory_manager.lock().unwrap().allocate_kvm_memory_slot();
let mut iommu_attached_device_ids = Vec::new(); let mut iommu_attached_device_ids = Vec::new();
let mut allocator = address_manager.allocator.lock().unwrap(); let mut allocator = address_manager.allocator.lock().unwrap();

View File

@ -21,7 +21,7 @@ use kvm_ioctls::*;
pub struct MemoryManager { pub struct MemoryManager {
guest_memory: Arc<RwLock<GuestMemoryMmap>>, guest_memory: Arc<RwLock<GuestMemoryMmap>>,
ram_regions: u32, next_kvm_memory_slot: u32,
start_of_device_area: GuestAddress, start_of_device_area: GuestAddress,
end_of_device_area: GuestAddress, end_of_device_area: GuestAddress,
} }
@ -192,7 +192,7 @@ impl MemoryManager {
Ok(Arc::new(Mutex::new(MemoryManager { Ok(Arc::new(Mutex::new(MemoryManager {
guest_memory, guest_memory,
ram_regions: ram_regions.len() as u32, next_kvm_memory_slot: ram_regions.len() as u32,
start_of_device_area, start_of_device_area,
end_of_device_area, end_of_device_area,
}))) })))
@ -202,10 +202,6 @@ impl MemoryManager {
self.guest_memory.clone() self.guest_memory.clone()
} }
pub fn ram_regions(&self) -> u32 {
self.ram_regions
}
pub fn start_of_device_area(&self) -> GuestAddress { pub fn start_of_device_area(&self) -> GuestAddress {
self.start_of_device_area self.start_of_device_area
} }
@ -213,4 +209,10 @@ impl MemoryManager {
pub fn end_of_device_area(&self) -> GuestAddress { pub fn end_of_device_area(&self) -> GuestAddress {
self.end_of_device_area self.end_of_device_area
} }
pub fn allocate_kvm_memory_slot(&mut self) -> u32 {
let slot_id = self.next_kvm_memory_slot;
self.next_kvm_memory_slot += 1;
slot_id
}
} }

View File

@ -320,7 +320,6 @@ impl Vm {
let start_of_device_area = memory_manager.lock().unwrap().start_of_device_area(); let start_of_device_area = memory_manager.lock().unwrap().start_of_device_area();
let end_of_device_area = memory_manager.lock().unwrap().end_of_device_area(); let end_of_device_area = memory_manager.lock().unwrap().end_of_device_area();
let ram_regions = memory_manager.lock().unwrap().ram_regions();
let guest_memory = memory_manager.lock().unwrap().guest_memory(); let guest_memory = memory_manager.lock().unwrap().guest_memory();
let vm_info = VmInfo { let vm_info = VmInfo {
memory: &guest_memory, memory: &guest_memory,
@ -330,8 +329,13 @@ impl Vm {
end_of_device_area, end_of_device_area,
}; };
let device_manager = let device_manager = DeviceManager::new(
DeviceManager::new(&vm_info, allocator, ram_regions, &exit_evt, &reset_evt) &vm_info,
allocator,
memory_manager.clone(),
&exit_evt,
&reset_evt,
)
.map_err(Error::DeviceManager)?; .map_err(Error::DeviceManager)?;
let on_tty = unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0; let on_tty = unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0;