Merge "guest: trusty: enable pvmfw-verified pVM for security and test VMs" into main
diff --git a/android/virtmgr/fsfdt/Android.bp b/android/virtmgr/fsfdt/Android.bp
index 1d03522..64a253d 100644
--- a/android/virtmgr/fsfdt/Android.bp
+++ b/android/virtmgr/fsfdt/Android.bp
@@ -28,12 +28,12 @@
         "liblibfdt",
         "libanyhow",
     ],
-    apex_available: ["com.android.virt"],
 }
 
 rust_library_rlib {
     name: "libfsfdt",
     defaults: ["libfsfdt_default"],
+    apex_available: ["com.android.virt"],
 }
 
 rust_test {
diff --git a/android/virtmgr/src/crosvm.rs b/android/virtmgr/src/crosvm.rs
index 59f115e..8500421 100644
--- a/android/virtmgr/src/crosvm.rs
+++ b/android/virtmgr/src/crosvm.rs
@@ -1044,8 +1044,8 @@
             // When this mode is enabled, two hypervisor specific IDs are expected to be packed
             // into the instance ID. We extract them here and pass along to crosvm so they can be
             // given to the hypervisor driver via an ioctl.
-            let vm_id = u32::from_le_bytes(config.instance_id[60..64].try_into().unwrap());
-            let pas_id = u16::from_le_bytes(config.instance_id[58..60].try_into().unwrap());
+            let pas_id = u32::from_le_bytes(config.instance_id[60..64].try_into().unwrap());
+            let vm_id = u16::from_le_bytes(config.instance_id[58..60].try_into().unwrap());
             command.arg("--hypervisor").arg(
                 format!("gunyah[device=/dev/gunyah,qcom_trusted_vm_id={vm_id},qcom_trusted_vm_pas_id={pas_id}]"),
             );
diff --git a/android/virtualizationservice/Android.bp b/android/virtualizationservice/Android.bp
index fb6e39a..6f76510 100644
--- a/android/virtualizationservice/Android.bp
+++ b/android/virtualizationservice/Android.bp
@@ -55,12 +55,12 @@
         "libservice_vm_comm",
         "libservice_vm_manager",
     ],
-    apex_available: ["com.android.virt"],
 }
 
 rust_binary {
     name: "virtualizationservice",
     defaults: ["virtualizationservice_defaults"],
+    apex_available: ["com.android.virt"],
 }
 
 xsd_config {
diff --git a/guest/compos_key_helper/Android.bp b/guest/compos_key_helper/Android.bp
index 4d86780..0cd4c33 100644
--- a/guest/compos_key_helper/Android.bp
+++ b/guest/compos_key_helper/Android.bp
@@ -5,7 +5,6 @@
 cc_defaults {
     name: "compos_key_defaults",
     defaults: ["avf_build_flags_cc"],
-    apex_available: ["com.android.compos"],
 
     shared_libs: [
         "libbase",
@@ -18,6 +17,7 @@
     defaults: ["compos_key_defaults"],
     srcs: ["compos_key.cpp"],
     export_include_dirs: ["."],
+    apex_available: ["com.android.compos"],
 }
 
 cc_binary {
@@ -33,6 +33,7 @@
         "libvm_payload#current",
         "libbinder_ndk",
     ],
+    apex_available: ["com.android.compos"],
 }
 
 cc_test {
diff --git a/guest/pvmfw/src/fdt.rs b/guest/pvmfw/src/fdt.rs
index 6716130..59399b3 100644
--- a/guest/pvmfw/src/fdt.rs
+++ b/guest/pvmfw/src/fdt.rs
@@ -78,48 +78,99 @@
     }
 }
 
