pub struct DeviceRange<'a>(/* private fields */);
Expand description

Represents a range of memory as seen from the device.

A DeviceRange can be accessed through the try_ptr and try_mut_ptr methods. Although these functions are guaranteed to point to valid memory, due to the requirements on new, raw pointers are still returned as the memory may always be being modified in parallel by the guest and so references cannot be safely created. The onus therefore is on the caller to access this memory in a way that is safe under concurrent modifications.

Although there may be concurrent modifications, these are only from the guest, and it can be assumed that a DeviceRange does not alias any other Rust objects from the heap, stack, globals etc.

With the requirements on new users of a DeviceRange can assume that pointers returned from try_ptr and try_mut_ptr are valid for reads and writes and are correctly aligned. Further, it can be assumed that ptr.offset(N) is valid for any N < len() / size_of::<T>(). These pointer are only valid as long as the original DeviceRange is still alive.

The expected way to get DeviceRange is through DriverMem::translate, and it is only implementations of that trait that are expected to use new and actually construct a DeviceRange.

Implementations§

source§

impl<'a> DeviceRange<'a>

source

pub fn split_at(&self, offset: usize) -> Option<(Self, Self)>

Split the range at offset producing two new ranges.

Returns None if offset is not in the range, otherwise produces the two ranges [start.. start + offset) and [start + offset ..end).

source

pub fn len(&self) -> usize

source

pub unsafe fn new(range: Range<usize>) -> Self

Construct a new DeviceRange.

§Safety

The provided range must be:

  • Valid memory that can be read or written to if it were cast to a pointer.
  • Not alias any Rust objects from the heap, stack, globals etc.
  • Remain valid for the lifetime 'a.
source

pub fn try_mut_ptr<T>(&self) -> Option<*mut T>

Attempt to get a pointer to a mutable T at the start of the range.

Returns a None if the range is too small to represent a T, or if the start of the range has the wrong alignment. Although there ways to safely perform accesses to unaligned pointers, as virtio requires all objects to be placed with correct alignment any misalignment represents a configuration issue.

The caller may assume that if a pointer is returned that it is valid for reads and writes of an object of size and alignment of T, however no guarantee is made on T being a copy-able object that can be safely read or written. Further, the returned pointer is valid only as long as the underlying DeviceRange is alive.

source

pub fn try_ptr<T>(&self) -> Option<*const T>

Attempt to get a pointer to a T at the start of the range.

See try_mut_ptr.

source

pub fn get(&self) -> Range<usize>

Retrieve the underlying range.

Trait Implementations§

source§

impl<'a> Clone for DeviceRange<'a>

source§

fn clone(&self) -> DeviceRange<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for DeviceRange<'a>

source§

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

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

impl<'a> PartialEq for DeviceRange<'a>

source§

fn eq(&self, other: &DeviceRange<'a>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<'a> Eq for DeviceRange<'a>

source§

impl<'a> StructuralPartialEq for DeviceRange<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for DeviceRange<'a>

§

impl<'a> RefUnwindSafe for DeviceRange<'a>

§

impl<'a> Send for DeviceRange<'a>

§

impl<'a> Sync for DeviceRange<'a>

§

impl<'a> Unpin for DeviceRange<'a>

§

impl<'a> UnwindSafe for DeviceRange<'a>

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where 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 T
where 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> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where 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 T
where 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.