| // Copyright 2020 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| use std::fmt::{self, Display}; |
| use std::fs::OpenOptions; |
| use std::io; |
| |
| use crate::Pstore; |
| use kvm::Vm; |
| use resources::SystemAllocator; |
| use resources::{Alloc, MmioType}; |
| use sys_util::{GuestAddress, MemoryMapping}; |
| |
| /// Error for pstore. |
| #[derive(Debug)] |
| pub enum Error { |
| IoError(io::Error), |
| MmapError(sys_util::MmapError), |
| ResourcesError(resources::Error), |
| SysUtilError(sys_util::Error), |
| } |
| |
| impl Display for Error { |
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| use self::Error::*; |
| |
| match self { |
| IoError(e) => write!(f, "failed to create pstore backend file: {}", e), |
| MmapError(e) => write!(f, "failed to get file mapped address: {}", e), |
| ResourcesError(e) => write!(f, "failed to allocate pstore region: {}", e), |
| SysUtilError(e) => write!(f, "file to add pstore region to mmio: {}", e), |
| } |
| } |
| } |
| |
| impl std::error::Error for Error {} |
| type Result<T> = std::result::Result<T, Error>; |
| |
| pub struct RamoopsRegion { |
| pub address: u64, |
| pub size: u32, |
| } |
| |
| /// Creates a mmio memory region for pstore. |
| pub fn create_memory_region( |
| vm: &mut Vm, |
| resources: &mut SystemAllocator, |
| pstore: &Pstore, |
| ) -> Result<RamoopsRegion> { |
| let file = OpenOptions::new() |
| .read(true) |
| .write(true) |
| .create(true) |
| .open(&pstore.path) |
| .map_err(Error::IoError)?; |
| file.set_len(pstore.size as u64).map_err(Error::IoError)?; |
| |
| let address = resources |
| .mmio_allocator(MmioType::High) |
| .allocate(pstore.size as u64, Alloc::Pstore, "pstore".to_owned()) |
| .map_err(Error::ResourcesError)?; |
| |
| let memory_mapping = |
| MemoryMapping::from_fd(&file, pstore.size as usize).map_err(Error::MmapError)?; |
| |
| vm.add_mmio_memory(GuestAddress(address), memory_mapping, false, false) |
| .map_err(Error::SysUtilError)?; |
| |
| Ok(RamoopsRegion { |
| address, |
| size: pstore.size, |
| }) |
| } |