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.