mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
devices: Add e820/memory_map to fw_cfg device
We build the memory map in the fw_cfg device based on the memory size. Signed-off-by: Alex Orozco <alexorozco@google.com>
This commit is contained in:
@@ -19,15 +19,35 @@ use std::{
|
||||
sync::{Arc, Barrier},
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use arch::aarch64::layout::{
|
||||
MEM_32BIT_DEVICES_START, MEM_32BIT_RESERVED_START, RAM_64BIT_START, RAM_START as HIGH_RAM_START,
|
||||
};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use arch::layout::{
|
||||
EBDA_START, HIGH_RAM_START, MEM_32BIT_DEVICES_SIZE, MEM_32BIT_DEVICES_START,
|
||||
MEM_32BIT_RESERVED_START, PCI_MMCONFIG_SIZE, PCI_MMCONFIG_START, RAM_64BIT_START,
|
||||
};
|
||||
use arch::RegionType;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use linux_loader::bootparam::boot_params;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use linux_loader::loader::pe::arm64_image_header as boot_params;
|
||||
use vm_device::BusDevice;
|
||||
use vm_memory::ByteValued;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use vm_memory::GuestAddress;
|
||||
use vmm_sys_util::sock_ctrl_msg::IntoIovec;
|
||||
use zerocopy::{FromBytes, IntoBytes};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
// https://github.com/project-oak/oak/tree/main/stage0_bin#memory-layout
|
||||
const STAGE0_START_ADDRESS: GuestAddress = GuestAddress(0xfffe_0000);
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
const STAGE0_SIZE: usize = 0x2_0000;
|
||||
const E820_RAM: u32 = 1;
|
||||
const E820_RESERVED: u32 = 2;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
const PORT_FW_CFG_SELECTOR: u64 = 0x510;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
@@ -165,6 +185,63 @@ impl FwCfg {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_e820(&mut self, mem_size: usize) -> Result<()> {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
let mut mem_regions = vec![
|
||||
(GuestAddress(0), EBDA_START.0 as usize, RegionType::Ram),
|
||||
(
|
||||
MEM_32BIT_DEVICES_START,
|
||||
MEM_32BIT_DEVICES_SIZE as usize,
|
||||
RegionType::Reserved,
|
||||
),
|
||||
(
|
||||
PCI_MMCONFIG_START,
|
||||
PCI_MMCONFIG_SIZE as usize,
|
||||
RegionType::Reserved,
|
||||
),
|
||||
(STAGE0_START_ADDRESS, STAGE0_SIZE, RegionType::Reserved),
|
||||
];
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
let mut mem_regions = arch::aarch64::arch_memory_regions();
|
||||
if mem_size < MEM_32BIT_DEVICES_START.0 as usize {
|
||||
mem_regions.push((
|
||||
HIGH_RAM_START,
|
||||
mem_size - HIGH_RAM_START.0 as usize,
|
||||
RegionType::Ram,
|
||||
));
|
||||
} else {
|
||||
mem_regions.push((
|
||||
HIGH_RAM_START,
|
||||
MEM_32BIT_RESERVED_START.0 as usize - HIGH_RAM_START.0 as usize,
|
||||
RegionType::Ram,
|
||||
));
|
||||
mem_regions.push((
|
||||
RAM_64BIT_START,
|
||||
mem_size - (MEM_32BIT_DEVICES_START.0 as usize),
|
||||
RegionType::Ram,
|
||||
));
|
||||
}
|
||||
let mut bytes = vec![];
|
||||
for (addr, size, region) in mem_regions.iter() {
|
||||
let type_ = match region {
|
||||
RegionType::Ram => E820_RAM,
|
||||
RegionType::Reserved => E820_RESERVED,
|
||||
RegionType::SubRegion => continue,
|
||||
};
|
||||
let mut entry = BootE820Entry {
|
||||
addr: addr.0,
|
||||
size: *size as u64,
|
||||
type_,
|
||||
};
|
||||
bytes.extend_from_slice(entry.as_mut_bytes());
|
||||
}
|
||||
let item = FwCfgItem {
|
||||
name: "etc/e820".to_owned(),
|
||||
content: FwCfgContent::Bytes(bytes),
|
||||
};
|
||||
self.add_item(item)
|
||||
}
|
||||
|
||||
fn file_dir_mut(&mut self) -> &mut Vec<u8> {
|
||||
let FwCfgContent::Bytes(file_buf) = &mut self.known_items[FW_CFG_FILE_DIR as usize] else {
|
||||
unreachable!("fw_cfg: selector {FW_CFG_FILE_DIR:#x} should be FwCfgContent::Byte!")
|
||||
|
||||
@@ -351,6 +351,10 @@ pub enum Error {
|
||||
#[cfg(feature = "fw_cfg")]
|
||||
#[error("Fw Cfg missing kernel cmdline")]
|
||||
MissingFwCfgCmdline,
|
||||
|
||||
#[cfg(feature = "fw_cfg")]
|
||||
#[error("Error creating e820 map")]
|
||||
CreatingE820Map(#[source] io::Error),
|
||||
}
|
||||
pub type Result<T> = result::Result<T, Error>;
|
||||
|
||||
@@ -801,6 +805,15 @@ impl Vm {
|
||||
device_manager: &Arc<Mutex<DeviceManager>>,
|
||||
config: &Arc<Mutex<VmConfig>>,
|
||||
) -> Result<()> {
|
||||
device_manager
|
||||
.lock()
|
||||
.unwrap()
|
||||
.fw_cfg()
|
||||
.expect("fw_cfg device must be present")
|
||||
.lock()
|
||||
.unwrap()
|
||||
.add_e820(config.lock().unwrap().memory.size as usize)
|
||||
.map_err(Error::CreatingE820Map)?;
|
||||
let kernel = config
|
||||
.lock()
|
||||
.unwrap()
|
||||
|
||||
Reference in New Issue
Block a user