Merge changes from topic "custom-smcs" into main
* changes:
Start a VM in suspended state if vendor_tee_services were requested
custom smcs: check for presence of HAL
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index 190acc7..161a534 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -117,6 +117,9 @@
const SECRETKEEPER_IDENTIFIER: &str =
"android.hardware.security.secretkeeper.ISecretkeeper/default";
+const VM_CAPABILITIES_HAL_IDENTIFIER: &str =
+ "android.hardware.virtualization.capabilities.IVmCapabilitiesService/default";
+
const UNFORMATTED_STORAGE_MAGIC: &str = "UNFORMATTED-STORAGE";
/// crosvm requires all partitions to be a multiple of 4KiB.
@@ -765,10 +768,11 @@
}
}
- // TODO(b/391774181): handle vendor tee services (which require talking to HAL) as well.
- if !vendor_tee_services.is_empty() {
- return Err(anyhow!("support for vendor tee services is coming soon!"))
- .or_binder_exception(ExceptionCode::UNSUPPORTED_OPERATION);
+ if !vendor_tee_services.is_empty() && !is_vm_capabilities_hal_supported() {
+ return Err(anyhow!(
+ "requesting access to tee services requires {VM_CAPABILITIES_HAL_IDENTIFIER}"
+ ))
+ .or_binder_exception(ExceptionCode::UNSUPPORTED_OPERATION);
}
// TODO(b/391774181): remove this check in a follow-up patch.
@@ -1011,6 +1015,7 @@
enable_hypervisor_specific_auth_method: config.enableHypervisorSpecificAuthMethod,
instance_id,
custom_memory_backing_files,
+ start_suspended: !vendor_tee_services.is_empty(),
};
let instance = Arc::new(
VmInstance::new(
@@ -1019,6 +1024,7 @@
requester_uid,
requester_debug_pid,
vm_context,
+ vendor_tee_services,
)
.with_context(|| format!("Failed to create VM with config {:?}", config))
.with_log()
@@ -1719,6 +1725,16 @@
fn create(instance: Arc<VmInstance>) -> Strong<dyn IVirtualMachine::IVirtualMachine> {
BnVirtualMachine::new_binder(VirtualMachine { instance }, BinderFeatures::default())
}
+
+ fn handle_vendor_tee_services(&self) -> binder::Result<()> {
+ // TODO(b/360102915): get vm_fd from crosvm
+ // TODO(b/360102915): talk to HAL
+ self.instance
+ .resume_full()
+ .with_context(|| format!("Error resuming VM with CID {}", self.instance.cid))
+ .with_log()
+ .or_service_specific_exception(-1)
+ }
}
impl Interface for VirtualMachine {}
@@ -1761,7 +1777,12 @@
.start()
.with_context(|| format!("Error starting VM with CID {}", self.instance.cid))
.with_log()
- .or_service_specific_exception(-1)
+ .or_service_specific_exception(-1)?;
+ if !self.instance.vendor_tee_services.is_empty() {
+ self.handle_vendor_tee_services()
+ } else {
+ Ok(())
+ }
}
fn stop(&self) -> binder::Result<()> {
@@ -2338,6 +2359,11 @@
.expect("Could not check for declared Secretkeeper interface")
}
+fn is_vm_capabilities_hal_supported() -> bool {
+ binder::is_declared(VM_CAPABILITIES_HAL_IDENTIFIER)
+ .expect("failed to check if {VM_CAPABILITIES_HAL_IDENTIFIER} is present")
+}
+
impl VirtualMachineService {
fn new_binder(state: Arc<Mutex<State>>, cid: Cid) -> Strong<dyn IVirtualMachineService> {
BnVirtualMachineService::new_binder(
diff --git a/android/virtmgr/src/crosvm.rs b/android/virtmgr/src/crosvm.rs
index 15a4199..c264185 100644
--- a/android/virtmgr/src/crosvm.rs
+++ b/android/virtmgr/src/crosvm.rs
@@ -142,6 +142,7 @@
pub instance_id: [u8; 64],
// (memfd, guest address, size)
pub custom_memory_backing_files: Vec<(OwnedFd, u64, u64)>,
+ pub start_suspended: bool,
}
#[derive(Debug)]
@@ -419,6 +420,8 @@
pub vm_metric: Mutex<VmMetric>,
// Whether virtio-balloon is enabled
pub balloon_enabled: bool,
+ /// List of vendor tee services this VM might access.
+ pub vendor_tee_services: Vec<String>,
/// The latest lifecycle state which the payload reported itself to be in.
payload_state: Mutex<PayloadState>,
/// Represents the condition that payload_state was updated
@@ -446,6 +449,7 @@
requester_uid: u32,
requester_debug_pid: i32,
vm_context: VmContext,
+ vendor_tee_services: Vec<String>,
) -> Result<VmInstance, Error> {
validate_config(&config)?;
let cid = config.cid;
@@ -473,6 +477,7 @@
payload_state_updated: Condvar::new(),
requester_uid_name,
balloon_enabled,
+ vendor_tee_services,
};
info!("{} created", &instance);
Ok(instance)
@@ -826,6 +831,18 @@
}
Ok(())
}
+
+ /// Performs full resume of VM.
+ pub fn resume_full(&self) -> Result<(), Error> {
+ let socket_path_cstring = path_to_cstring(&self.crosvm_control_socket_path);
+ // SAFETY: Pointer is valid for the lifetime of the call.
+ let success =
+ unsafe { crosvm_control::crosvm_client_resume_vm_full(socket_path_cstring.as_ptr()) };
+ if !success {
+ bail!("Failed to resume VM");
+ }
+ Ok(())
+ }
}
impl Rss {
@@ -1431,6 +1448,10 @@
}
}
+ if config.start_suspended {
+ command.arg("--suspended");
+ }
+
print_crosvm_args(&command);
let result = SharedChild::spawn(&mut command)?;