use ax_memory_addr::PhysAddr;
use axvm_types::{GuestPhysAddr, MappingFlags};
use super::Backend;
use crate::NestedPageTableOps;
impl<Npt: NestedPageTableOps> Backend<Npt> {
pub const fn new_linear(pa_to_va_delta: i128) -> Self {
Self::Linear { pa_to_va_delta }
}
fn linear_paddr(vaddr: GuestPhysAddr, pa_to_va_delta: i128) -> Option<PhysAddr> {
let paddr = (vaddr.as_usize() as i128).checked_sub(pa_to_va_delta)?;
usize::try_from(paddr).ok().map(PhysAddr::from)
}
pub(crate) fn map_linear(
&self,
start: GuestPhysAddr,
size: usize,
flags: MappingFlags,
pt: &mut Npt,
pa_to_va_delta: i128,
) -> bool {
let Some(pa_start) = Self::linear_paddr(start, pa_to_va_delta) else {
return false;
};
debug!(
"map_linear: [{:#x}, {:#x}) -> [{:#x}, {:#x}) {:?}",
start,
start + size,
pa_start,
pa_start + size,
flags
);
let allow_huge = true;
pt.map_region(
start,
|va| {
Self::linear_paddr(va, pa_to_va_delta)
.expect("linear mapping physical address underflow")
},
size,
flags,
allow_huge,
)
.is_ok()
}
pub(crate) fn unmap_linear(
&self,
start: GuestPhysAddr,
size: usize,
pt: &mut Npt,
_pa_to_va_delta: i128,
) -> bool {
debug!("unmap_linear: [{:#x}, {:#x})", start, start + size);
pt.unmap_region(start, size).is_ok()
}
}