• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Chromium OS Authors. All rights reserved.
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::fmt::{self, Display};
6 use std::fs::OpenOptions;
7 use std::io;
8 
9 use crate::Pstore;
10 use base::MemoryMappingBuilder;
11 use hypervisor::Vm;
12 use resources::SystemAllocator;
13 use resources::{Alloc, MmioType};
14 use vm_memory::GuestAddress;
15 
16 /// Error for pstore.
17 #[derive(Debug)]
18 pub enum Error {
19     IoError(io::Error),
20     MmapError(base::MmapError),
21     ResourcesError(resources::Error),
22     SysUtilError(base::Error),
23 }
24 
25 impl Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result26     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
27         use self::Error::*;
28 
29         match self {
30             IoError(e) => write!(f, "failed to create pstore backend file: {}", e),
31             MmapError(e) => write!(f, "failed to get file mapped address: {}", e),
32             ResourcesError(e) => write!(f, "failed to allocate pstore region: {}", e),
33             SysUtilError(e) => write!(f, "file to add pstore region to mmio: {}", e),
34         }
35     }
36 }
37 
38 impl std::error::Error for Error {}
39 type Result<T> = std::result::Result<T, Error>;
40 
41 pub struct RamoopsRegion {
42     pub address: u64,
43     pub size: u32,
44 }
45 
46 /// Creates a mmio memory region for pstore.
create_memory_region( vm: &mut impl Vm, resources: &mut SystemAllocator, pstore: &Pstore, ) -> Result<RamoopsRegion>47 pub fn create_memory_region(
48     vm: &mut impl Vm,
49     resources: &mut SystemAllocator,
50     pstore: &Pstore,
51 ) -> Result<RamoopsRegion> {
52     let file = OpenOptions::new()
53         .read(true)
54         .write(true)
55         .create(true)
56         .open(&pstore.path)
57         .map_err(Error::IoError)?;
58     file.set_len(pstore.size as u64).map_err(Error::IoError)?;
59 
60     let address = resources
61         .mmio_allocator(MmioType::High)
62         .allocate(pstore.size as u64, Alloc::Pstore, "pstore".to_owned())
63         .map_err(Error::ResourcesError)?;
64 
65     let memory_mapping = MemoryMappingBuilder::new(pstore.size as usize)
66         .from_file(&file)
67         .build()
68         .map_err(Error::MmapError)?;
69 
70     vm.add_memory_region(
71         GuestAddress(address),
72         Box::new(memory_mapping),
73         false,
74         false,
75     )
76     .map_err(Error::SysUtilError)?;
77 
78     Ok(RamoopsRegion {
79         address,
80         size: pstore.size,
81     })
82 }
83