libavf: implement setHypervisorSpecificAuthMethod for Gunyah
Bug: 381971305
Bug: 380912007
Test: m
Change-Id: Ic997b73f5cad00d4b93a1aff64ee3d24aebf2c6f
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index 0cde751..c71b5c5 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -588,8 +588,11 @@
check_gdb_allowed(config)?;
}
+ let instance_id = extract_instance_id(config);
let mut device_tree_overlays = vec![];
- if let Some(dt_overlay) = maybe_create_reference_dt_overlay(config, &temporary_directory)? {
+ if let Some(dt_overlay) =
+ maybe_create_reference_dt_overlay(config, &instance_id, &temporary_directory)?
+ {
device_tree_overlays.push(dt_overlay);
}
if let Some(dtbo) = get_dtbo(config) {
@@ -860,6 +863,8 @@
balloon: config.balloon,
usb_config,
dump_dt_fd,
+ enable_hypervisor_specific_auth_method: config.enableHypervisorSpecificAuthMethod,
+ instance_id,
};
let instance = Arc::new(
VmInstance::new(
@@ -947,6 +952,7 @@
fn maybe_create_reference_dt_overlay(
config: &VirtualMachineConfig,
+ instance_id: &[u8; 64],
temporary_directory: &Path,
) -> binder::Result<Option<File>> {
// Currently, VirtMgr adds the host copy of reference DT & untrusted properties
@@ -975,11 +981,9 @@
vec![]
};
- let instance_id;
let key_material;
let mut untrusted_props = Vec::with_capacity(2);
if cfg!(llpvm_changes) {
- instance_id = extract_instance_id(config);
untrusted_props.push((cstr!("instance-id"), &instance_id[..]));
let want_updatable = extract_want_updatable(config);
if want_updatable && is_secretkeeper_supported() {
diff --git a/android/virtmgr/src/crosvm.rs b/android/virtmgr/src/crosvm.rs
index f3b669f..a90c1ff 100644
--- a/android/virtmgr/src/crosvm.rs
+++ b/android/virtmgr/src/crosvm.rs
@@ -137,6 +137,8 @@
pub balloon: bool,
pub usb_config: UsbConfig,
pub dump_dt_fd: Option<File>,
+ pub enable_hypervisor_specific_auth_method: bool,
+ pub instance_id: [u8; 64],
}
#[derive(Debug)]
@@ -989,7 +991,29 @@
let mut memory_mib = config.memory_mib;
+ if config.enable_hypervisor_specific_auth_method && !config.protected {
+ bail!("hypervisor specific auth method only supported for protected VMs");
+ }
if config.protected {
+ if config.enable_hypervisor_specific_auth_method {
+ if !hypervisor_props::is_gunyah()? {
+ bail!("hypervisor specific auth method not supported for current hypervisor");
+ }
+ // "QCOM Trusted VM" compatibility mode.
+ //
+ // 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());
+ command.arg("--hypervisor").arg(
+ format!("gunyah[device=/dev/gunyah,qcom_trusted_vm_id={vm_id},qcom_trusted_vm_pas_id={pas_id}]"),
+ );
+ // Put the FDT close to the payload (default is end of RAM) to so that CMA can be used
+ // without bloating memory usage.
+ command.arg("--fdt-position").arg("after-payload");
+ }
+
match system_properties::read(SYSPROP_CUSTOM_PVMFW_PATH)? {
Some(pvmfw_path) if !pvmfw_path.is_empty() => {
if pvmfw_path == "none" {
diff --git a/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl b/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
index 62a6d57..b6eff64 100644
--- a/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
+++ b/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
@@ -120,4 +120,10 @@
/** List of tee services this VM wants to access */
String[] teeServices;
+
+ /**
+ * Set whether to use an alternate, hypervisor-specific authentication method for protected
+ * VMs.
+ */
+ boolean enableHypervisorSpecificAuthMethod;
}
diff --git a/libs/hypervisor_props/src/lib.rs b/libs/hypervisor_props/src/lib.rs
index 14614fd..094e895 100644
--- a/libs/hypervisor_props/src/lib.rs
+++ b/libs/hypervisor_props/src/lib.rs
@@ -37,3 +37,8 @@
pub fn version() -> Result<Option<String>> {
Ok(hypervisorproperties::hypervisor_version()?)
}
+
+/// Returns if the hypervisor is Gunyah
+pub fn is_gunyah() -> Result<bool> {
+ Ok(version()?.unwrap_or_default().starts_with("gunyah"))
+}
diff --git a/libs/libavf/src/lib.rs b/libs/libavf/src/lib.rs
index 4f23da4..6532ace 100644
--- a/libs/libavf/src/lib.rs
+++ b/libs/libavf/src/lib.rs
@@ -237,16 +237,21 @@
config.protectedVm = protected_vm;
}
-/// NOT IMPLEMENTED.
+/// Set whether to use an alternate, hypervisor-specific authentication method for protected VMs.
///
-/// # Returns
-/// It always returns `-ENOTSUP`.
+/// # Safety
+/// `config` must be a pointer returned by `AVirtualMachineRawConfig_create`.
#[no_mangle]
-pub extern "C" fn AVirtualMachineRawConfig_setHypervisorSpecificAuthMethod(
- _config: *mut VirtualMachineRawConfig,
- _enable: bool,
+pub unsafe extern "C" fn AVirtualMachineRawConfig_setHypervisorSpecificAuthMethod(
+ config: *mut VirtualMachineRawConfig,
+ enable: bool,
) -> c_int {
- -libc::ENOTSUP
+ // SAFETY: `config` is assumed to be a valid, non-null pointer returned by
+ // AVirtualMachineRawConfig_create. It's the only reference to the object.
+ let config = unsafe { &mut *config };
+ config.enableHypervisorSpecificAuthMethod = enable;
+ // We don't validate whether this is supported until later, when the VM is started.
+ 0
}
/// NOT IMPLEMENTED.