blob: 70fdd0a9ab64d1565c30d445d2975467131803c0 [file] [log] [blame]
// Copyright 2023, The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! This module regroups some common traits shared by all the hypervisors.
use crate::error::{Error, Result};
use crate::util::SIZE_4KB;
/// Expected MMIO guard granule size, validated during MMIO guard initialization.
pub const MMIO_GUARD_GRANULE_SIZE: usize = SIZE_4KB;
/// Trait for the hypervisor.
pub trait Hypervisor {
/// Returns the hypervisor's MMIO_GUARD implementation, if any.
fn as_mmio_guard(&self) -> Option<&dyn MmioGuardedHypervisor> {
None
}
/// Returns the hypervisor's dynamic memory sharing implementation, if any.
fn as_mem_sharer(&self) -> Option<&dyn MemSharingHypervisor> {
None
}
}
pub trait MmioGuardedHypervisor {
/// Enrolls with the MMIO guard so that all MMIO will be blocked unless allow-listed with
/// `MmioGuardedHypervisor::map`.
fn enroll(&self) -> Result<()>;
/// Maps a page containing the given memory address to the hypervisor MMIO guard.
/// The page size corresponds to the MMIO guard granule size.
fn map(&self, addr: usize) -> Result<()>;
/// Unmaps a page containing the given memory address from the hypervisor MMIO guard.
/// The page size corresponds to the MMIO guard granule size.
fn unmap(&self, addr: usize) -> Result<()>;
/// Returns the MMIO guard granule size in bytes.
fn granule(&self) -> Result<usize>;
// TODO(ptosi): Fully move granule validation to client code.
/// Validates the MMIO guard granule size.
fn validate_granule(&self) -> Result<()> {
match self.granule()? {
MMIO_GUARD_GRANULE_SIZE => Ok(()),
granule => Err(Error::UnsupportedMmioGuardGranule(granule)),
}
}
}
pub trait MemSharingHypervisor {
/// Shares a region of memory with host, granting it read, write and execute permissions.
/// The size of the region is equal to the memory protection granule returned by
/// [`hyp_meminfo`].
fn share(&self, base_ipa: u64) -> Result<()>;
/// Revokes access permission from host to a memory region previously shared with
/// [`mem_share`]. The size of the region is equal to the memory protection granule returned by
/// [`hyp_meminfo`].
fn unshare(&self, base_ipa: u64) -> Result<()>;
/// Returns the memory protection granule size in bytes.
fn granule(&self) -> Result<usize>;
}