Merge "pvmfw: Add exception handling infrastructure"
diff --git a/pvmfw/README.md b/pvmfw/README.md
index 4e93648..1eb7286 100644
--- a/pvmfw/README.md
+++ b/pvmfw/README.md
@@ -197,16 +197,20 @@
that it differs from the `BccHandover` defined by the specification in that its
`Bcc` field is mandatory (while optional in the original).
-Devices that fully implement DICE should provide a certificate rooted at the
-Unique Device Secret (UDS) in a boot stage preceding the pvmfw loader (typically
-ABL), in such a way that it would receive a valid `BccHandover`, that can be
-passed to [`BccHandoverMainFlow`][BccHandoverMainFlow] along with the inputs
-described below.
+Ideally devices that fully implement DICE should provide a certificate rooted at
+the Unique Device Secret (UDS) in a boot stage preceding the pvmfw loader
+(typically ABL), in such a way that it would receive a valid `BccHandover`, that
+can be passed to [`BccHandoverMainFlow`][BccHandoverMainFlow] along with the
+inputs described below.
-Otherwise, as an intermediate step towards supporting DICE throughout the
-software stack of the device, incomplete implementations may root the BCC at the
-pvmfw loader, using an arbitrary constant as initial CDI. The pvmfw loader can
-easily do so by:
+However, there is a limitation in Android 14 that means that a UDS-rooted DICE
+chain must not be used for pvmfw. A non-UDS rooted DICE chain is recommended for
+Android 14.
+
+As an intermediate step towards supporting DICE throughout the software stack of
+the device, incomplete implementations may root the BCC at the pvmfw loader,
+using an arbitrary constant as initial CDI. The pvmfw loader can easily do so
+by:
1. Building a BCC-less `BccHandover` using CBOR operations
([example][Trusty-BCC]) and containing the constant CDIs
diff --git a/pvmfw/src/helpers.rs b/pvmfw/src/helpers.rs
index 9c739d1..8c05217 100644
--- a/pvmfw/src/helpers.rs
+++ b/pvmfw/src/helpers.rs
@@ -19,6 +19,7 @@
pub const SIZE_4KB: usize = 4 << 10;
pub const SIZE_2MB: usize = 2 << 20;
+pub const SIZE_4MB: usize = 4 << 20;
pub const GUEST_PAGE_SIZE: usize = SIZE_4KB;
diff --git a/pvmfw/src/memory.rs b/pvmfw/src/memory.rs
index d90808b..7df25f2 100644
--- a/pvmfw/src/memory.rs
+++ b/pvmfw/src/memory.rs
@@ -16,7 +16,7 @@
#![deny(unsafe_op_in_unsafe_fn)]
-use crate::helpers::{self, align_down, align_up, page_4kb_of, SIZE_4KB};
+use crate::helpers::{self, align_down, align_up, page_4kb_of, SIZE_4KB, SIZE_4MB};
use crate::mmu;
use alloc::alloc::alloc_zeroed;
use alloc::alloc::dealloc;
@@ -136,6 +136,7 @@
impl MemoryTracker {
const CAPACITY: usize = 5;
const MMIO_CAPACITY: usize = 5;
+ const PVMFW_RANGE: MemoryRange = (BASE_ADDR - SIZE_4MB)..BASE_ADDR;
/// Create a new instance from an active page table, covering the maximum RAM size.
pub fn new(page_table: mmu::PageTable) -> Self {
@@ -201,7 +202,7 @@
/// appropriately.
pub fn map_mmio_range(&mut self, range: MemoryRange) -> Result<()> {
// MMIO space is below the main memory region.
- if range.end > self.total.start {
+ if range.end > self.total.start || overlaps(&Self::PVMFW_RANGE, &range) {
return Err(MemoryTrackerError::OutOfRange);
}
if self.mmio_regions.iter().any(|r| overlaps(r, &range)) {