Skip to content

Commit 028caca

Browse files
committed
refactor(x86): iterate over regions to populate memory map
The way we populate the PVH and E820 memmap is by redoing all the math about the regions. Replace that duplicated logic with an iteration over the guest memory, filtering by Dram type (as we don't want to expose other regions we will add in the future). Furthermore, clamp the first 1MB as it's reserved for the system. Signed-off-by: Riccardo Mancini <[email protected]>
1 parent 5221b1f commit 028caca

File tree

1 file changed

+21
-57
lines changed

1 file changed

+21
-57
lines changed

src/vmm/src/arch/x86_64/mod.rs

Lines changed: 21 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ pub mod xstate;
3131
#[allow(missing_docs)]
3232
pub mod generated;
3333

34+
use std::cmp::max;
3435
use std::fs::File;
3536

3637
use kvm::Kvm;
3738
use layout::{
38-
CMDLINE_START, FIRST_ADDR_PAST_32BITS, FIRST_ADDR_PAST_64BITS_MMIO, MMIO32_MEM_SIZE,
39-
MMIO32_MEM_START, MMIO64_MEM_SIZE, MMIO64_MEM_START, PCI_MMCONFIG_SIZE, PCI_MMCONFIG_START,
39+
CMDLINE_START, MMIO32_MEM_SIZE, MMIO32_MEM_START, MMIO64_MEM_SIZE, MMIO64_MEM_START,
40+
PCI_MMCONFIG_SIZE, PCI_MMCONFIG_START,
4041
};
4142
use linux_loader::configurator::linux::LinuxBootConfigurator;
4243
use linux_loader::configurator::pvh::PvhBootConfigurator;
@@ -59,7 +60,7 @@ use crate::initrd::InitrdConfig;
5960
use crate::utils::{align_down, u64_to_usize, usize_to_u64};
6061
use crate::vmm_config::machine_config::MachineConfig;
6162
use crate::vstate::memory::{
62-
Address, GuestAddress, GuestMemory, GuestMemoryMmap, GuestMemoryRegion,
63+
Address, GuestAddress, GuestMemory, GuestMemoryMmap, GuestMemoryRegion, GuestRegionType,
6364
};
6465
use crate::vstate::vcpu::KvmVcpuConfigureError;
6566
use crate::{Vcpu, VcpuConfig, Vm, logger};
@@ -253,10 +254,6 @@ fn configure_pvh(
253254
initrd: &Option<InitrdConfig>,
254255
) -> Result<(), ConfigurationError> {
255256
const XEN_HVM_START_MAGIC_VALUE: u32 = 0x336e_c578;
256-
let first_addr_past_32bits = GuestAddress(FIRST_ADDR_PAST_32BITS);
257-
let end_32bit_gap_start = GuestAddress(MMIO32_MEM_START);
258-
let first_addr_past_64bits = GuestAddress(FIRST_ADDR_PAST_64BITS_MMIO);
259-
let end_64bit_gap_start = GuestAddress(MMIO64_MEM_START);
260257
let himem_start = GuestAddress(layout::HIMEM_START);
261258

262259
// Vector to hold modules (currently either empty or holding initrd).
@@ -294,36 +291,21 @@ fn configure_pvh(
294291
type_: E820_RESERVED,
295292
..Default::default()
296293
});
297-
let last_addr = guest_mem.last_addr();
298294

299-
if last_addr > first_addr_past_64bits {
300-
memmap.push(hvm_memmap_table_entry {
301-
addr: first_addr_past_64bits.raw_value(),
302-
size: last_addr.unchecked_offset_from(first_addr_past_64bits) + 1,
303-
type_: MEMMAP_TYPE_RAM,
304-
..Default::default()
305-
});
306-
}
307-
308-
if last_addr > first_addr_past_32bits {
295+
for region in guest_mem
296+
.iter()
297+
.filter(|region| region.region_type == GuestRegionType::Dram)
298+
{
299+
// the first 1MB is reserved for the kernel
300+
let addr = max(himem_start, region.start_addr());
309301
memmap.push(hvm_memmap_table_entry {
310-
addr: first_addr_past_32bits.raw_value(),
311-
size: (end_64bit_gap_start.unchecked_offset_from(first_addr_past_32bits))
312-
.min(last_addr.unchecked_offset_from(first_addr_past_32bits) + 1),
302+
addr: addr.raw_value(),
303+
size: region.last_addr().unchecked_offset_from(addr) + 1,
313304
type_: MEMMAP_TYPE_RAM,
314305
..Default::default()
315306
});
316307
}
317308

318-
memmap.push(hvm_memmap_table_entry {
319-
addr: himem_start.raw_value(),
320-
size: end_32bit_gap_start
321-
.unchecked_offset_from(himem_start)
322-
.min(last_addr.unchecked_offset_from(himem_start) + 1),
323-
type_: MEMMAP_TYPE_RAM,
324-
..Default::default()
325-
});
326-
327309
// Construct the hvm_start_info structure and serialize it into
328310
// boot_params. This will be stored at PVH_INFO_START address, and %rbx
329311
// will be initialized to contain PVH_INFO_START prior to starting the
@@ -368,10 +350,6 @@ fn configure_64bit_boot(
368350
const KERNEL_HDR_MAGIC: u32 = 0x5372_6448;
369351
const KERNEL_LOADER_OTHER: u8 = 0xff;
370352
const KERNEL_MIN_ALIGNMENT_BYTES: u32 = 0x0100_0000; // Must be non-zero.
371-
let first_addr_past_32bits = GuestAddress(FIRST_ADDR_PAST_32BITS);
372-
let end_32bit_gap_start = GuestAddress(MMIO32_MEM_START);
373-
let first_addr_past_64bits = GuestAddress(FIRST_ADDR_PAST_64BITS_MMIO);
374-
let end_64bit_gap_start = GuestAddress(MMIO64_MEM_START);
375353

376354
let himem_start = GuestAddress(layout::HIMEM_START);
377355

@@ -409,35 +387,20 @@ fn configure_64bit_boot(
409387
E820_RESERVED,
410388
)?;
411389

412-
let last_addr = guest_mem.last_addr();
413-
414-
if last_addr > first_addr_past_64bits {
415-
add_e820_entry(
416-
&mut params,
417-
first_addr_past_64bits.raw_value(),
418-
last_addr.unchecked_offset_from(first_addr_past_64bits) + 1,
419-
E820_RAM,
420-
)?;
421-
}
422-
423-
if last_addr > first_addr_past_32bits {
390+
for region in guest_mem
391+
.iter()
392+
.filter(|region| region.region_type == GuestRegionType::Dram)
393+
{
394+
// the first 1MB is reserved for the kernel
395+
let addr = max(himem_start, region.start_addr());
424396
add_e820_entry(
425397
&mut params,
426-
first_addr_past_32bits.raw_value(),
427-
(end_64bit_gap_start.unchecked_offset_from(first_addr_past_32bits))
428-
.min(last_addr.unchecked_offset_from(first_addr_past_32bits) + 1),
398+
addr.raw_value(),
399+
region.last_addr().unchecked_offset_from(addr) + 1,
429400
E820_RAM,
430401
)?;
431402
}
432403

433-
add_e820_entry(
434-
&mut params,
435-
himem_start.raw_value(),
436-
(last_addr.unchecked_offset_from(himem_start) + 1)
437-
.min(end_32bit_gap_start.unchecked_offset_from(himem_start)),
438-
E820_RAM,
439-
)?;
440-
441404
LinuxBootConfigurator::write_bootparams(
442405
&BootParams::new(&params, GuestAddress(layout::ZERO_PAGE_START)),
443406
guest_mem,
@@ -573,6 +536,7 @@ mod tests {
573536
use linux_loader::loader::bootparam::boot_e820_entry;
574537

575538
use super::*;
539+
use crate::arch::x86_64::layout::FIRST_ADDR_PAST_32BITS;
576540
use crate::test_utils::{arch_mem, single_region_mem};
577541
use crate::utils::mib_to_bytes;
578542
use crate::vstate::resources::ResourceAllocator;

0 commit comments

Comments
 (0)