xen/foreignmemory/
mapped.rs1use 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 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}