arch/
pstore.rs

1// Copyright 2020 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::fs::OpenOptions;
6
7use anyhow::bail;
8use anyhow::Context;
9use anyhow::Result;
10use base::MemoryMappingBuilder;
11use hypervisor::MemCacheType;
12use hypervisor::Vm;
13use resources::AddressRange;
14use vm_memory::GuestAddress;
15
16use crate::Pstore;
17
18mod sys;
19
20pub struct RamoopsRegion {
21    pub address: u64,
22    pub size: u32,
23}
24
25/// Creates a mmio memory region for pstore.
26pub fn create_memory_region(
27    vm: &mut impl Vm,
28    region: AddressRange,
29    pstore: &Pstore,
30) -> Result<RamoopsRegion> {
31    let region_size = region.len().context("failed to get region len")?;
32    if region_size < pstore.size.into() {
33        bail!("insufficient space for pstore {} {}", region, pstore.size);
34    }
35
36    let mut open_opts = OpenOptions::new();
37    open_opts.read(true).write(true).create(true);
38    sys::set_extra_open_opts(&mut open_opts);
39
40    let file = open_opts
41        .open(&pstore.path)
42        .context("failed to open pstore")?;
43    file.set_len(pstore.size as u64)
44        .context("failed to set pstore length")?;
45
46    let memory_mapping = MemoryMappingBuilder::new(pstore.size as usize)
47        .from_file(&file)
48        .build()
49        .context("failed to mmap pstore")?;
50
51    vm.add_memory_region(
52        GuestAddress(region.start),
53        Box::new(memory_mapping),
54        false,
55        false,
56        MemCacheType::CacheCoherent,
57    )
58    .context("failed to add pstore region")?;
59
60    Ok(RamoopsRegion {
61        address: region.start,
62        size: pstore.size,
63    })
64}
65
66pub fn add_ramoops_kernel_cmdline(
67    cmdline: &mut kernel_cmdline::Cmdline,
68    ramoops_region: &RamoopsRegion,
69) -> std::result::Result<(), kernel_cmdline::Error> {
70    // It seems that default record_size is only 4096 byte even if crosvm allocates
71    // more memory. It means that one crash can only 4096 byte.
72    // Set record_size and console_size to 1/4 of allocated memory size.
73    // This configulation is same as the host.
74    let ramoops_opts = [
75        ("mem_address", ramoops_region.address),
76        ("mem_size", ramoops_region.size as u64),
77    ];
78    for (name, val) in &ramoops_opts {
79        cmdline.insert_str(format!("ramoops.{name}={val:#x}"))?;
80    }
81    Ok(())
82}