+/// For non-standardly sized integer properties, not following <#size-cells> or <#address-cells>.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+enum DeviceTreeInteger {
+    SingleCell(u32),
+    DoubleCell(u64),
+}
+
+impl DeviceTreeInteger {
+    fn read_from(node: &FdtNode, name: &CStr) -> libfdt::Result<Option<Self>> {
+        if let Some(bytes) = node.getprop(name)? {
+            Ok(Some(Self::from_bytes(bytes).ok_or(FdtError::BadValue)?))
+        } else {
+            Ok(None)
+        }
+    }
+
+    fn from_bytes(bytes: &[u8]) -> Option<Self> {
+        if let Some(val) = bytes.try_into().ok().map(u32::from_be_bytes) {
+            return Some(Self::SingleCell(val));
+        } else if let Some(val) = bytes.try_into().ok().map(u64::from_be_bytes) {
+            return Some(Self::DoubleCell(val));
+        }
+        None
+    }
+
+    fn write_to(&self, node: &mut FdtNodeMut, name: &CStr) -> libfdt::Result<()> {
+        match self {
+            Self::SingleCell(value) => node.setprop(name, &value.to_be_bytes()),
+            Self::DoubleCell(value) => node.setprop(name, &value.to_be_bytes()),
+        }
+    }
+}
+
+impl From<DeviceTreeInteger> for usize {
+    fn from(i: DeviceTreeInteger) -> Self {
+        match i {
+            DeviceTreeInteger::SingleCell(v) => v.try_into().unwrap(),
+            DeviceTreeInteger::DoubleCell(v) => v.try_into().unwrap(),
+        }
+    }
+}
+
+/// Returns the pair or integers or an error if only one value is present.
+fn read_two_ints(
+    node: &FdtNode,
+    name_a: &CStr,
+    name_b: &CStr,
+) -> libfdt::Result<Option<(DeviceTreeInteger, DeviceTreeInteger)>> {
+    let a = DeviceTreeInteger::read_from(node, name_a)?;
+    let b = DeviceTreeInteger::read_from(node, name_b)?;
+
+    match (a, b) {
+        (Some(a), Some(b)) => Ok(Some((a, b))),
+        (None, None) => Ok(None),
+        _ => Err(FdtError::NotFound),
+    }
+}
+
 /// Extract from /config the address range containing the pre-loaded kernel.
 ///
 /// Absence of /config is not an error. However, an error is returned if only one of the two
 /// properties is present.
 pub fn read_kernel_range_from(fdt: &Fdt) -> libfdt::Result<Option<Range<usize>>> {
-    let addr = c"kernel-address";
-    let size = c"kernel-size";
-
-    if let Some(config) = fdt.node(c"/config")? {
-        match (config.getprop_u32(addr)?, config.getprop_u32(size)?) {
-            (None, None) => {}
-            (Some(addr), Some(size)) => {
-                let addr = addr as usize;
-                let size = size as usize;
-                return Ok(Some(addr..(addr + size)));
-            }
-            _ => return Err(FdtError::NotFound),
+    if let Some(ref config) = fdt.node(c"/config")? {
+        if let Some((addr, size)) = read_two_ints(config, c"kernel-address", c"kernel-size")? {
+            let addr = usize::from(addr);
+            let size = usize::from(size);
+            return Ok(Some(addr..(addr + size)));
         }
     }
-
     Ok(None)
 }
 
+fn read_initrd_range_props(
+    fdt: &Fdt,
+) -> libfdt::Result<Option<(DeviceTreeInteger, DeviceTreeInteger)>> {
+    if let Some(ref chosen) = fdt.chosen()? {
+        read_two_ints(chosen, c"linux,initrd-start", c"linux,initrd-end")
+    } else {
+        Ok(None)
+    }
+}
+
 /// Extract from /chosen the address range containing the pre-loaded ramdisk.
 ///
 /// Absence is not an error as there can be initrd-less VM. However, an error is returned if only
 /// one of the two properties is present.
 pub fn read_initrd_range_from(fdt: &Fdt) -> libfdt::Result<Option<Range<usize>>> {
-    let start = c"linux,initrd-start";
-    let end = c"linux,initrd-end";
-
-    if let Some(chosen) = fdt.chosen()? {
-        match (chosen.getprop_u32(start)?, chosen.getprop_u32(end)?) {
-            (None, None) => {}
-            (Some(start), Some(end)) => {
-                return Ok(Some((start as usize)..(end as usize)));
-            }
-            _ => return Err(FdtError::NotFound),
-        }
+    if let Some((start, end)) = read_initrd_range_props(fdt)? {
+        Ok(Some(usize::from(start)..usize::from(end)))
+    } else {
+        Ok(None)
     }
-
-    Ok(None)
 }
 
 /// Read /avf/untrusted/instance-id, if present.
@@ -140,13 +191,14 @@
     }
 }
 
-fn patch_initrd_range(fdt: &mut Fdt, initrd_range: &Range<usize>) -> libfdt::Result<()> {
-    let start = u32::try_from(initrd_range.start).unwrap();
-    let end = u32::try_from(initrd_range.end).unwrap();
-
+fn patch_initrd_range(
+    fdt: &mut Fdt,
+    start: &DeviceTreeInteger,
+    end: &DeviceTreeInteger,
+) -> libfdt::Result<()> {
     let mut node = fdt.chosen_mut()?.ok_or(FdtError::NotFound)?;
-    node.setprop(c"linux,initrd-start", &start.to_be_bytes())?;
-    node.setprop(c"linux,initrd-end", &end.to_be_bytes())?;
+    start.write_to(&mut node, c"linux,initrd-start")?;
+    end.write_to(&mut node, c"linux,initrd-end")?;
     Ok(())
 }
 
@@ -1024,7 +1076,7 @@
 
 #[derive(Debug)]
 pub struct DeviceTreeInfo {
-    pub initrd_range: Option<Range<usize>>,
+    initrd_range: Option<(DeviceTreeInteger, DeviceTreeInteger)>,
     pub memory_range: Range<usize>,
     bootargs: Option<CString>,
     cpus: ArrayVec<[CpuInfo; DeviceTreeInfo::MAX_CPUS]>,
@@ -1122,7 +1174,7 @@
     guest_page_size: usize,
     hyp_page_size: Option<usize>,
 ) -> Result<DeviceTreeInfo, RebootReason> {
-    let initrd_range = read_initrd_range_from(fdt).map_err(|e| {
+    let initrd_range = read_initrd_range_props(fdt).map_err(|e| {
         error!("Failed to read initrd range from DT: {e}");
         RebootReason::InvalidFdt
     })?;
@@ -1236,8 +1288,8 @@
 }
 
 fn patch_device_tree(fdt: &mut Fdt, info: &DeviceTreeInfo) -> Result<(), RebootReason> {
-    if let Some(initrd_range) = &info.initrd_range {
-        patch_initrd_range(fdt, initrd_range).map_err(|e| {
+    if let Some((start, end)) = &info.initrd_range {
+        patch_initrd_range(fdt, start, end).map_err(|e| {
             error!("Failed to patch initrd range to DT: {e}");
             RebootReason::InvalidFdt
         })?;
diff --git a/libs/libservice_vm_requests/Android.bp b/libs/libservice_vm_requests/Android.bp
index d87b087..4a575b2 100644
--- a/libs/libservice_vm_requests/Android.bp
+++ b/libs/libservice_vm_requests/Android.bp
@@ -9,9 +9,6 @@
     defaults: ["avf_build_flags_rust"],
     srcs: ["src/lib.rs"],
     prefer_rlib: true,
-    apex_available: [
-        "com.android.virt",
-    ],
     no_stdlibs: true,
     stdlibs: [
         "libcore.rust_sysroot",
@@ -37,6 +34,9 @@
 rust_library_rlib {
     name: "libservice_vm_requests_nostd",
     defaults: ["libservice_vm_requests_nostd_defaults"],
+    apex_available: [
+        "com.android.virt",
+    ],
 }
 
 rust_test {
diff --git a/tests/authfs/Android.bp b/tests/authfs/Android.bp
index aa814eb..4c44bb3 100644
--- a/tests/authfs/Android.bp
+++ b/tests/authfs/Android.bp
@@ -3,6 +3,7 @@
     defaults: ["authfs_defaults"],
     test_suites: ["general-tests"],
     data: [":authfs_test_files"],
+    apex_available: ["//apex_available:platform"],
 }
 
 filegroup {