use std::fs::OpenOptions;
use anyhow::bail;
use anyhow::Context;
use anyhow::Result;
use base::MemoryMappingBuilder;
use hypervisor::MemCacheType;
use hypervisor::Vm;
use resources::AddressRange;
use vm_memory::GuestAddress;
use crate::Pstore;
mod sys;
pub struct RamoopsRegion {
pub address: u64,
pub size: u32,
}
pub fn create_memory_region(
vm: &mut impl Vm,
region: AddressRange,
pstore: &Pstore,
) -> Result<RamoopsRegion> {
let region_size = region.len().context("failed to get region len")?;
if region_size < pstore.size.into() {
bail!("insufficient space for pstore {} {}", region, pstore.size);
}
let mut open_opts = OpenOptions::new();
open_opts.read(true).write(true).create(true);
sys::set_extra_open_opts(&mut open_opts);
let file = open_opts
.open(&pstore.path)
.context("failed to open pstore")?;
file.set_len(pstore.size as u64)
.context("failed to set pstore length")?;
let memory_mapping = MemoryMappingBuilder::new(pstore.size as usize)
.from_file(&file)
.build()
.context("failed to mmap pstore")?;
vm.add_memory_region(
GuestAddress(region.start),
Box::new(memory_mapping),
false,
false,
MemCacheType::CacheCoherent,
)
.context("failed to add pstore region")?;
Ok(RamoopsRegion {
address: region.start,
size: pstore.size,
})
}
pub fn add_ramoops_kernel_cmdline(
cmdline: &mut kernel_cmdline::Cmdline,
ramoops_region: &RamoopsRegion,
) -> std::result::Result<(), kernel_cmdline::Error> {
let ramoops_opts = [
("mem_address", ramoops_region.address),
("mem_size", ramoops_region.size as u64),
];
for (name, val) in &ramoops_opts {
cmdline.insert_str(format!("ramoops.{}={:#x}", name, val))?;
}
Ok(())
}