Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
5953e7f
msg_proto
Dec 10, 2025
6299b38
improve optee msg handlers
Dec 11, 2025
8048e8a
improve abstraction
Dec 11, 2025
c7310c3
revison and add RemotePtr placeholders
Dec 11, 2025
09db748
rename
Dec 11, 2025
e3c6785
revision
Dec 12, 2025
03bfe78
revise remote pointers
Dec 12, 2025
00bd8bb
ratchet
Dec 12, 2025
11bd6b1
handle ta request. wip
Dec 12, 2025
f4a7103
support tmem and some revision
Dec 12, 2025
4f814dd
fix tmem and rmem handling
Dec 12, 2025
0343958
separate out handle_ta_request
Dec 12, 2025
0b2f39b
get os uuid
Dec 12, 2025
c79d8f3
comment
Dec 12, 2025
102cfa9
replace Errno with OpteeSmcReturn
Dec 12, 2025
ea8335f
add comments
Dec 14, 2025
16850b8
validate message
Dec 14, 2025
0ca522a
clarification
Dec 15, 2025
f2ea3b8
get rid of recursive handler invocation
Dec 16, 2025
68dd2c6
some docs for physical pointer (wip)
Dec 19, 2025
a5b3161
improve phys ptr abstraction (wip)
Dec 20, 2025
0723e9d
checkpoint
Dec 22, 2025
ebe9393
separate const and mut ptrs
Dec 22, 2025
88e2154
read/write slice
Dec 22, 2025
4a2a7b3
revised
Dec 22, 2025
1e2b158
check page contiguity
Dec 23, 2025
27152aa
VmapProvider
Dec 23, 2025
0c32c92
addressed comments
Dec 24, 2025
b40a151
impl Drop for PhysPtrs
Dec 24, 2025
5063f72
VmapProvider validate and protect
Dec 24, 2025
b4ab389
use existing NonZeroAddress
Dec 26, 2025
3bb2fc2
rename
Dec 29, 2025
fadf32d
use PhysPageAddr for ShmRefMap
Dec 29, 2025
7c387a9
clarification
Jan 8, 2026
9a88e08
handle TA request (wip)
Dec 15, 2025
bc469ff
read_data_from_shm_phys_addrs
Dec 16, 2025
368cdf4
ta uuid
Dec 16, 2025
cc24af9
prepare for return to normal world
Dec 16, 2025
2fcbde4
drop out_addresses from utee_params
Dec 16, 2025
a02d0d4
optee_msg_handler upcall (wip)
Dec 17, 2025
64ca1b8
rebase
Dec 23, 2025
dcd3023
revision with new APIs
Dec 23, 2025
5a9fca5
rebase
Dec 26, 2025
f60ac6a
rebase
Dec 29, 2025
7f7bb82
remove vsm_optee_smc from the LVBS platform
Dec 29, 2025
fe1171d
fix TeeUuid
Dec 29, 2025
e8b07e9
explictly use page_offset
Dec 29, 2025
5b4fcf9
xsave
Dec 30, 2025
1293f24
clarify
Jan 9, 2026
8700931
refactoring
Jan 9, 2026
3b85f35
feedbacks
Jan 23, 2026
eee0380
refactor
Jan 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion dev_tests/src/ratchet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn ratchet_globals() -> Result<()> {
("litebox_runner_lvbs/", 3),
("litebox_runner_snp/", 1),
("litebox_shim_linux/", 1),
("litebox_shim_optee/", 6),
("litebox_shim_optee/", 7),
],
|file| {
Ok(file
Expand Down Expand Up @@ -65,6 +65,7 @@ fn ratchet_maybe_uninit() -> Result<()> {
("litebox_platform_linux_userland/", 3),
("litebox_platform_lvbs/", 5),
("litebox_shim_linux/", 5),
("litebox_shim_optee/", 1),
],
|file| {
Ok(file
Expand Down
1 change: 1 addition & 0 deletions litebox/src/mm/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ impl<const ALIGN: usize> core::ops::Add<usize> for NonZeroPageSize<ALIGN> {
}

/// A non-zero address that is `ALIGN`-aligned.
#[derive(Clone, Copy)]
pub struct NonZeroAddress<const ALIGN: usize>(usize);

impl<const ALIGN: usize> NonZeroAddress<ALIGN> {
Expand Down
1 change: 1 addition & 0 deletions litebox/src/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
pub mod common_providers;
pub mod page_mgmt;
pub mod trivial_providers;
pub mod vmap;

#[cfg(test)]
pub(crate) mod mock;
Expand Down
177 changes: 177 additions & 0 deletions litebox/src/platform/vmap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

use crate::platform::page_mgmt::MemoryRegionPermissions;
use thiserror::Error;

/// A provider to map and unmap physical pages with virtually contiguous addresses.
///
/// `ALIGN`: The page frame size.
///
/// This provider is written to implement `litebox_shim_optee::ptr::PhysMutPtr` and
/// `litebox_shim_optee::ptr::PhysConstPtr`. It can benefit other modules which need
/// Linux kernel's `vmap()` and `vunmap()` functionalities (e.g., HVCI/HEKI, drivers).
pub trait VmapProvider<const ALIGN: usize> {
/// Data structure for an array of physical page addresses which are virtually contiguous.
type PhysPageAddrArray;

/// Data structure to maintain the mapping information returned by `vmap()`.
type PhysPageMapInfo;

/// Map the given `PhysPageAddrArray` into virtually contiguous addresses with the given
/// [`PhysPageMapPermissions`] while returning [`PhysPageMapInfo`]. This function
/// expects that it can access and update the page table using `&self`.
///
/// This function is analogous to Linux kernel's `vmap()`.
///
/// # Safety
///
/// The caller should ensure that `pages` are not in active use by other entities
/// (especially, there should be no read/write or write/write conflicts).
/// Unfortunately, LiteBox itself cannot fully guarantee this and it needs some helps
/// from the caller, hypervisor, or hardware.
/// Multiple LiteBox threads might concurrently call this function with overlapping
/// physical pages, so the implementation should safely handle such cases.
unsafe fn vmap(
&self,
pages: Self::PhysPageAddrArray,
perms: PhysPageMapPermissions,
) -> Result<Self::PhysPageMapInfo, PhysPointerError>;

/// Unmap the previously mapped virtually contiguous addresses ([`PhysPageMapInfo`]).
/// Use `&self` to access and update the page table.
///
/// This function is analogous to Linux kernel's `vunmap()`.
///
/// # Safety
///
/// The caller should ensure that the virtual addresses in `vmap_info` are not in active
/// use by other entities.
unsafe fn vunmap(&self, vmap_info: Self::PhysPageMapInfo) -> Result<(), PhysPointerError>;

/// Validate that the given physical pages do not belong to LiteBox-owned memory.
/// Use `&self` to get the memory layout of the platform (i.e., the physical memory
/// range assigned to LiteBox).
///
/// This function is a no-op if there is no other world or VM sharing the physical memory.
///
/// Returns `Ok(())` if valid. If the pages are not valid, returns `Err(PhysPointerError)`.
fn validate(&self, pages: Self::PhysPageAddrArray) -> Result<(), PhysPointerError>;

/// Protect the given physical pages to ensure concurrent read or exclusive write access:
/// - Read protection: prevent others from writing to the pages.
/// - Read/write protection: prevent others from reading or writing to the pages.
/// - No protection: allow others to read and write the pages.
///
/// This function can be implemented using EPT/NPT, TZASC, PMP, or some other hardware mechanisms.
/// It is a no-op if there is no other world or VM sharing the physical memory.
///
/// Returns `Ok(())` if it successfully protects the pages. If it fails, returns
/// `Err(PhysPointerError)`.
///
/// # Safety
///
/// Since this function is expected to use hypercalls or other privileged hardware features,
/// the caller must ensure that it is safe to perform such operations at the time of the call.
/// Also, the caller should unprotect the pages when they are no longer needed to be protected.
unsafe fn protect(
&self,
pages: Self::PhysPageAddrArray,
perms: PhysPageMapPermissions,
) -> Result<(), PhysPointerError>;
}

/// Data structure representing a physical address with page alignment.
///
/// Currently, this is an alias to `crate::mm::linux::NonZeroAddress`. This might change if
/// we selectively conduct sanity checks based on whether an address is virtual or physical
/// (e.g., whether a virtual address is canonical, whether a physical address is tagged with
/// a valid key ID, etc.).
pub type PhysPageAddr<const ALIGN: usize> = crate::mm::linux::NonZeroAddress<ALIGN>;

/// Data structure to maintain the mapping information returned by `vmap()`.
///
/// `base` is the virtual address of the mapped region which is page aligned.
/// `size` is the size of the mapped region in bytes.
#[derive(Clone)]
pub struct PhysPageMapInfo<const ALIGN: usize> {
pub base: *mut u8,
pub size: usize,
}

bitflags::bitflags! {
/// Physical page map permissions which is a restricted version of
/// [`litebox::platform::page_mgmt::MemoryRegionPermissions`].
///
/// This module only supports READ and WRITE permissions. Both EXECUTE and SHARED
/// permissions are explicitly prohibited.
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct PhysPageMapPermissions: u8 {
/// Readable
const READ = 1 << 0;
/// Writable
const WRITE = 1 << 1;
const _ = !0;
}
}

impl From<MemoryRegionPermissions> for PhysPageMapPermissions {
fn from(perms: MemoryRegionPermissions) -> Self {
let mut phys_perms = PhysPageMapPermissions::empty();
if perms.contains(MemoryRegionPermissions::READ) {
phys_perms |= PhysPageMapPermissions::READ;
}
if perms.contains(MemoryRegionPermissions::WRITE) {
phys_perms |= PhysPageMapPermissions::WRITE;
}
phys_perms
}
}

impl From<PhysPageMapPermissions> for MemoryRegionPermissions {
fn from(perms: PhysPageMapPermissions) -> Self {
let mut mem_perms = MemoryRegionPermissions::empty();
if perms.contains(PhysPageMapPermissions::READ) {
mem_perms |= MemoryRegionPermissions::READ;
}
if perms.contains(PhysPageMapPermissions::WRITE) {
mem_perms |= MemoryRegionPermissions::WRITE;
}
mem_perms
}
}

/// Possible errors for physical pointer access with `VmapProvider`
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum PhysPointerError {
#[error("Physical address {0:#x} is invalid to access")]
InvalidPhysicalAddress(usize),
#[error("Physical address {0:#x} is not aligned to {1} bytes")]
UnalignedPhysicalAddress(usize, usize),
#[error("Offset {0:#x} is not aligned to {1} bytes")]
UnalignedOffset(usize, usize),
#[error("Base offset {0:#x} is greater than or equal to alignment ({1} bytes)")]
InvalidBaseOffset(usize, usize),
#[error(
"The total size of the given pages ({0} bytes) is insufficient for the requested type ({1} bytes)"
)]
InsufficientPhysicalPages(usize, usize),
#[error("Index {0} is out of bounds (count: {1})")]
IndexOutOfBounds(usize, usize),
#[error("Physical address {0:#x} is already mapped")]
AlreadyMapped(usize),
#[error("Physical address {0:#x} is unmapped")]
Unmapped(usize),
#[error("No mapping information available")]
NoMappingInfo,
#[error("Overflow occurred during calculation")]
Overflow,
#[error("Non-contiguous physical pages in the array")]
NonContiguousPages,
#[error("The operation is unsupported on this platform")]
UnsupportedOperation,
#[error("Unsupported permissions: {0:#x}")]
UnsupportedPermissions(u8),
}
1 change: 1 addition & 0 deletions litebox_common_optee/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ litebox = { path = "../litebox/", version = "0.1.0" }
litebox_common_linux = { path = "../litebox_common_linux/", version = "0.1.0" }
modular-bitfield = { version = "0.12.0", default-features = false }
num_enum = { version = "0.7.3", default-features = false }
thiserror = { version = "2.0.6", default-features = false }

[lints]
workspace = true
Loading