twizzler_abi/syscall/
map_control.rs

1use twizzler_rt_abi::{
2    bindings::sync_info,
3    error::{ArgumentError, TwzError},
4    Result,
5};
6
7use super::{convert_codes_to_result, twzerr, Syscall};
8use crate::arch::syscall::raw_syscall;
9
10/// Possible map control commands for [sys_map_ctrl].
11#[derive(Clone, Copy, Debug)]
12pub enum MapControlCmd {
13    /// Sync an entire mapping
14    Sync(*const sync_info),
15    /// Discard a mapping
16    Discard,
17    /// Invalidate a mapping
18    Invalidate,
19    /// Update a mapping
20    Update,
21}
22
23impl From<MapControlCmd> for (u64, u64) {
24    fn from(c: MapControlCmd) -> Self {
25        match c {
26            MapControlCmd::Sync(x) => (0, x.addr() as u64),
27            MapControlCmd::Discard => (1, 0),
28            MapControlCmd::Invalidate => (2, 0),
29            MapControlCmd::Update => (3, 0),
30        }
31    }
32}
33
34impl TryFrom<(u64, u64)> for MapControlCmd {
35    type Error = TwzError;
36    fn try_from(value: (u64, u64)) -> Result<Self> {
37        Ok(match value.0 {
38            0 => MapControlCmd::Sync((value.1 as usize) as *const sync_info),
39            1 => MapControlCmd::Discard,
40            2 => MapControlCmd::Invalidate,
41            3 => MapControlCmd::Update,
42            _ => return Err(ArgumentError::InvalidArgument.into()),
43        })
44    }
45}
46
47/// Perform a kernel operation on this mapping.
48pub fn sys_map_ctrl(start: *const u8, len: usize, cmd: MapControlCmd, opts2: u64) -> Result<()> {
49    let (cmd, opts) = cmd.into();
50    let args = [start.addr() as u64, len as u64, cmd, opts, opts2];
51    let (code, val) = unsafe { raw_syscall(Syscall::MapCtrl, &args) };
52    convert_codes_to_result(code, val, |c, _| c != 0, |_, _| (), twzerr)
53}