vmbase: Support missing SwiotlbInfo DT node
Stop failing with an Err() when SwiotlbInfo::new_from_fdt() is called on
DTs missing the "restricted-dma-pool" (e.g. in non-protected VMs) and
instead return Ok(None), which the caller can handle appropriately.
While here, use the proper error code (BadValue) when a <reg> property
is present but empty or is missing a size.
Bug: 377276983
Test: m {pvmfw,rialto,vmbase_example_{bios,kernel}}_bin
Test: atest rialto_test vmbase_example.integration_test
Change-Id: I58179318d34c33c20e6333f02b066574d0fb47a5
diff --git a/guest/pvmfw/src/fdt.rs b/guest/pvmfw/src/fdt.rs
index 6bbb05e..027f163 100644
--- a/guest/pvmfw/src/fdt.rs
+++ b/guest/pvmfw/src/fdt.rs
@@ -1140,10 +1140,15 @@
RebootReason::InvalidFdt
})?;
- let swiotlb_info = SwiotlbInfo::new_from_fdt(fdt).map_err(|e| {
- error!("Failed to read swiotlb info from DT: {e}");
- RebootReason::InvalidFdt
- })?;
+ let swiotlb_info = SwiotlbInfo::new_from_fdt(fdt)
+ .map_err(|e| {
+ error!("Failed to read swiotlb info from DT: {e}");
+ RebootReason::InvalidFdt
+ })?
+ .ok_or_else(|| {
+ error!("Swiotlb info missing from DT");
+ RebootReason::InvalidFdt
+ })?;
validate_swiotlb_info(&swiotlb_info, &memory_range)?;
let device_assignment = match vm_dtbo {
diff --git a/guest/rialto/src/main.rs b/guest/rialto/src/main.rs
index 0b79e1e..ec26e0f 100644
--- a/guest/rialto/src/main.rs
+++ b/guest/rialto/src/main.rs
@@ -117,7 +117,7 @@
MEMORY.lock().as_mut().unwrap().init_dynamic_shared_pool(granule).inspect_err(|_| {
error!("Failed to initialize dynamically shared pool.");
})?;
- } else if let Ok(swiotlb_info) = SwiotlbInfo::new_from_fdt(fdt) {
+ } else if let Ok(Some(swiotlb_info)) = SwiotlbInfo::new_from_fdt(fdt) {
let range = swiotlb_info.fixed_range().ok_or_else(|| {
error!("Pre-shared pool range not specified in swiotlb node");
Error::from(FdtError::BadValue)
diff --git a/libs/libvmbase/src/fdt.rs b/libs/libvmbase/src/fdt.rs
index ff0eaf0..aaf354e 100644
--- a/libs/libvmbase/src/fdt.rs
+++ b/libs/libvmbase/src/fdt.rs
@@ -33,20 +33,20 @@
impl SwiotlbInfo {
/// Creates a `SwiotlbInfo` struct from the given device tree.
- pub fn new_from_fdt(fdt: &Fdt) -> libfdt::Result<SwiotlbInfo> {
- let node =
- fdt.compatible_nodes(cstr!("restricted-dma-pool"))?.next().ok_or(FdtError::NotFound)?;
-
+ pub fn new_from_fdt(fdt: &Fdt) -> libfdt::Result<Option<SwiotlbInfo>> {
+ let Some(node) = fdt.compatible_nodes(cstr!("restricted-dma-pool"))?.next() else {
+ return Ok(None);
+ };
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)?;
+ let reg = reg.next().ok_or(FdtError::BadValue)?;
+ let size = reg.size.ok_or(FdtError::BadValue)?;
(Some(reg.addr.try_into().unwrap()), size.try_into().unwrap(), None)
} else {
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(Self { addr, size, align })
+ Ok(Some(Self { addr, size, align }))
}
/// Returns the fixed range of memory mapped by the SWIOTLB buffer, if available.