pvmfw: Move DT sanitization to main()
Move it so that it can re-use other inputs e.g. VBMeta capabilities.
This should not compromise the integrity of pvmfw as it still happens
before the DT is used to initialize the PCI bus and swiotlb region.
Move the shared memory setup to main(), so that it only happens when
actually needed i.e. when the instance.img is used, requiring a shared
region for the VirtIO transport.
Bug: 339782511
Bug: 377276983
Test: m pvmfw_bin
Change-Id: I6de6e4607d110c2f8fffd9a3d9527716dca92565
diff --git a/guest/pvmfw/src/main.rs b/guest/pvmfw/src/main.rs
index bde03ff..9f9614a 100644
--- a/guest/pvmfw/src/main.rs
+++ b/guest/pvmfw/src/main.rs
@@ -35,7 +35,7 @@
use crate::bcc::Bcc;
use crate::dice::PartialInputs;
use crate::entry::RebootReason;
-use crate::fdt::modify_for_next_stage;
+use crate::fdt::{modify_for_next_stage, sanitize_device_tree};
use crate::helpers::GUEST_PAGE_SIZE;
use crate::instance::EntryBody;
use crate::instance::Error as InstanceError;
@@ -54,21 +54,23 @@
use pvmfw_embedded_key::PUBLIC_KEY;
use vmbase::fdt::pci::{PciError, PciInfo};
use vmbase::heap;
-use vmbase::memory::flush;
+use vmbase::memory::{flush, init_shared_pool};
use vmbase::rand;
use vmbase::virtio::pci;
const NEXT_BCC_SIZE: usize = GUEST_PAGE_SIZE;
fn main(
- fdt: &mut Fdt,
+ untrusted_fdt: &mut Fdt,
signed_kernel: &[u8],
ramdisk: Option<&[u8]>,
current_bcc_handover: &[u8],
mut debug_policy: Option<&[u8]>,
+ vm_dtbo: Option<&mut [u8]>,
+ vm_ref_dt: Option<&[u8]>,
) -> Result<(Range<usize>, bool), RebootReason> {
info!("pVM firmware");
- debug!("FDT: {:?}", fdt.as_ptr());
+ debug!("FDT: {:?}", untrusted_fdt.as_ptr());
debug!("Signed kernel: {:?} ({:#x} bytes)", signed_kernel.as_ptr(), signed_kernel.len());
debug!("AVB public key: addr={:?}, size={:#x} ({1})", PUBLIC_KEY.as_ptr(), PUBLIC_KEY.len());
if let Some(rd) = ramdisk {
@@ -97,14 +99,6 @@
debug_policy = None;
}
- // Set up PCI bus for VirtIO devices.
- let pci_info = PciInfo::from_fdt(fdt).map_err(handle_pci_error)?;
- debug!("PCI: {:#x?}", pci_info);
- let mut pci_root = pci::initialize(pci_info).map_err(|e| {
- error!("Failed to initialize PCI: {e}");
- RebootReason::InternalError
- })?;
-
let verified_boot_data = verify_payload(signed_kernel, ramdisk, PUBLIC_KEY).map_err(|e| {
error!("Failed to verify the payload: {e}");
RebootReason::PayloadVerificationError
@@ -115,6 +109,20 @@
info!("Please disregard any previous libavb ERROR about initrd_normal.");
}
+ let fdt_info = sanitize_device_tree(untrusted_fdt, vm_dtbo, vm_ref_dt)?;
+ let fdt = untrusted_fdt; // DT has now been sanitized.
+ let pci_info = PciInfo::from_fdt(fdt).map_err(handle_pci_error)?;
+ debug!("PCI: {:#x?}", pci_info);
+ // Set up PCI bus for VirtIO devices.
+ let mut pci_root = pci::initialize(pci_info).map_err(|e| {
+ error!("Failed to initialize PCI: {e}");
+ RebootReason::InternalError
+ })?;
+ init_shared_pool(fdt_info.swiotlb_info.fixed_range()).map_err(|e| {
+ error!("Failed to initialize shared pool: {e}");
+ RebootReason::InternalError
+ })?;
+
let next_bcc = heap::aligned_boxed_slice(NEXT_BCC_SIZE, GUEST_PAGE_SIZE).ok_or_else(|| {
error!("Failed to allocate the next-stage BCC");
RebootReason::InternalError