twizzler_abi/syscall/
map_control.rs1use core::sync::atomic::{AtomicU64, Ordering};
2
3use twizzler_rt_abi::{
4 error::{ArgumentError, RawTwzError, ResourceError, TwzError},
5 Result,
6};
7
8use super::{convert_codes_to_result, twzerr, Syscall};
9use crate::arch::syscall::raw_syscall;
10
11bitflags::bitflags! {
12 #[derive(Debug, Clone, Copy)]
14 pub struct SyncFlags: u32 {
15 const DURABLE = 1 << 0;
17 const ASYNC_DURABLE = 1 << 0;
19 }
20}
21
22#[derive(Debug, Clone, Copy)]
24pub struct SyncInfo {
25 pub release: *const AtomicU64,
27 pub release_compare: u64,
29 pub release_set: u64,
31 pub durable: *const AtomicU64,
33 pub flags: SyncFlags,
35}
36
37unsafe impl Send for SyncInfo {}
38unsafe impl Sync for SyncInfo {}
39
40impl SyncInfo {
41 pub unsafe fn try_release(&self) -> Result<()> {
42 self.release
43 .as_ref()
44 .unwrap()
45 .compare_exchange(
46 self.release_compare,
47 self.release_set,
48 Ordering::SeqCst,
49 Ordering::SeqCst,
50 )
51 .map_err(|_| TwzError::Resource(ResourceError::Refused))
52 .map(|_| ())
53 }
54
55 pub unsafe fn set_durable(&self, err: impl Into<RawTwzError>) {
56 if self.durable.is_null() {
57 return;
58 }
59
60 self.durable
61 .as_ref()
62 .unwrap()
63 .store(err.into().raw(), Ordering::SeqCst);
64 }
65}
66
67#[derive(Clone, Copy, Debug)]
69pub enum MapControlCmd {
70 Sync(*const SyncInfo),
72 Discard,
74 Invalidate,
76 Update,
78}
79
80impl From<MapControlCmd> for (u64, u64) {
81 fn from(c: MapControlCmd) -> Self {
82 match c {
83 MapControlCmd::Sync(x) => (0, x.addr() as u64),
84 MapControlCmd::Discard => (1, 0),
85 MapControlCmd::Invalidate => (2, 0),
86 MapControlCmd::Update => (3, 0),
87 }
88 }
89}
90
91impl TryFrom<(u64, u64)> for MapControlCmd {
92 type Error = TwzError;
93 fn try_from(value: (u64, u64)) -> Result<Self> {
94 Ok(match value.0 {
95 0 => MapControlCmd::Sync((value.1 as usize) as *const SyncInfo),
96 1 => MapControlCmd::Discard,
97 2 => MapControlCmd::Invalidate,
98 3 => MapControlCmd::Update,
99 _ => return Err(ArgumentError::InvalidArgument.into()),
100 })
101 }
102}
103
104pub fn sys_map_ctrl(start: *const u8, len: usize, cmd: MapControlCmd, opts2: u64) -> Result<()> {
106 let (cmd, opts) = cmd.into();
107 let args = [start.addr() as u64, len as u64, cmd, opts, opts2];
108 let (code, val) = unsafe { raw_syscall(Syscall::MapCtrl, &args) };
109 convert_codes_to_result(code, val, |c, _| c != 0, |_, _| (), twzerr)
110}