pvmfw: Do not return error when interrupts property is not present

There can be some nodes without an interrupt property.
Do not return error in that case.

Test: m libpvmfw.device_assignment.test pvmfw
Bug: 385802423
Change-Id: I0ab048872d07220e3d54ea7995a24315f9fd5a31
Signed-off-by: Sreenad Menon <quic_sreemeno@quicinc.com>
diff --git a/guest/pvmfw/src/device_assignment.rs b/guest/pvmfw/src/device_assignment.rs
index efdf4c4..2e4bb6d 100644
--- a/guest/pvmfw/src/device_assignment.rs
+++ b/guest/pvmfw/src/device_assignment.rs
@@ -742,7 +742,7 @@
     // <reg> property from the crosvm DT
     reg: Vec<DeviceReg>,
     // <interrupts> property from the crosvm DT
-    interrupts: Vec<u8>,
+    interrupts: Option<Vec<u8>>,
     // Parsed <iommus> property from the crosvm DT. Tuple of PvIommu and vSID.
     iommus: Option<Vec<(PvIommu, Vsid)>>,
 }
@@ -796,19 +796,18 @@
         Ok(())
     }
 
-    fn parse_interrupts(node: &FdtNode) -> Result<Vec<u8>> {
+    fn parse_interrupts(node: &FdtNode) -> Result<Option<Vec<u8>>> {
+        let Some(cells) = node.getprop_cells(c"interrupts")? else {
+            return Ok(None);
+        };
         // Validation: Validate if interrupts cell numbers are multiple of #interrupt-cells.
         // We can't know how many interrupts would exist.
-        let interrupts_cells = node
-            .getprop_cells(c"interrupts")?
-            .ok_or(DeviceAssignmentError::InvalidInterrupts)?
-            .count();
-        if interrupts_cells % CELLS_PER_INTERRUPT != 0 {
+        if cells.count() % CELLS_PER_INTERRUPT != 0 {
             return Err(DeviceAssignmentError::InvalidInterrupts);
         }
 
         // Once validated, keep the raw bytes so patch can be done with setprop()
-        Ok(node.getprop(c"interrupts").unwrap().unwrap().into())
+        Ok(Some(node.getprop(c"interrupts").unwrap().unwrap().into()))
     }
 
     // TODO(b/277993056): Also validate /__local_fixups__ to ensure that <iommus> has phandle.
@@ -914,7 +913,11 @@
     fn patch(&self, fdt: &mut Fdt, pviommu_phandles: &BTreeMap<PvIommu, Phandle>) -> Result<()> {
         let mut dst = fdt.node_mut(&self.node_path)?.unwrap();
         dst.setprop(c"reg", &to_be_bytes(&self.reg))?;
-        dst.setprop(c"interrupts", &self.interrupts)?;
+        if let Some(interrupts) = &self.interrupts {
+            dst.setprop(c"interrupts", interrupts)?;
+        } else {
+            dst.nop_property(c"interrupts")?;
+        }
 
         if let Some(iommus) = &self.iommus {
             let mut iommus_vec = Vec::with_capacity(8 * iommus.len());
@@ -1345,7 +1348,7 @@
         let expected = [AssignedDeviceInfo {
             node_path: CString::new("/bus0/backlight").unwrap(),
             reg: vec![[0x9, 0xFF].into()],
-            interrupts: into_fdt_prop(vec![0x0, 0xF, 0x4]),
+            interrupts: Some(into_fdt_prop(vec![0x0, 0xF, 0x4])),
             iommus: Some(vec![]),
         }];
 
@@ -1370,7 +1373,7 @@
         let expected = [AssignedDeviceInfo {
             node_path: CString::new("/rng").unwrap(),
             reg: vec![[0x9, 0xFF].into()],
-            interrupts: into_fdt_prop(vec![0x0, 0xF, 0x4]),
+            interrupts: Some(into_fdt_prop(vec![0x0, 0xF, 0x4])),
             iommus: Some(vec![(PvIommu { id: 0x4 }, Vsid(0xFF0))]),
         }];