Skip to content

Commit 5221b1f

Browse files
committed
refactor(aarch64): do not use GuestMemory::last_addr()
As we will add other guest memory regions, last_addr() will not return what we actually want: the last addr of the DRAM region. Use the region type introduced in an earlier refactor to find the DRAM region and use that instead. Signed-off-by: Riccardo Mancini <[email protected]>
1 parent 2649896 commit 5221b1f

File tree

2 files changed

+36
-30
lines changed

2 files changed

+36
-30
lines changed

src/vmm/src/arch/aarch64/fdt.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::ffi::CString;
99
use std::fmt::Debug;
1010

1111
use vm_fdt::{Error as VmFdtError, FdtWriter, FdtWriterNode};
12-
use vm_memory::GuestMemoryError;
12+
use vm_memory::{GuestMemoryError, GuestMemoryRegion};
1313

1414
use super::cache_info::{CacheEntry, read_cache_config};
1515
use super::gic::GICDevice;
@@ -22,7 +22,7 @@ use crate::device_manager::mmio::MMIODeviceInfo;
2222
use crate::device_manager::pci_mngr::PciDevices;
2323
use crate::devices::acpi::vmgenid::{VMGENID_MEM_SIZE, VmGenId};
2424
use crate::initrd::InitrdConfig;
25-
use crate::vstate::memory::{Address, GuestMemory, GuestMemoryMmap};
25+
use crate::vstate::memory::{Address, GuestMemory, GuestMemoryMmap, GuestRegionType};
2626

2727
// This is a value for uniquely identifying the FDT node declaring the interrupt controller.
2828
const GIC_PHANDLE: u32 = 1;
@@ -227,14 +227,20 @@ fn create_memory_node(fdt: &mut FdtWriter, guest_mem: &GuestMemoryMmap) -> Resul
227227
// The reason we do this is that Linux does not allow remapping system memory. However, without
228228
// remap, kernel drivers cannot get virtual addresses to read data from device memory. Leaving
229229
// this memory region out allows Linux kernel modules to remap and thus read this region.
230-
let mem_size = guest_mem.last_addr().raw_value()
231-
- super::layout::DRAM_MEM_START
232-
- super::layout::SYSTEM_MEM_SIZE
233-
+ 1;
234-
let mem_reg_prop = &[
235-
super::layout::DRAM_MEM_START + super::layout::SYSTEM_MEM_SIZE,
236-
mem_size,
237-
];
230+
231+
// Pick the first (and only) memory region
232+
let dram_region = guest_mem
233+
.iter()
234+
.find(|region| region.region_type == GuestRegionType::Dram)
235+
.unwrap();
236+
// Find the start of memory after the system memory region
237+
let start_addr = dram_region
238+
.start_addr()
239+
.unchecked_add(super::layout::SYSTEM_MEM_SIZE);
240+
// Size of the memory is the region size minus the system memory size
241+
let mem_size = dram_region.len() - super::layout::SYSTEM_MEM_SIZE;
242+
243+
let mem_reg_prop = &[start_addr.raw_value(), mem_size];
238244
let mem = fdt.begin_node("memory@ram")?;
239245
fdt.property_string("device_type", "memory")?;
240246
fdt.property_array_u64("reg", mem_reg_prop)?;

src/vmm/src/arch/aarch64/mod.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,17 @@ use std::fs::File;
2222

2323
use linux_loader::loader::pe::PE as Loader;
2424
use linux_loader::loader::{Cmdline, KernelLoader};
25-
use vm_memory::GuestMemoryError;
25+
use vm_memory::{GuestMemoryError, GuestMemoryRegion};
2626

2727
use crate::arch::{BootProtocol, EntryPoint, arch_memory_regions_with_gap};
2828
use crate::cpu_config::aarch64::{CpuConfiguration, CpuConfigurationError};
2929
use crate::cpu_config::templates::CustomCpuTemplate;
3030
use crate::initrd::InitrdConfig;
3131
use crate::utils::{align_up, u64_to_usize, usize_to_u64};
3232
use crate::vmm_config::machine_config::MachineConfig;
33-
use crate::vstate::memory::{Address, Bytes, GuestAddress, GuestMemory, GuestMemoryMmap};
33+
use crate::vstate::memory::{
34+
Address, Bytes, GuestAddress, GuestMemory, GuestMemoryMmap, GuestRegionType,
35+
};
3436
use crate::vstate::vcpu::KvmVcpuError;
3537
use crate::{DeviceManager, Kvm, Vcpu, VcpuConfig, Vm, logger};
3638

@@ -151,31 +153,29 @@ pub fn initrd_load_addr(guest_mem: &GuestMemoryMmap, initrd_size: usize) -> Opti
151153
usize_to_u64(initrd_size),
152154
usize_to_u64(super::GUEST_PAGE_SIZE),
153155
);
154-
match GuestAddress(get_fdt_addr(guest_mem)).checked_sub(rounded_size) {
155-
Some(offset) => {
156-
if guest_mem.address_in_range(offset) {
157-
Some(offset.raw_value())
158-
} else {
159-
None
160-
}
161-
}
162-
None => None,
163-
}
156+
GuestAddress(get_fdt_addr(guest_mem))
157+
.checked_sub(rounded_size)
158+
.filter(|&addr| guest_mem.address_in_range(addr))
159+
.map(|addr| addr.raw_value())
164160
}
165161

166162
// Auxiliary function to get the address where the device tree blob is loaded.
167163
fn get_fdt_addr(mem: &GuestMemoryMmap) -> u64 {
164+
// Find the first (and only) DRAM region.
165+
let dram_region = mem
166+
.iter()
167+
.find(|region| region.region_type == GuestRegionType::Dram)
168+
.unwrap();
169+
168170
// If the memory allocated is smaller than the size allocated for the FDT,
169171
// we return the start of the DRAM so that
170172
// we allow the code to try and load the FDT.
171-
172-
if let Some(addr) = mem.last_addr().checked_sub(layout::FDT_MAX_SIZE as u64 - 1)
173-
&& mem.address_in_range(addr)
174-
{
175-
return addr.raw_value();
176-
}
177-
178-
layout::DRAM_MEM_START
173+
dram_region
174+
.last_addr()
175+
.checked_sub(layout::FDT_MAX_SIZE as u64 - 1)
176+
.filter(|&addr| mem.address_in_range(addr))
177+
.map(|addr| addr.raw_value())
178+
.unwrap_or(layout::DRAM_MEM_START)
179179
}
180180

181181
/// Load linux kernel into guest memory.

0 commit comments

Comments
 (0)