mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-09 14:25:21 +00:00
vmm: memory_manager: Rely on physical bits for address space size
If the user provided a maximum physical bits value for the vCPUs, the memory manager will adapt the guest physical address space accordingly so that devices are not placed further than the specified value. It's important to note that if the number exceed what is available on the host, the smaller number will be picked. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
52ad78886c
commit
aec88e20d7
@ -12,7 +12,7 @@ use acpi_tables::{aml, aml::Aml};
|
|||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use arch::x86_64::{SgxEpcRegion, SgxEpcSection};
|
use arch::x86_64::{SgxEpcRegion, SgxEpcSection};
|
||||||
use arch::{get_host_cpu_phys_bits, layout, RegionType};
|
use arch::{layout, RegionType};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use devices::ioapic;
|
use devices::ioapic;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -256,8 +256,8 @@ const SELECTION_OFFSET: u64 = 0;
|
|||||||
// The MMIO address space size is subtracted with the size of a 4k page. This
|
// The MMIO address space size is subtracted with the size of a 4k page. This
|
||||||
// is done on purpose to workaround a Linux bug when the VMM allocates devices
|
// is done on purpose to workaround a Linux bug when the VMM allocates devices
|
||||||
// at the end of the addressable space.
|
// at the end of the addressable space.
|
||||||
fn mmio_address_space_size() -> u64 {
|
fn mmio_address_space_size(phys_bits: u8) -> u64 {
|
||||||
(1 << get_host_cpu_phys_bits()) - 0x1000
|
(1 << phys_bits) - 0x1000
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BusDevice for MemoryManager {
|
impl BusDevice for MemoryManager {
|
||||||
@ -448,6 +448,7 @@ impl MemoryManager {
|
|||||||
config: &MemoryConfig,
|
config: &MemoryConfig,
|
||||||
ext_regions: Option<Vec<MemoryRegion>>,
|
ext_regions: Option<Vec<MemoryRegion>>,
|
||||||
prefault: bool,
|
prefault: bool,
|
||||||
|
phys_bits: u8,
|
||||||
) -> Result<Arc<Mutex<MemoryManager>>, Error> {
|
) -> Result<Arc<Mutex<MemoryManager>>, Error> {
|
||||||
let user_provided_zones = config.size == 0;
|
let user_provided_zones = config.size == 0;
|
||||||
let mut allow_mem_hotplug: bool = false;
|
let mut allow_mem_hotplug: bool = false;
|
||||||
@ -585,7 +586,8 @@ impl MemoryManager {
|
|||||||
|
|
||||||
let boot_guest_memory = guest_memory.clone();
|
let boot_guest_memory = guest_memory.clone();
|
||||||
|
|
||||||
let end_of_device_area = GuestAddress(mmio_address_space_size() - 1);
|
let mmio_address_space_size = mmio_address_space_size(phys_bits);
|
||||||
|
let end_of_device_area = GuestAddress(mmio_address_space_size - 1);
|
||||||
|
|
||||||
let mut start_of_device_area =
|
let mut start_of_device_area =
|
||||||
MemoryManager::start_addr(guest_memory.last_addr(), allow_mem_hotplug)?;
|
MemoryManager::start_addr(guest_memory.last_addr(), allow_mem_hotplug)?;
|
||||||
@ -656,7 +658,7 @@ impl MemoryManager {
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
(1 << 16 as GuestUsize),
|
(1 << 16 as GuestUsize),
|
||||||
GuestAddress(0),
|
GuestAddress(0),
|
||||||
mmio_address_space_size(),
|
mmio_address_space_size,
|
||||||
layout::MEM_32BIT_DEVICES_START,
|
layout::MEM_32BIT_DEVICES_START,
|
||||||
layout::MEM_32BIT_DEVICES_SIZE,
|
layout::MEM_32BIT_DEVICES_SIZE,
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -740,6 +742,7 @@ impl MemoryManager {
|
|||||||
config: &MemoryConfig,
|
config: &MemoryConfig,
|
||||||
source_url: &str,
|
source_url: &str,
|
||||||
prefault: bool,
|
prefault: bool,
|
||||||
|
phys_bits: u8,
|
||||||
) -> Result<Arc<Mutex<MemoryManager>>, Error> {
|
) -> Result<Arc<Mutex<MemoryManager>>, Error> {
|
||||||
let url = Url::parse(source_url).unwrap();
|
let url = Url::parse(source_url).unwrap();
|
||||||
/* url must be valid dir which is verified in recv_vm_snapshot() */
|
/* url must be valid dir which is verified in recv_vm_snapshot() */
|
||||||
@ -777,7 +780,7 @@ impl MemoryManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryManager::new(vm, config, Some(ext_regions), prefault)
|
MemoryManager::new(vm, config, Some(ext_regions), prefault, phys_bits)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Restore(MigratableError::Restore(anyhow!(
|
Err(Error::Restore(MigratableError::Restore(anyhow!(
|
||||||
"Could not find {}-section from snapshot",
|
"Could not find {}-section from snapshot",
|
||||||
|
@ -38,6 +38,7 @@ use crate::{
|
|||||||
PciDeviceInfo, CPU_MANAGER_SNAPSHOT_ID, DEVICE_MANAGER_SNAPSHOT_ID, MEMORY_MANAGER_SNAPSHOT_ID,
|
PciDeviceInfo, CPU_MANAGER_SNAPSHOT_ID, DEVICE_MANAGER_SNAPSHOT_ID, MEMORY_MANAGER_SNAPSHOT_ID,
|
||||||
};
|
};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
use arch::get_host_cpu_phys_bits;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use arch::BootProtocol;
|
use arch::BootProtocol;
|
||||||
use arch::EntryPoint;
|
use arch::EntryPoint;
|
||||||
@ -51,6 +52,7 @@ use linux_loader::loader::elf::PvhBootCapability::PvhEntryPresent;
|
|||||||
use linux_loader::loader::KernelLoader;
|
use linux_loader::loader::KernelLoader;
|
||||||
use seccomp::{SeccompAction, SeccompFilter};
|
use seccomp::{SeccompAction, SeccompFilter};
|
||||||
use signal_hook::{iterator::Signals, SIGINT, SIGTERM, SIGWINCH};
|
use signal_hook::{iterator::Signals, SIGINT, SIGTERM, SIGWINCH};
|
||||||
|
use std::cmp;
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
@ -431,6 +433,11 @@ impl VmmOps for VmOps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn physical_bits(max_phys_bits: Option<u8>) -> u8 {
|
||||||
|
let host_phys_bits = get_host_cpu_phys_bits();
|
||||||
|
cmp::min(host_phys_bits, max_phys_bits.unwrap_or(host_phys_bits))
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Vm {
|
pub struct Vm {
|
||||||
kernel: File,
|
kernel: File,
|
||||||
initramfs: Option<File>,
|
initramfs: Option<File>,
|
||||||
@ -629,11 +636,13 @@ impl Vm {
|
|||||||
let vm = hypervisor.create_vm().unwrap();
|
let vm = hypervisor.create_vm().unwrap();
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
vm.enable_split_irq().unwrap();
|
vm.enable_split_irq().unwrap();
|
||||||
|
let phys_bits = physical_bits(config.lock().unwrap().cpus.max_phys_bits);
|
||||||
let memory_manager = MemoryManager::new(
|
let memory_manager = MemoryManager::new(
|
||||||
vm.clone(),
|
vm.clone(),
|
||||||
&config.lock().unwrap().memory.clone(),
|
&config.lock().unwrap().memory.clone(),
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
phys_bits,
|
||||||
)
|
)
|
||||||
.map_err(Error::MemoryManager)?;
|
.map_err(Error::MemoryManager)?;
|
||||||
|
|
||||||
@ -697,12 +706,14 @@ impl Vm {
|
|||||||
let memory_manager = if let Some(memory_manager_snapshot) =
|
let memory_manager = if let Some(memory_manager_snapshot) =
|
||||||
snapshot.snapshots.get(MEMORY_MANAGER_SNAPSHOT_ID)
|
snapshot.snapshots.get(MEMORY_MANAGER_SNAPSHOT_ID)
|
||||||
{
|
{
|
||||||
|
let phys_bits = physical_bits(config.lock().unwrap().cpus.max_phys_bits);
|
||||||
MemoryManager::new_from_snapshot(
|
MemoryManager::new_from_snapshot(
|
||||||
memory_manager_snapshot,
|
memory_manager_snapshot,
|
||||||
vm.clone(),
|
vm.clone(),
|
||||||
&config.lock().unwrap().memory.clone(),
|
&config.lock().unwrap().memory.clone(),
|
||||||
source_url,
|
source_url,
|
||||||
prefault,
|
prefault,
|
||||||
|
phys_bits,
|
||||||
)
|
)
|
||||||
.map_err(Error::MemoryManager)?
|
.map_err(Error::MemoryManager)?
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user