pvmfw: Apply VM DTBO
This CL only applies assigned VM DTBO for the simplest case, which
iommu, phandle, nor aliases aren't involved.
Next CLs will handle following cases:
- Apply iommu. Platform DT will be also updated to have pre-populated
pvmiommu node
- Validate patched values (reg, iommu, ..)
- Handle __local_fixup__, __fixups__ (i.e. handle phandle in VM DTBO)
- Handle /alias in VM DTBO
- ...
Bug: 277993056
Test: atest libpvmfw.device_assignment.test, launch protected VM
Change-Id: I4e4aea0885da925ae419921d729380a1d71707e0
diff --git a/pvmfw/src/entry.rs b/pvmfw/src/entry.rs
index 9c929a9..ed73bc9 100644
--- a/pvmfw/src/entry.rs
+++ b/pvmfw/src/entry.rs
@@ -83,7 +83,12 @@
}
impl<'a> MemorySlices<'a> {
- fn new(fdt: usize, kernel: usize, kernel_size: usize) -> Result<Self, RebootReason> {
+ fn new(
+ fdt: usize,
+ kernel: usize,
+ kernel_size: usize,
+ vm_dtbo: Option<&mut [u8]>,
+ ) -> Result<Self, RebootReason> {
let fdt_size = NonZeroUsize::new(crosvm::FDT_MAX_SIZE).unwrap();
// TODO - Only map the FDT as read-only, until we modify it right before jump_to_payload()
// e.g. by generating a DTBO for a template DT in main() and, on return, re-map DT as RW,
@@ -95,12 +100,12 @@
// SAFETY: The tracker validated the range to be in main memory, mapped, and not overlap.
let fdt = unsafe { slice::from_raw_parts_mut(range.start as *mut u8, range.len()) };
+
+ let info = fdt::sanitize_device_tree(fdt, vm_dtbo)?;
let fdt = libfdt::Fdt::from_mut_slice(fdt).map_err(|e| {
- error!("Failed to spawn the FDT wrapper: {e}");
+ error!("Failed to load sanitized FDT: {e}");
RebootReason::InvalidFdt
})?;
-
- let info = fdt::sanitize_device_tree(fdt)?;
debug!("Fdt passed validation!");
let memory_range = info.memory_range;
@@ -207,7 +212,7 @@
RebootReason::InvalidConfig
})?;
- let (bcc_slice, debug_policy) = appended.get_entries();
+ let (bcc_slice, debug_policy, vm_dtbo) = appended.get_entries();
// Up to this point, we were using the built-in static (from .rodata) page tables.
MEMORY.lock().replace(MemoryTracker::new(
@@ -217,7 +222,7 @@
Some(memory::appended_payload_range()),
));
- let slices = MemorySlices::new(fdt, payload, payload_size)?;
+ let slices = MemorySlices::new(fdt, payload, payload_size, vm_dtbo)?;
// This wrapper allows main() to be blissfully ignorant of platform details.
let next_bcc = crate::main(slices.fdt, slices.kernel, slices.ramdisk, bcc_slice, debug_policy)?;
@@ -427,10 +432,10 @@
}
}
- fn get_entries(&mut self) -> (&mut [u8], Option<&mut [u8]>) {
+ fn get_entries(&mut self) -> (&mut [u8], Option<&mut [u8]>, Option<&mut [u8]>) {
match self {
Self::Config(ref mut cfg) => cfg.get_entries(),
- Self::LegacyBcc(ref mut bcc) => (bcc, None),
+ Self::LegacyBcc(ref mut bcc) => (bcc, None, None),
}
}
}