Merge "pvmfw: Optimize MMIO guard map"
diff --git a/libs/libfdt/Android.bp b/libs/libfdt/Android.bp
index 72399b0..5a729f1 100644
--- a/libs/libfdt/Android.bp
+++ b/libs/libfdt/Android.bp
@@ -37,6 +37,7 @@
],
rustlibs: [
"liblibfdt_bindgen",
+ "libzerocopy_nostd",
],
whole_static_libs: [
"libfdt",
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index 9785941..df1058e 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -26,6 +26,7 @@
use core::fmt;
use core::mem;
use core::result;
+use zerocopy::AsBytes as _;
/// Error type corresponding to libfdt error codes.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -441,6 +442,13 @@
fdt_err_expect_zero(ret)
}
+ /// Replace the value of the given (address, size) pair property with the given value, and
+ /// ensure that the given value has the same length as the current value length
+ pub fn setprop_addrrange_inplace(&mut self, name: &CStr, addr: u64, size: u64) -> Result<()> {
+ let pair = [addr.to_be(), size.to_be()];
+ self.setprop_inplace(name, pair.as_bytes())
+ }
+
/// Create or change a flag-like empty property.
pub fn setprop_empty(&mut self, name: &CStr) -> Result<()> {
self.setprop(name, &[])
@@ -459,6 +467,17 @@
fdt_err_expect_zero(ret)
}
+ /// Overwrite the given property with FDT_NOP, effectively removing it from the DT.
+ pub fn nop_property(&mut self, name: &CStr) -> Result<()> {
+ // SAFETY - Accesses are constrained to the DT totalsize (validated by ctor) when the
+ // library locates the node's property.
+ let ret = unsafe {
+ libfdt_bindgen::fdt_nop_property(self.fdt.as_mut_ptr(), self.offset, name.as_ptr())
+ };
+
+ fdt_err_expect_zero(ret)
+ }
+
/// Reduce the size of the given property to new_size
pub fn trimprop(&mut self, name: &CStr, new_size: usize) -> Result<()> {
let (prop, len) =
diff --git a/pvmfw/avb/src/descriptor.rs b/pvmfw/avb/src/descriptor.rs
deleted file mode 100644
index cd623ac..0000000
--- a/pvmfw/avb/src/descriptor.rs
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2023, The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//! Structs and functions relating to the descriptors.
-
-use crate::error::{AvbIOError, AvbSlotVerifyError};
-use crate::partition::PartitionName;
-use crate::utils::{self, is_not_null, to_nonnull, to_usize, usize_checked_add};
-use avb_bindgen::{
- avb_descriptor_foreach, avb_hash_descriptor_validate_and_byteswap, AvbDescriptor,
- AvbHashDescriptor, AvbVBMetaData, AVB_SHA256_DIGEST_SIZE,
-};
-use core::{
- ffi::c_void,
- mem::{size_of, MaybeUninit},
- ops::Range,
- slice,
-};
-use tinyvec::ArrayVec;
-
-/// Digest type for kernel and initrd.
-pub type Digest = [u8; AVB_SHA256_DIGEST_SIZE as usize];
-
-/// `HashDescriptors` can have maximum one `HashDescriptor` per known partition.
-#[derive(Default)]
-pub(crate) struct HashDescriptors(
- ArrayVec<[HashDescriptor; PartitionName::NUM_OF_KNOWN_PARTITIONS]>,
-);
-
-impl HashDescriptors {
- /// Builds `HashDescriptors` from `AvbVBMetaData`.
- /// Returns an error if the given `AvbVBMetaData` contains non-hash descriptor, hash
- /// descriptor of unknown `PartitionName` or duplicated hash descriptors.
- ///
- /// # Safety
- ///
- /// Behavior is undefined if any of the following conditions are violated:
- /// * `vbmeta.vbmeta_data` must be non-null and points to a valid VBMeta.
- /// * `vbmeta.vbmeta_data` must be valid for reading `vbmeta.vbmeta_size` bytes.
- pub(crate) unsafe fn from_vbmeta(vbmeta: AvbVBMetaData) -> Result<Self, AvbSlotVerifyError> {
- is_not_null(vbmeta.vbmeta_data).map_err(|_| AvbSlotVerifyError::Io)?;
- let mut descriptors = Self::default();
- // SAFETY: It is safe as the raw pointer `vbmeta.vbmeta_data` is a non-null pointer and
- // points to a valid VBMeta structure.
- if !unsafe {
- avb_descriptor_foreach(
- vbmeta.vbmeta_data,
- vbmeta.vbmeta_size,
- Some(check_and_save_descriptor),
- &mut descriptors as *mut _ as *mut c_void,
- )
- } {
- return Err(AvbSlotVerifyError::InvalidMetadata);
- }
- Ok(descriptors)
- }
-
- fn push(&mut self, descriptor: HashDescriptor) -> utils::Result<()> {
- if self.0.iter().any(|d| d.partition_name_eq(&descriptor)) {
- return Err(AvbIOError::Io);
- }
- self.0.push(descriptor);
- Ok(())
- }
-
- pub(crate) fn len(&self) -> usize {
- self.0.len()
- }
-
- /// Finds the `HashDescriptor` for the given `PartitionName`.
- /// Throws an error if no corresponding descriptor found.
- pub(crate) fn find(
- &self,
- partition_name: PartitionName,
- ) -> Result<&HashDescriptor, AvbSlotVerifyError> {
- self.0
- .iter()
- .find(|d| d.partition_name == partition_name)
- .ok_or(AvbSlotVerifyError::InvalidMetadata)
- }
-}
-
-/// # Safety
-///
-/// Behavior is undefined if any of the following conditions are violated:
-/// * The `descriptor` pointer must be non-null and points to a valid `AvbDescriptor` struct.
-/// * The `user_data` pointer must be non-null and points to a valid `HashDescriptors` struct.
-unsafe extern "C" fn check_and_save_descriptor(
- descriptor: *const AvbDescriptor,
- user_data: *mut c_void,
-) -> bool {
- // SAFETY: It is safe because the caller must ensure that the `descriptor` pointer and
- // the `user_data` are non-null and valid.
- unsafe { try_check_and_save_descriptor(descriptor, user_data).is_ok() }
-}
-
-/// # Safety
-///
-/// Behavior is undefined if any of the following conditions are violated:
-/// * The `descriptor` pointer must be non-null and points to a valid `AvbDescriptor` struct.
-/// * The `user_data` pointer must be non-null and points to a valid `HashDescriptors` struct.
-unsafe fn try_check_and_save_descriptor(
- descriptor: *const AvbDescriptor,
- user_data: *mut c_void,
-) -> utils::Result<()> {
- is_not_null(descriptor)?;
- // SAFETY: It is safe because the caller ensures that `descriptor` is a non-null pointer
- // pointing to a valid struct.
- let desc = unsafe { AvbHashDescriptorWrap::from_descriptor_ptr(descriptor)? };
- // SAFETY: It is safe because the caller ensures that `descriptor` is a non-null pointer
- // pointing to a valid struct.
- let data = unsafe { slice::from_raw_parts(descriptor as *const u8, desc.len()?) };
- let mut descriptors = to_nonnull(user_data as *mut HashDescriptors)?;
- // SAFETY: It is safe because the caller ensures that `user_data` is a non-null pointer
- // pointing to a valid struct.
- let descriptors = unsafe { descriptors.as_mut() };
- descriptors.push(HashDescriptor::new(&desc, data)?)
-}
-
-#[derive(Default)]
-pub(crate) struct HashDescriptor {
- partition_name: PartitionName,
- pub(crate) digest: Digest,
-}
-
-impl HashDescriptor {
- fn new(desc: &AvbHashDescriptorWrap, data: &[u8]) -> utils::Result<Self> {
- let partition_name = data
- .get(desc.partition_name_range()?)
- .ok_or(AvbIOError::RangeOutsidePartition)?
- .try_into()?;
- let partition_digest =
- data.get(desc.digest_range()?).ok_or(AvbIOError::RangeOutsidePartition)?;
- let mut digest = [0u8; size_of::<Digest>()];
- digest.copy_from_slice(partition_digest);
- Ok(Self { partition_name, digest })
- }
-
- fn partition_name_eq(&self, other: &HashDescriptor) -> bool {
- self.partition_name == other.partition_name
- }
-}
-
-/// `AvbHashDescriptor` contains the metadata for the given descriptor.
-struct AvbHashDescriptorWrap(AvbHashDescriptor);
-
-impl AvbHashDescriptorWrap {
- /// # Safety
- ///
- /// Behavior is undefined if any of the following conditions are violated:
- /// * The `descriptor` pointer must be non-null and point to a valid `AvbDescriptor`.
- unsafe fn from_descriptor_ptr(descriptor: *const AvbDescriptor) -> utils::Result<Self> {
- is_not_null(descriptor)?;
- // SAFETY: It is safe as the raw pointer `descriptor` is non-null and points to
- // a valid `AvbDescriptor`.
- let desc = unsafe {
- let mut desc = MaybeUninit::uninit();
- if !avb_hash_descriptor_validate_and_byteswap(
- descriptor as *const AvbHashDescriptor,
- desc.as_mut_ptr(),
- ) {
- return Err(AvbIOError::Io);
- }
- desc.assume_init()
- };
- Ok(Self(desc))
- }
-
- fn len(&self) -> utils::Result<usize> {
- usize_checked_add(
- size_of::<AvbDescriptor>(),
- to_usize(self.0.parent_descriptor.num_bytes_following)?,
- )
- }
-
- fn partition_name_end(&self) -> utils::Result<usize> {
- usize_checked_add(size_of::<AvbHashDescriptor>(), to_usize(self.0.partition_name_len)?)
- }
-
- fn partition_name_range(&self) -> utils::Result<Range<usize>> {
- let start = size_of::<AvbHashDescriptor>();
- Ok(start..(self.partition_name_end()?))
- }
-
- fn digest_range(&self) -> utils::Result<Range<usize>> {
- let start = usize_checked_add(self.partition_name_end()?, to_usize(self.0.salt_len)?)?;
- let end = usize_checked_add(start, to_usize(self.0.digest_len)?)?;
- Ok(start..end)
- }
-}
diff --git a/pvmfw/avb/src/descriptor/descriptors.rs b/pvmfw/avb/src/descriptor/descriptors.rs
new file mode 100644
index 0000000..6eaf643
--- /dev/null
+++ b/pvmfw/avb/src/descriptor/descriptors.rs
@@ -0,0 +1,148 @@
+// Copyright 2023, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Structs and functions relating to the descriptor data.
+
+use crate::error::AvbIOError;
+use crate::partition::PartitionName;
+use crate::utils::{self, is_not_null, to_usize, usize_checked_add};
+use crate::Digest;
+use avb_bindgen::{
+ avb_descriptor_validate_and_byteswap, avb_hash_descriptor_validate_and_byteswap, AvbDescriptor,
+ AvbDescriptorTag, AvbHashDescriptor,
+};
+use core::{
+ mem::{size_of, MaybeUninit},
+ ops::Range,
+ slice,
+};
+
+pub(super) enum Descriptor<'a> {
+ Hash(HashDescriptor<'a>),
+}
+
+impl<'a> Descriptor<'a> {
+ /// # Safety
+ ///
+ /// Behavior is undefined if any of the following conditions are violated:
+ /// * The `descriptor` pointer must be non-null and point to a valid `AvbDescriptor`.
+ pub(super) unsafe fn from_descriptor_ptr(
+ descriptor: *const AvbDescriptor,
+ ) -> utils::Result<Self> {
+ // SAFETY: It is safe as the raw pointer `descriptor` is non-null and points to
+ // a valid `AvbDescriptor`.
+ let avb_descriptor =
+ unsafe { get_valid_descriptor(descriptor, avb_descriptor_validate_and_byteswap)? };
+ let len = usize_checked_add(
+ size_of::<AvbDescriptor>(),
+ to_usize(avb_descriptor.num_bytes_following)?,
+ )?;
+ // SAFETY: It is safe because the caller ensures that `descriptor` is a non-null pointer
+ // pointing to a valid struct.
+ let data = unsafe { slice::from_raw_parts(descriptor as *const u8, len) };
+ match avb_descriptor.tag.try_into() {
+ Ok(AvbDescriptorTag::AVB_DESCRIPTOR_TAG_HASH) => {
+ // SAFETY: It is safe because the caller ensures that `descriptor` is a non-null
+ // pointer pointing to a valid struct.
+ let h = unsafe { HashDescriptorHeader::from_descriptor_ptr(descriptor)? };
+ Ok(Self::Hash(HashDescriptor::new(&h, data)?))
+ }
+ _ => Err(AvbIOError::NoSuchValue),
+ }
+ }
+}
+
+struct HashDescriptorHeader(AvbHashDescriptor);
+
+impl HashDescriptorHeader {
+ /// # Safety
+ ///
+ /// Behavior is undefined if any of the following conditions are violated:
+ /// * The `descriptor` pointer must be non-null and point to a valid `AvbDescriptor`.
+ unsafe fn from_descriptor_ptr(descriptor: *const AvbDescriptor) -> utils::Result<Self> {
+ // SAFETY: It is safe as the raw pointer `descriptor` is non-null and points to
+ // a valid `AvbDescriptor`.
+ unsafe {
+ get_valid_descriptor(
+ descriptor as *const AvbHashDescriptor,
+ avb_hash_descriptor_validate_and_byteswap,
+ )
+ .map(Self)
+ }
+ }
+
+ fn partition_name_end(&self) -> utils::Result<usize> {
+ usize_checked_add(size_of::<AvbHashDescriptor>(), to_usize(self.0.partition_name_len)?)
+ }
+
+ fn partition_name_range(&self) -> utils::Result<Range<usize>> {
+ let start = size_of::<AvbHashDescriptor>();
+ Ok(start..(self.partition_name_end()?))
+ }
+
+ fn digest_range(&self) -> utils::Result<Range<usize>> {
+ let start = usize_checked_add(self.partition_name_end()?, to_usize(self.0.salt_len)?)?;
+ let end = usize_checked_add(start, to_usize(self.0.digest_len)?)?;
+ Ok(start..end)
+ }
+}
+
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+/// * The `descriptor_ptr` pointer must be non-null and point to a valid `AvbDescriptor`.
+unsafe fn get_valid_descriptor<T>(
+ descriptor_ptr: *const T,
+ descriptor_validate_and_byteswap: unsafe extern "C" fn(src: *const T, dest: *mut T) -> bool,
+) -> utils::Result<T> {
+ is_not_null(descriptor_ptr)?;
+ // SAFETY: It is safe because the caller ensures that `descriptor_ptr` is a non-null pointer
+ // pointing to a valid struct.
+ let descriptor = unsafe {
+ let mut desc = MaybeUninit::uninit();
+ if !descriptor_validate_and_byteswap(descriptor_ptr, desc.as_mut_ptr()) {
+ return Err(AvbIOError::Io);
+ }
+ desc.assume_init()
+ };
+ Ok(descriptor)
+}
+
+pub(crate) struct HashDescriptor<'a> {
+ pub(crate) partition_name: PartitionName,
+ pub(crate) digest: &'a Digest,
+}
+
+impl<'a> Default for HashDescriptor<'a> {
+ fn default() -> Self {
+ Self { partition_name: Default::default(), digest: &Self::EMPTY_DIGEST }
+ }
+}
+
+impl<'a> HashDescriptor<'a> {
+ const EMPTY_DIGEST: Digest = [0u8; 32];
+
+ fn new(desc: &HashDescriptorHeader, data: &'a [u8]) -> utils::Result<Self> {
+ let partition_name = data
+ .get(desc.partition_name_range()?)
+ .ok_or(AvbIOError::RangeOutsidePartition)?
+ .try_into()?;
+ let digest = data
+ .get(desc.digest_range()?)
+ .ok_or(AvbIOError::RangeOutsidePartition)?
+ .try_into()
+ .map_err(|_| AvbIOError::InvalidValueSize)?;
+ Ok(Self { partition_name, digest })
+ }
+}
diff --git a/pvmfw/avb/src/descriptor/mod.rs b/pvmfw/avb/src/descriptor/mod.rs
new file mode 100644
index 0000000..3c169bf
--- /dev/null
+++ b/pvmfw/avb/src/descriptor/mod.rs
@@ -0,0 +1,129 @@
+// Copyright 2023, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Structs and functions relating to the descriptors.
+
+mod descriptors;
+
+pub(crate) use self::descriptors::HashDescriptor;
+
+use self::descriptors::Descriptor;
+use crate::error::{AvbIOError, AvbSlotVerifyError};
+use crate::partition::PartitionName;
+use crate::utils::{self, is_not_null, to_nonnull};
+use avb_bindgen::{avb_descriptor_foreach, AvbDescriptor, AvbVBMetaData, AVB_SHA256_DIGEST_SIZE};
+use core::ffi::c_void;
+use tinyvec::ArrayVec;
+
+/// Digest type for kernel and initrd.
+pub type Digest = [u8; AVB_SHA256_DIGEST_SIZE as usize];
+
+/// `Descriptors` can have at most one `HashDescriptor` per known partition and at most one
+/// `PropertyDescriptor`.
+#[derive(Default)]
+pub(crate) struct Descriptors<'a> {
+ hash_descriptors: ArrayVec<[HashDescriptor<'a>; PartitionName::NUM_OF_KNOWN_PARTITIONS]>,
+}
+
+impl<'a> Descriptors<'a> {
+ /// Builds `Descriptors` from `AvbVBMetaData`.
+ /// Returns an error if the given `AvbVBMetaData` contains non-hash descriptor, hash
+ /// descriptor of unknown `PartitionName` or duplicated hash descriptors.
+ ///
+ /// # Safety
+ ///
+ /// Behavior is undefined if any of the following conditions are violated:
+ /// * `vbmeta.vbmeta_data` must be non-null and points to a valid VBMeta.
+ /// * `vbmeta.vbmeta_data` must be valid for reading `vbmeta.vbmeta_size` bytes.
+ pub(crate) unsafe fn from_vbmeta(vbmeta: AvbVBMetaData) -> Result<Self, AvbSlotVerifyError> {
+ is_not_null(vbmeta.vbmeta_data).map_err(|_| AvbSlotVerifyError::Io)?;
+ let mut descriptors = Self::default();
+ // SAFETY: It is safe as the raw pointer `vbmeta.vbmeta_data` is a non-null pointer and
+ // points to a valid VBMeta structure.
+ if !unsafe {
+ avb_descriptor_foreach(
+ vbmeta.vbmeta_data,
+ vbmeta.vbmeta_size,
+ Some(check_and_save_descriptor),
+ &mut descriptors as *mut _ as *mut c_void,
+ )
+ } {
+ return Err(AvbSlotVerifyError::InvalidMetadata);
+ }
+ Ok(descriptors)
+ }
+
+ pub(crate) fn num_hash_descriptor(&self) -> usize {
+ self.hash_descriptors.len()
+ }
+
+ /// Finds the `HashDescriptor` for the given `PartitionName`.
+ /// Throws an error if no corresponding descriptor found.
+ pub(crate) fn find_hash_descriptor(
+ &self,
+ partition_name: PartitionName,
+ ) -> Result<&HashDescriptor, AvbSlotVerifyError> {
+ self.hash_descriptors
+ .iter()
+ .find(|d| d.partition_name == partition_name)
+ .ok_or(AvbSlotVerifyError::InvalidMetadata)
+ }
+
+ fn push(&mut self, descriptor: Descriptor<'a>) -> utils::Result<()> {
+ match descriptor {
+ Descriptor::Hash(d) => self.push_hash_descriptor(d),
+ }
+ }
+
+ fn push_hash_descriptor(&mut self, descriptor: HashDescriptor<'a>) -> utils::Result<()> {
+ if self.hash_descriptors.iter().any(|d| d.partition_name == descriptor.partition_name) {
+ return Err(AvbIOError::Io);
+ }
+ self.hash_descriptors.push(descriptor);
+ Ok(())
+ }
+}
+
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+/// * The `descriptor` pointer must be non-null and points to a valid `AvbDescriptor` struct.
+/// * The `user_data` pointer must be non-null and points to a valid `Descriptors` struct.
+unsafe extern "C" fn check_and_save_descriptor(
+ descriptor: *const AvbDescriptor,
+ user_data: *mut c_void,
+) -> bool {
+ // SAFETY: It is safe because the caller must ensure that the `descriptor` pointer and
+ // the `user_data` are non-null and valid.
+ unsafe { try_check_and_save_descriptor(descriptor, user_data).is_ok() }
+}
+
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+/// * The `descriptor` pointer must be non-null and points to a valid `AvbDescriptor` struct.
+/// * The `user_data` pointer must be non-null and points to a valid `Descriptors` struct.
+unsafe fn try_check_and_save_descriptor(
+ descriptor: *const AvbDescriptor,
+ user_data: *mut c_void,
+) -> utils::Result<()> {
+ let mut descriptors = to_nonnull(user_data as *mut Descriptors)?;
+ // SAFETY: It is safe because the caller ensures that `user_data` is a non-null pointer
+ // pointing to a valid struct.
+ let descriptors = unsafe { descriptors.as_mut() };
+ // SAFETY: It is safe because the caller ensures that `descriptor` is a non-null pointer
+ // pointing to a valid struct.
+ let descriptor = unsafe { Descriptor::from_descriptor_ptr(descriptor)? };
+ descriptors.push(descriptor)
+}
diff --git a/pvmfw/avb/src/error.rs b/pvmfw/avb/src/error.rs
index 674e5a7..c2b7428 100644
--- a/pvmfw/avb/src/error.rs
+++ b/pvmfw/avb/src/error.rs
@@ -93,7 +93,6 @@
#[allow(dead_code)]
Oom,
/// AVB_IO_RESULT_ERROR_IO,
- #[allow(dead_code)]
Io,
/// AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION,
NoSuchPartition,
diff --git a/pvmfw/avb/src/verify.rs b/pvmfw/avb/src/verify.rs
index b03506c..ded0766 100644
--- a/pvmfw/avb/src/verify.rs
+++ b/pvmfw/avb/src/verify.rs
@@ -14,7 +14,7 @@
//! This module handles the pvmfw payload verification.
-use crate::descriptor::{Digest, HashDescriptors};
+use crate::descriptor::{Descriptors, Digest};
use crate::error::AvbSlotVerifyError;
use crate::ops::{Ops, Payload};
use crate::partition::PartitionName;
@@ -63,9 +63,9 @@
}
fn verify_vbmeta_has_only_one_hash_descriptor(
- hash_descriptors: &HashDescriptors,
+ descriptors: &Descriptors,
) -> Result<(), AvbSlotVerifyError> {
- if hash_descriptors.len() == 1 {
+ if descriptors.num_hash_descriptor() == 1 {
Ok(())
} else {
Err(AvbSlotVerifyError::InvalidMetadata)
@@ -112,14 +112,14 @@
// SAFETY: It is safe because the `vbmeta_image` is collected from `AvbSlotVerifyData`,
// which is returned by `avb_slot_verify()` when the verification succeeds. It is
// guaranteed by libavb to be non-null and to point to a valid VBMeta structure.
- let hash_descriptors = unsafe { HashDescriptors::from_vbmeta(vbmeta_image)? };
- let kernel_descriptor = hash_descriptors.find(PartitionName::Kernel)?;
+ let descriptors = unsafe { Descriptors::from_vbmeta(vbmeta_image)? };
+ let kernel_descriptor = descriptors.find_hash_descriptor(PartitionName::Kernel)?;
if initrd.is_none() {
- verify_vbmeta_has_only_one_hash_descriptor(&hash_descriptors)?;
+ verify_vbmeta_has_only_one_hash_descriptor(&descriptors)?;
return Ok(VerifiedBootData {
debug_level: DebugLevel::None,
- kernel_digest: kernel_descriptor.digest,
+ kernel_digest: *kernel_descriptor.digest,
initrd_digest: None,
public_key: trusted_public_key,
});
@@ -140,11 +140,11 @@
initrd_partition_name,
initrd.len(),
)?;
- let initrd_descriptor = hash_descriptors.find(initrd_partition_name)?;
+ let initrd_descriptor = descriptors.find_hash_descriptor(initrd_partition_name)?;
Ok(VerifiedBootData {
debug_level,
- kernel_digest: kernel_descriptor.digest,
- initrd_digest: Some(initrd_descriptor.digest),
+ kernel_digest: *kernel_descriptor.digest,
+ initrd_digest: Some(*initrd_descriptor.digest),
public_key: trusted_public_key,
})
}
diff --git a/pvmfw/platform.dts b/pvmfw/platform.dts
index a7b1de7..74439d9 100644
--- a/pvmfw/platform.dts
+++ b/pvmfw/platform.dts
@@ -37,6 +37,7 @@
ranges;
swiotlb: restricted_dma_reserved {
compatible = "restricted-dma-pool";
+ reg = <PLACEHOLDER4>;
size = <PLACEHOLDER2>;
alignment = <PLACEHOLDER2>;
};
diff --git a/pvmfw/src/fdt.rs b/pvmfw/src/fdt.rs
index 98802b4..c0241ca 100644
--- a/pvmfw/src/fdt.rs
+++ b/pvmfw/src/fdt.rs
@@ -440,7 +440,7 @@
pub struct SwiotlbInfo {
addr: Option<usize>,
size: usize,
- align: usize,
+ align: Option<usize>,
}
impl SwiotlbInfo {
@@ -452,17 +452,16 @@
fn read_swiotlb_info_from(fdt: &Fdt) -> libfdt::Result<SwiotlbInfo> {
let node =
fdt.compatible_nodes(cstr!("restricted-dma-pool"))?.next().ok_or(FdtError::NotFound)?;
- let align =
- node.getprop_u64(cstr!("alignment"))?.ok_or(FdtError::NotFound)?.try_into().unwrap();
- let (addr, size) = if let Some(mut reg) = node.reg()? {
+ let (addr, size, align) = if let Some(mut reg) = node.reg()? {
let reg = reg.next().ok_or(FdtError::NotFound)?;
let size = reg.size.ok_or(FdtError::NotFound)?;
reg.addr.checked_add(size).ok_or(FdtError::BadValue)?;
- (Some(reg.addr.try_into().unwrap()), size.try_into().unwrap())
+ (Some(reg.addr.try_into().unwrap()), size.try_into().unwrap(), None)
} else {
- let size = node.getprop_u64(cstr!("size"))?.ok_or(FdtError::NotFound)?.try_into().unwrap();
- (None, size)
+ let size = node.getprop_u64(cstr!("size"))?.ok_or(FdtError::NotFound)?;
+ let align = node.getprop_u64(cstr!("alignment"))?.ok_or(FdtError::NotFound)?;
+ (None, size.try_into().unwrap(), Some(align.try_into().unwrap()))
};
Ok(SwiotlbInfo { addr, size, align })
@@ -480,7 +479,7 @@
return Err(RebootReason::InvalidFdt);
}
- if (align % GUEST_PAGE_SIZE) != 0 {
+ if let Some(align) = align.filter(|&a| a % GUEST_PAGE_SIZE != 0) {
error!("Invalid swiotlb alignment {:#x}", align);
return Err(RebootReason::InvalidFdt);
}
@@ -498,16 +497,19 @@
fn patch_swiotlb_info(fdt: &mut Fdt, swiotlb_info: &SwiotlbInfo) -> libfdt::Result<()> {
let mut node =
fdt.root_mut()?.next_compatible(cstr!("restricted-dma-pool"))?.ok_or(FdtError::NotFound)?;
- node.setprop_inplace(cstr!("alignment"), &swiotlb_info.align.to_be_bytes())?;
if let Some(range) = swiotlb_info.fixed_range() {
- node.appendprop_addrrange(
+ node.setprop_addrrange_inplace(
cstr!("reg"),
range.start.try_into().unwrap(),
range.len().try_into().unwrap(),
)?;
+ node.nop_property(cstr!("size"))?;
+ node.nop_property(cstr!("alignment"))?;
} else {
+ node.nop_property(cstr!("reg"))?;
node.setprop_inplace(cstr!("size"), &swiotlb_info.size.to_be_bytes())?;
+ node.setprop_inplace(cstr!("alignment"), &swiotlb_info.align.unwrap().to_be_bytes())?;
}
Ok(())