pub struct Userfaultfd {
    uffd: Uffd,
}
Expand description

Wrapper for [userfaultfd::Uffd] to be used in the vmm-swap feature.

Safety

The userfaultfd operations (UFFDIO_COPY and UFFDIO_ZEROPAGE) looks unsafe since it fills a memory content directly. But they actually are not unsafe operation but UFFDIO_REGISTER should be the unsafe operation for Rust memory safety.

According to the Rust document,

All runtime-allocated memory in a Rust program begins its life as uninitialized.

The userfaultfd operations actually does not change/overwrite the existing memory contents but they just setup the “uninitialized” pages. If the page was already initialized, the userfaultfd operations fail and return EEXIST error (which is not documented unfortunately). So they originally does not affect the Rust memory safety.

The “uninitialized” page in this context has 2 patterns:

  1. pages which is never touched or,
  2. pages which is never touched after MADV_REMOVE

Filling the (1) pages with any contents should not affect the Rust memory safety.

Filling the (2) pages potentially may break the memory used by Rust. But the safety should be examined at MADV_REMOVE and UFFDIO_REGISTER timing.

Fields§

§uffd: Uffd

Implementations§

source§

impl Userfaultfd

source

pub fn new() -> Result<Self>

Creates a new userfaultfd using userfaultfd(2) syscall.

This is public for tests.

source

pub unsafe fn register(&self, addr: usize, len: usize) -> Result<IoctlFlags>

Register a range of memory to the userfaultfd.

After this registration, any page faults on the range will be caught by the userfaultfd.

Arguments
  • addr - the starting address of the range of memory.
  • len - the length in bytes of the range of memory.
Safety

[addr, addr+len) must lie within a [MemoryMapping], and that mapping must live for the lifespan of the userfaultfd kernel object (which may be distinct from the Userfaultfd rust object in this process).

source

pub fn unregister(&self, addr: usize, len: usize) -> Result<()>

Unregister a range of memory from the userfaultfd.

Arguments
  • addr - the starting address of the range of memory.
  • len - the length in bytes of the range of memory.
source

pub fn zero(&self, addr: usize, len: usize, wake: bool) -> Result<usize>

Initialize page(s) and fill it with zero.

Arguments
  • addr - the starting address of the page(s) to be initialzed with zero.
  • len - the length in bytes of the page(s).
  • wake - whether or not to unblock the faulting thread.
source

pub fn copy( &self, addr: usize, len: usize, data: *const u8, wake: bool ) -> Result<usize>

Copy the data to the page(s) starting from addr.

Arguments
  • addr - the starting address of the page(s) to be initialzed with data.
  • len - the length in bytes of the page(s).
  • data - the starting address of the content.
  • wake - whether or not to unblock the faulting thread.
source

pub fn wake(&self, addr: usize, len: usize) -> Result<()>

Wake the faulting thread blocked by the page(s).

If the page is not initialized, the thread causes a page fault again.

Arguments
  • addr - the starting address of the page(s).
  • len - the length in bytes of the page(s).
source

pub fn read_event(&self) -> Result<Option<UffdEvent>>

Read an event from the userfaultfd.

Return None immediately if no events is ready to read.

source

pub fn try_clone(&self) -> Result<Self>

Try to clone Userfaultfd

Trait Implementations§

source§

impl AsRawDescriptor for Userfaultfd

source§

fn as_raw_descriptor(&self) -> RawDescriptor

Returns the underlying raw descriptor. Read more
source§

impl Debug for Userfaultfd

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl From<Uffd> for Userfaultfd

source§

fn from(uffd: Uffd) -> Self

Converts to this type from the input type.
source§

impl FromRawDescriptor for Userfaultfd

source§

unsafe fn from_raw_descriptor(descriptor: RawDescriptor) -> Self

Safety Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> AsRawDescriptors for Twhere T: AsRawDescriptor,

§

fn as_raw_descriptors(&self) -> Vec<i32, Global>

Returns the underlying raw descriptors. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.