pub struct NvramSpecServices<S: InspectableNvramStorage> { /* private fields */ }
Expand description

An implementation of UEFI spec 8.2 - Variable Services

This API tries to match the API defined by the UEFI spec 1:1, hence why it doesn’t look very “Rust-y”.

If you need to interact with NvramServices outside the context of the UEFI device itself, consider importing the NvramServicesExt trait. This trait provides various helper methods that make it easier to get/set nvram variables, without worrying about the nitty-gritty details of UCS-2 string encoding, pointer sizes/nullness, etc…

Instead of returning a typical Result type, these methods all return a tuple of (Option<T>, EfiStatus, Option<NvramError>), where the EfiStatus field should be unconditionally returned to the guest, while the NvramError type provides additional context as to what error occurred in OpenVMM (i.e: for logging purposes).

Implementations§

source§

impl<S: InspectableNvramStorage> NvramSpecServices<S>

source

pub fn new(storage: S) -> NvramSpecServices<S>

Construct a new NvramServices instance from an existing storage backend.

source

pub async fn is_empty(&mut self) -> Result<bool, NvramStorageError>

Check if the nvram store is empty.

source

pub async fn update_setup_mode(&mut self) -> Result<(), NvramStorageError>

Update “SetupMode” based on the current value of “PK”

From UEFI spec section 32.3

While no Platform Key is enrolled, the SetupMode variable shall be equal to 1. While SetupMode == 1, the platform firmware shall not require authentication in order to modify the Platform Key, Key Enrollment Key, OsRecoveryOrder, OsRecovery####, and image security databases.

After the Platform Key is enrolled, the SetupMode variable shall be equal to 0. While SetupMode == 0, the platform firmware shall require authentication in order to modify the Platform Key, Key Enrollment Key, OsRecoveryOrder, OsRecovery####, and image security databases.

source

pub fn exit_boot_services(&mut self)

Nvram behavior changes after the guest signals that ExitBootServices has been called (e.g: hiding variables that are only accessible at boot-time).

source

pub fn reset(&mut self)

Called when the VM resets to return to the preboot state.

source

pub fn prepare_for_boot(&mut self)

Called after injecting any pre-boot nvram vars, transitioning the nvram store to start accepting calls from guest UEFI.

source

pub async fn uefi_get_variable( &mut self, name: Option<&[u8]>, in_vendor: Guid, out_attr: &mut u32, in_out_data_size: &mut u32, data_is_null: bool, ) -> NvramResult<Option<Vec<u8>>>

Get a variable identified by name + vendor, returning the variable’s attributes and data.

  • in_name
    • (In) Variable name (a null-terminated UTF-16 string, or None if the guest passed a nullptr)
  • in_vendor
    • (In) Variable vendor guid
  • out_attr
    • (Out) Variable’s attributes
    • Note: According to the UEFI spec: attr will be populated on both EFI_SUCCESS and when EFI_BUFFER_TOO_SMALL is returned.
  • in_out_data_size
    • (In) Size of available data buffer (provided by guest)
    • (Out) Size of data to be written into buffer
    • Note: If data_is_null is true, and in_out_data_size is set to 0, in_out_data_size will be updated with the size required to store the variable.
  • data_is_null
    • (In) bool indicating if guest passed nullptr as the data addr
source

pub async fn uefi_set_variable( &mut self, name: Option<&[u8]>, in_vendor: Guid, in_attr: u32, in_data_size: u32, data: Option<Vec<u8>>, ) -> NvramResult<()>

Set a variable identified by name + vendor with the specified attr and data

  • name
    • (In) Variable name (a null-terminated UTF-16 string, or None if the guest passed a nullptr)
    • Note: name must contain one or more character.
  • in_vendor
    • (In) Variable vendor guid
  • in_attr
    • (In) Variable’s attributes
  • in_data_size
    • (In) Length of data to be written
    • If len in 0, and the EFI_VARIABLE_APPEND_WRITE, EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS, or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS are not set, the variable will be deleted.
  • data
    • (In) Variable data (or None if the guest passed a nullptr)
source

pub async fn uefi_get_next_variable( &mut self, in_out_name_size: &mut u32, name: Option<&[u8]>, vendor: Guid, ) -> NvramResult<Option<(Vec<u8>, Guid)>>

Return the variable immediately following the variable identified by name + vendor key.

If name is an empty string, the first variable is returned.

  • name
    • (In) Variable name (a null-terminated UTF-16 string, or None if the guest passed a nullptr)
  • in_out_name_size
    • (In) Length of the provided name
    • (Out) Length of the next variable name
    • Note: If there is insufficient space in the name buffer to store the next variable, in_out_name_size will be updated with the size required to store the variable.
  • vendor
    • (In) Variable vendor guid

Trait Implementations§

source§

impl<S: Debug + InspectableNvramStorage> Debug for NvramSpecServices<S>

source§

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

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

impl<S: InspectableNvramStorage> Inspect for NvramSpecServices<S>

source§

fn inspect(&self, req: Request<'_>)

Inspects the object.
source§

impl<S: InspectableNvramStorage> NvramServicesExt for NvramSpecServices<S>

source§

fn get_variable<'life0, 'life1, 'async_trait>( &'life0 mut self, vendor: Guid, name: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(u32, Vec<u8>), (EfiStatus, Option<NvramError>)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get a variable identified by name (as a Rust string) + vendor, returning the variable’s attributes and data.
source§

fn get_variable_ucs2<'life0, 'life1, 'async_trait>( &'life0 mut self, vendor: Guid, name: &'life1 Ucs2LeSlice, ) -> Pin<Box<dyn Future<Output = Result<(u32, Vec<u8>), (EfiStatus, Option<NvramError>)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get a variable identified by name (as a UCS-2 string) + vendor, returning the variable’s attributes and data.
source§

fn set_variable<'life0, 'life1, 'async_trait>( &'life0 mut self, vendor: Guid, name: &'life1 str, attr: u32, data: Vec<u8>, ) -> Pin<Box<dyn Future<Output = Result<(), (EfiStatus, Option<NvramError>)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Set a variable identified by name (as a Rust string) + vendor with the specified attr and data.
source§

fn set_variable_ucs2<'life0, 'life1, 'async_trait>( &'life0 mut self, vendor: Guid, name: &'life1 Ucs2LeSlice, attr: u32, data: Vec<u8>, ) -> Pin<Box<dyn Future<Output = Result<(), (EfiStatus, Option<NvramError>)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Set a variable identified by name (as a UCS-2 string) + vendor with the specified attr and data.
source§

impl<S: InspectableNvramStorage> SaveRestore for NvramSpecServices<S>

source§

type SavedState = SavedState

The concrete saved state type.
source§

fn save(&mut self) -> Result<Self::SavedState, SaveError>

Saves the object’s state.
source§

fn restore(&mut self, state: Self::SavedState) -> Result<(), RestoreError>

Restores the object’s state.

Auto Trait Implementations§

§

impl<S> Freeze for NvramSpecServices<S>
where S: Freeze,

§

impl<S> RefUnwindSafe for NvramSpecServices<S>
where S: RefUnwindSafe,

§

impl<S> Send for NvramSpecServices<S>

§

impl<S> Sync for NvramSpecServices<S>

§

impl<S> Unpin for NvramSpecServices<S>
where S: Unpin,

§

impl<S> UnwindSafe for NvramSpecServices<S>
where S: UnwindSafe,

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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.

§

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

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

source§

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>,

source§

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.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

impl<T, U> Upcast<U> for T
where U: Downcast<T>,