Skip to main content

xen/foreignmemory/
mapped.rs

1use std::{
2    ffi::c_void,
3    ops::{Deref, DerefMut},
4};
5
6use xen_sys::{xenforeignmemory_map, xenforeignmemory_unmap};
7
8use super::{XenForeignMemory, XenForeignMemoryProtection};
9use crate::{XenDomainId, XenError, consts::PAGE_SIZE};
10
11pub struct XenForeignMemoryMapped {
12    foreignmemory: XenForeignMemory,
13    ptr: *mut c_void,
14    pages: usize,
15}
16
17impl XenForeignMemoryMapped {
18    pub(crate) fn new(
19        foreignmemory: XenForeignMemory,
20        domain_id: XenDomainId,
21        protection: XenForeignMemoryProtection,
22        arr: &[u64],
23        err: Option<&mut [i32]>,
24    ) -> Result<Self, XenError> {
25        if let Some(err) = &err {
26            debug_assert_eq!(arr.len(), err.len());
27        }
28
29        let ptr = unsafe {
30            xenforeignmemory_map(
31                foreignmemory.handle.0,
32                domain_id.0,
33                protection.bits(),
34                arr.len(),
35                arr.as_ptr() as *const _,
36                err.map_or_else(std::ptr::null_mut, <[_]>::as_mut_ptr),
37            )
38        };
39
40        if ptr.is_null() {
41            return Err(XenError::Io(std::io::Error::last_os_error()));
42        }
43
44        Ok(Self {
45            foreignmemory,
46            ptr,
47            pages: arr.len(),
48        })
49    }
50}
51
52impl Drop for XenForeignMemoryMapped {
53    fn drop(&mut self) {
54        //tracing::trace!("unmapping foreign memory");
55        unsafe {
56            xenforeignmemory_unmap(self.foreignmemory.handle.0, self.ptr, self.pages);
57        }
58    }
59}
60
61impl Deref for XenForeignMemoryMapped {
62    type Target = [u8];
63
64    #[inline]
65    fn deref(&self) -> &Self::Target {
66        unsafe {
67            std::slice::from_raw_parts(self.ptr as *const u8, self.pages * PAGE_SIZE as usize)
68        }
69    }
70}
71
72impl DerefMut for XenForeignMemoryMapped {
73    #[inline]
74    fn deref_mut(&mut self) -> &mut Self::Target {
75        unsafe {
76            std::slice::from_raw_parts_mut(self.ptr as *mut u8, self.pages * PAGE_SIZE as usize)
77        }
78    }
79}
80
81impl AsRef<[u8]> for XenForeignMemoryMapped {
82    fn as_ref(&self) -> &[u8] {
83        self.deref()
84    }
85}
86
87impl AsMut<[u8]> for XenForeignMemoryMapped {
88    fn as_mut(&mut self) -> &mut [u8] {
89        self.deref_mut()
90    }
91}