microsoft/openvmm

Public

mirrored fromhttps://github.com/microsoft/openvmmAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
0e50fcfba5329deb9a6dc1d352bf702cc6ffa4cc

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

openhcl/hcl/src/mapped_page.rs

68lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use std::cell::UnsafeCell;
5use std::fs::File;
6use std::io;
7use std::os::fd::AsRawFd;
8use std::ptr::NonNull;
9
10pub(crate) struct MappedPage<T>(NonNull<UnsafeCell<T>>);
11
12impl<T> MappedPage<T> {
13 pub fn new(fd: &File, pg_off: i64) -> io::Result<Self> {
14 // Make sure any T we're using can fit in any size page.
15 assert!(size_of::<T>() <= 4096);
16
17 // SAFETY: calling mmap as documented to create a new mapping.
18 let ptr = unsafe {
19 let page_size = libc::sysconf(libc::_SC_PAGESIZE);
20 libc::mmap(
21 std::ptr::null_mut(),
22 page_size as usize,
23 libc::PROT_READ | libc::PROT_WRITE,
24 libc::MAP_SHARED,
25 fd.as_raw_fd(),
26 pg_off * page_size,
27 )
28 };
29 if ptr == libc::MAP_FAILED {
30 return Err(io::Error::last_os_error());
31 }
32
33 Ok(Self(NonNull::new(ptr).unwrap().cast()))
34 }
35
36 pub fn as_ptr(&self) -> *mut T {
37 UnsafeCell::raw_get(self.0.as_ptr())
38 }
39
40 pub fn as_ref(&self) -> &UnsafeCell<T> {
41 // SAFETY: The pointer is valid and mapped for the lifetime of the struct,
42 // it will only every point to a T, and UnsafeCell allows interior mutability.
43 unsafe { self.0.as_ref() }
44 }
45}
46
47impl<T> std::fmt::Debug for MappedPage<T> {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 f.debug_tuple("MappedPage").field(&self.0).finish()
50 }
51}
52
53impl<T> Drop for MappedPage<T> {
54 fn drop(&mut self) {
55 // SAFETY: unmapping memory mapped at construction.
56 unsafe {
57 libc::munmap(
58 self.0.as_ptr().cast(),
59 libc::sysconf(libc::_SC_PAGESIZE) as usize,
60 );
61 }
62 }
63}
64
65// SAFETY: this is just a pointer value.
66unsafe impl<T> Send for MappedPage<T> {}
67// SAFETY: see above comment
68unsafe impl<T> Sync for MappedPage<T> {}
69