Allow host-controlled avf/untrusted prop

Allow addition of properties at /avf/untrusted in the DT overlay
created by virtmgr. While I'm here, refactor reference_dt into
dt_overlay to allow this & remove confusion of reference DT which from
the pt. of view of pVM is expected from ABL.

Include (a hardcoded) instance_id of VM in the DT overlay!

Test: vm_shell start-microdroid --auto-connect
Test: Check /proc/device-tree/avf/untrusted/instance-id has value of hardcoded id in non-protected VM
Test: atest virtualizationmanager_device_test
Bug: 291213394

Revert^2: This reverts commit 655d87fc5b0a0d33baecf40165da2ec1e8f37348.

Reason for revert: Revert^1 was caused by a bug in FsFdt, fixed in
parent commit of the current one.

Change-Id: Ia79fd8dce37f5a13b95c53edef89fe99e225c439
diff --git a/virtualizationmanager/src/aidl.rs b/virtualizationmanager/src/aidl.rs
index 771863b..6a8f1a1 100644
--- a/virtualizationmanager/src/aidl.rs
+++ b/virtualizationmanager/src/aidl.rs
@@ -19,9 +19,9 @@
 use crate::composite::make_composite_image;
 use crate::crosvm::{CrosvmConfig, DiskFile, PayloadState, VmContext, VmInstance, VmState};
 use crate::debug_config::DebugConfig;
+use crate::dt_overlay::{create_device_tree_overlay, VM_DT_OVERLAY_MAX_SIZE, VM_DT_OVERLAY_PATH};
 use crate::payload::{add_microdroid_payload_images, add_microdroid_system_images, add_microdroid_vendor_image};
 use crate::selinux::{getfilecon, SeContext};
-use crate::reference_dt;
 use android_os_permissions_aidl::aidl::android::os::IPermissionController;
 use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::{
     Certificate::Certificate,
@@ -68,6 +68,7 @@
     Status, StatusCode, Strong,
     IntoBinderResult,
 };
+use cstr::cstr;
 use disk::QcowFile;
 use glob::glob;
 use lazy_static::lazy_static;
@@ -79,6 +80,7 @@
 use semver::VersionReq;
 use std::collections::HashSet;
 use std::convert::TryInto;
+use std::fs;
 use std::ffi::CStr;
 use std::fs::{canonicalize, read_dir, remove_file, File, OpenOptions};
 use std::io::{BufRead, BufReader, Error, ErrorKind, Seek, SeekFrom, Write};
@@ -118,6 +120,8 @@
 /// crosvm requires all partitions to be a multiple of 4KiB.
 const PARTITION_GRANULARITY_BYTES: u64 = 4096;
 
+const VM_REFERENCE_DT_ON_HOST_PATH: &str = "/proc/device-tree/avf/reference";
+
 lazy_static! {
     pub static ref GLOBAL_SERVICE: Strong<dyn IVirtualizationServiceInternal> =
         wait_for_interface(BINDER_SERVICE_IDENTIFIER)
@@ -376,12 +380,36 @@
             check_gdb_allowed(config)?;
         }
 
-        let reference_dt = reference_dt::parse_reference_dt(&temporary_directory)
-            .context("Failed to create VM reference DT")
-            .or_service_specific_exception(-1)?;
-        if reference_dt.is_none() {
-            warn!("VM reference DT doesn't exist");
-        }
+        // Currently, VirtMgr adds the host copy of reference DT & an untrusted prop (instance-id)
+        let host_ref_dt = Path::new(VM_REFERENCE_DT_ON_HOST_PATH);
+        let host_ref_dt = if host_ref_dt.exists()
+            && read_dir(host_ref_dt).or_service_specific_exception(-1)?.next().is_some()
+        {
+            Some(host_ref_dt)
+        } else {
+            warn!("VM reference DT doesn't exist in host DT");
+            None
+        };
+
+        let untrusted_props = if cfg!(llpvm_changes) {
+            // TODO(b/291213394): Replace this with a per-VM instance Id.
+            let instance_id = b"sixtyfourbyteslonghardcoded_indeed_sixtyfourbyteslonghardcoded_h";
+            vec![(cstr!("instance-id"), &instance_id[..])]
+        } else {
+            vec![]
+        };
+
+        let device_tree_overlay = if host_ref_dt.is_some() || !untrusted_props.is_empty() {
+            let dt_output = temporary_directory.join(VM_DT_OVERLAY_PATH);
+            let mut data = [0_u8; VM_DT_OVERLAY_MAX_SIZE];
+            let fdt = create_device_tree_overlay(&mut data, host_ref_dt, &untrusted_props)
+                .map_err(|e| anyhow!("Failed to create DT overlay, {e:?}"))
+                .or_service_specific_exception(-1)?;
+            fs::write(&dt_output, fdt.as_slice()).or_service_specific_exception(-1)?;
+            Some(File::open(dt_output).or_service_specific_exception(-1)?)
+        } else {
+            None
+        };
 
         let debug_level = match config {
             VirtualMachineConfig::AppConfig(config) => config.debugLevel,
@@ -531,7 +559,7 @@
             gdb_port,
             vfio_devices,
             dtbo,
-            reference_dt,
+            device_tree_overlay,
         };
         let instance = Arc::new(
             VmInstance::new(