pvmfw: Accept either swiotlb DT reg or size/align

In accordance with the Linux documentation for "restricted-dma-pool",
either expect a static region through the <reg> property OR a dynamic
one with the <size> property, not both. When <reg> is used, assume that
<alignment> isn't needed either as no allocation is required (docs are
currently unclear on this).

Remove properties that aren't deemed necessary from the template DT,
when modifying it to generate the guest DT. To do so, NOP the properties
instead of deleting them, this has the same effect of removing them from
the DT but is O(1) instead of O(n) in the length of the DT; as we
fdt.pack() it once done, the final result remains as compact as possible
anyway.

Bug: 244630071
Test: m pvmfw_img
Change-Id: I22ae4bbb7fdc5030de4fd6db95a4103e3459c401
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index 9785941..17cafd5 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -459,6 +459,17 @@
         fdt_err_expect_zero(ret)
     }
 
+    /// Overwrite the given property with FDT_NOP, effectively removing it from the DT.
+    pub fn nop_property(&mut self, name: &CStr) -> Result<()> {
+        // SAFETY - Accesses are constrained to the DT totalsize (validated by ctor) when the
+        // library locates the node's property.
+        let ret = unsafe {
+            libfdt_bindgen::fdt_nop_property(self.fdt.as_mut_ptr(), self.offset, name.as_ptr())
+        };
+
+        fdt_err_expect_zero(ret)
+    }
+
     /// Reduce the size of the given property to new_size
     pub fn trimprop(&mut self, name: &CStr, new_size: usize) -> Result<()> {
         let (prop, len) =
diff --git a/pvmfw/src/fdt.rs b/pvmfw/src/fdt.rs
index 5ecb038..97db601 100644
--- a/pvmfw/src/fdt.rs
+++ b/pvmfw/src/fdt.rs
@@ -440,7 +440,7 @@
 pub struct SwiotlbInfo {
     addr: Option<usize>,
     size: usize,
-    align: usize,
+    align: Option<usize>,
 }
 
 impl SwiotlbInfo {
@@ -452,17 +452,16 @@
 fn read_swiotlb_info_from(fdt: &Fdt) -> libfdt::Result<SwiotlbInfo> {
     let node =
         fdt.compatible_nodes(cstr!("restricted-dma-pool"))?.next().ok_or(FdtError::NotFound)?;
-    let align =
-        node.getprop_u64(cstr!("alignment"))?.ok_or(FdtError::NotFound)?.try_into().unwrap();
 
-    let (addr, size) = if let Some(mut reg) = node.reg()? {
+    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)?;
         reg.addr.checked_add(size).ok_or(FdtError::BadValue)?;
-        (Some(reg.addr.try_into().unwrap()), size.try_into().unwrap())
+        (Some(reg.addr.try_into().unwrap()), size.try_into().unwrap(), None)
     } else {
-        let size = node.getprop_u64(cstr!("size"))?.ok_or(FdtError::NotFound)?.try_into().unwrap();
-        (None, size)
+        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(SwiotlbInfo { addr, size, align })
@@ -480,7 +479,7 @@
         return Err(RebootReason::InvalidFdt);
     }
 
-    if (align % GUEST_PAGE_SIZE) != 0 {
+    if let Some(align) = align.filter(|&a| a % GUEST_PAGE_SIZE != 0) {
         error!("Invalid swiotlb alignment {:#x}", align);
         return Err(RebootReason::InvalidFdt);
     }
@@ -498,7 +497,6 @@
 fn patch_swiotlb_info(fdt: &mut Fdt, swiotlb_info: &SwiotlbInfo) -> libfdt::Result<()> {
     let mut node =
         fdt.root_mut()?.next_compatible(cstr!("restricted-dma-pool"))?.ok_or(FdtError::NotFound)?;
-    node.setprop_inplace(cstr!("alignment"), &swiotlb_info.align.to_be_bytes())?;
 
     if let Some(range) = swiotlb_info.fixed_range() {
         node.appendprop_addrrange(
@@ -506,8 +504,11 @@
             range.start.try_into().unwrap(),
             range.len().try_into().unwrap(),
         )?;
+        node.nop_property(cstr!("size"))?;
+        node.nop_property(cstr!("alignment"))?;
     } else {
         node.setprop_inplace(cstr!("size"), &swiotlb_info.size.to_be_bytes())?;
+        node.setprop_inplace(cstr!("alignment"), &swiotlb_info.align.unwrap().to_be_bytes())?;
     }
 
     Ok(())