xref: /aosp_15_r20/external/crosvm/arch/src/pstore.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
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 
5 use std::fs::OpenOptions;
6 
7 use anyhow::bail;
8 use anyhow::Context;
9 use anyhow::Result;
10 use base::MemoryMappingBuilder;
11 use hypervisor::MemCacheType;
12 use hypervisor::Vm;
13 use resources::AddressRange;
14 use vm_memory::GuestAddress;
15 
16 use crate::Pstore;
17 
18 mod sys;
19 
20 pub struct RamoopsRegion {
21     pub address: u64,
22     pub size: u32,
23 }
24 
25 /// Creates a mmio memory region for pstore.
create_memory_region( vm: &mut impl Vm, region: AddressRange, pstore: &Pstore, ) -> Result<RamoopsRegion>26 pub 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 
add_ramoops_kernel_cmdline( cmdline: &mut kernel_cmdline::Cmdline, ramoops_region: &RamoopsRegion, ) -> std::result::Result<(), kernel_cmdline::Error>66 pub 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.{}={:#x}", name, val))?;
80     }
81     Ok(())
82 }
83