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