virtualizationservice: Add dtbo to VirtualMachineRawConfig
Bug: 381971307
Test: T/H
Change-Id: Iea377f4e6d2d4c8ae24dc6349c2b0b3ca432e944
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index daa755e..0cde751 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -29,6 +29,7 @@
ErrorCode::ErrorCode,
};
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
+ AssignedDevices::AssignedDevices,
AssignableDevice::AssignableDevice,
CpuTopology::CpuTopology,
DiskImage::DiskImage,
@@ -587,7 +588,19 @@
check_gdb_allowed(config)?;
}
- let device_tree_overlay = maybe_create_device_tree_overlay(config, &temporary_directory)?;
+ let mut device_tree_overlays = vec![];
+ if let Some(dt_overlay) = maybe_create_reference_dt_overlay(config, &temporary_directory)? {
+ device_tree_overlays.push(dt_overlay);
+ }
+ if let Some(dtbo) = get_dtbo(config) {
+ let dtbo = File::from(
+ dtbo.as_ref()
+ .try_clone()
+ .context("Failed to create VM DTBO from ParcelFileDescriptor")
+ .or_binder_exception(ExceptionCode::BAD_PARCELABLE)?,
+ );
+ device_tree_overlays.push(dtbo);
+ }
let debug_config = DebugConfig::new(config);
let ramdump = if !uses_gki_kernel(config) && debug_config.is_ramdump_needed() {
@@ -715,29 +728,30 @@
}
};
- let (vfio_devices, dtbo) = if !config.devices.is_empty() {
- let mut set = HashSet::new();
- for device in config.devices.iter() {
- let path = canonicalize(device)
- .with_context(|| format!("can't canonicalize {device}"))
- .or_service_specific_exception(-1)?;
- if !set.insert(path) {
- return Err(anyhow!("duplicated device {device}"))
- .or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT);
+ let (vfio_devices, dtbo) = match &config.devices {
+ AssignedDevices::Devices(devices) if !devices.is_empty() => {
+ let mut set = HashSet::new();
+ for device in devices.iter() {
+ let path = canonicalize(device)
+ .with_context(|| format!("can't canonicalize {device}"))
+ .or_service_specific_exception(-1)?;
+ if !set.insert(path) {
+ return Err(anyhow!("duplicated device {device}"))
+ .or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT);
+ }
}
+ let devices = GLOBAL_SERVICE.bindDevicesToVfioDriver(devices)?;
+ let dtbo_file = File::from(
+ GLOBAL_SERVICE
+ .getDtboFile()?
+ .as_ref()
+ .try_clone()
+ .context("Failed to create VM DTBO from ParcelFileDescriptor")
+ .or_binder_exception(ExceptionCode::BAD_PARCELABLE)?,
+ );
+ (devices, Some(dtbo_file))
}
- let devices = GLOBAL_SERVICE.bindDevicesToVfioDriver(&config.devices)?;
- let dtbo_file = File::from(
- GLOBAL_SERVICE
- .getDtboFile()?
- .as_ref()
- .try_clone()
- .context("Failed to create VM DTBO from ParcelFileDescriptor")
- .or_binder_exception(ExceptionCode::BAD_PARCELABLE)?,
- );
- (devices, Some(dtbo_file))
- } else {
- (vec![], None)
+ _ => (vec![], None),
};
let display_config = if cfg!(paravirtualized_devices) {
config
@@ -834,7 +848,7 @@
gdb_port,
vfio_devices,
dtbo,
- device_tree_overlay,
+ device_tree_overlays,
display_config,
input_device_options,
hugepages: config.hugePages,
@@ -931,7 +945,7 @@
Err(anyhow!("No hashtree digest is extracted from microdroid vendor image"))
}
-fn maybe_create_device_tree_overlay(
+fn maybe_create_reference_dt_overlay(
config: &VirtualMachineConfig,
temporary_directory: &Path,
) -> binder::Result<Option<File>> {
@@ -1000,6 +1014,16 @@
Ok(device_tree_overlay)
}
+fn get_dtbo(config: &VirtualMachineConfig) -> Option<&ParcelFileDescriptor> {
+ let VirtualMachineConfig::RawConfig(config) = config else {
+ return None;
+ };
+ match &config.devices {
+ AssignedDevices::Dtbo(dtbo) => dtbo.as_ref(),
+ _ => None,
+ }
+}
+
fn write_zero_filler(zero_filler_path: &Path) -> Result<()> {
let file = OpenOptions::new()
.create_new(true)
@@ -1260,7 +1284,7 @@
append_kernel_param("androidboot.microdroid.mount_vendor=1", &mut vm_config)
}
- vm_config.devices.clone_from(&custom_config.devices);
+ vm_config.devices = AssignedDevices::Devices(custom_config.devices.clone());
vm_config.networkSupported = custom_config.networkSupported;
for param in custom_config.extraKernelCmdlineParams.iter() {
diff --git a/android/virtmgr/src/crosvm.rs b/android/virtmgr/src/crosvm.rs
index affd430..f3b669f 100644
--- a/android/virtmgr/src/crosvm.rs
+++ b/android/virtmgr/src/crosvm.rs
@@ -125,7 +125,7 @@
pub gdb_port: Option<NonZeroU16>,
pub vfio_devices: Vec<VfioDevice>,
pub dtbo: Option<File>,
- pub device_tree_overlay: Option<File>,
+ pub device_tree_overlays: Vec<File>,
pub display_config: Option<DisplayConfig>,
pub input_device_options: Vec<InputDeviceOption>,
pub hugepages: bool,
@@ -1157,9 +1157,10 @@
.context("failed to create control listener")?;
command.arg("--socket").arg(add_preserved_fd(&mut preserved_fds, control_sock));
- if let Some(dt_overlay) = config.device_tree_overlay {
- command.arg("--device-tree-overlay").arg(add_preserved_fd(&mut preserved_fds, dt_overlay));
- }
+ config.device_tree_overlays.into_iter().for_each(|dt_overlay| {
+ let arg = add_preserved_fd(&mut preserved_fds, dt_overlay);
+ command.arg("--device-tree-overlay").arg(arg);
+ });
if cfg!(paravirtualized_devices) {
if let Some(gpu_config) = &config.gpu_config {
diff --git a/android/virtualizationservice/aidl/android/system/virtualizationservice/AssignedDevices.aidl b/android/virtualizationservice/aidl/android/system/virtualizationservice/AssignedDevices.aidl
new file mode 100644
index 0000000..984f596
--- /dev/null
+++ b/android/virtualizationservice/aidl/android/system/virtualizationservice/AssignedDevices.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.system.virtualizationservice;
+
+/** Assigned devices */
+union AssignedDevices {
+ /** List of SysFS nodes of devices to be assigned for VFIO */
+ String[] devices = {};
+
+ /** Device tree overlay for non-VFIO case */
+ ParcelFileDescriptor dtbo;
+}
diff --git a/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl b/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
index 9ebb7fe..62a6d57 100644
--- a/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
+++ b/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
@@ -15,6 +15,7 @@
*/
package android.system.virtualizationservice;
+import android.system.virtualizationservice.AssignedDevices;
import android.system.virtualizationservice.AudioConfig;
import android.system.virtualizationservice.CpuTopology;
import android.system.virtualizationservice.DiskImage;
@@ -91,8 +92,8 @@
*/
boolean hugePages;
- /** List of SysFS nodes of devices to be assigned */
- String[] devices;
+ /** Assigned devices */
+ AssignedDevices devices;
@nullable DisplayConfig displayConfig;
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java
index d6b38ea..6311168 100644
--- a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -40,6 +40,7 @@
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.sysprop.HypervisorProperties;
+import android.system.virtualizationservice.AssignedDevices;
import android.system.virtualizationservice.DiskImage;
import android.system.virtualizationservice.Partition;
import android.system.virtualizationservice.SharedPath;
@@ -807,7 +808,7 @@
config.memoryMib = bytesToMebiBytes(mMemoryBytes);
config.cpuTopology = (byte) this.mCpuTopology;
config.consoleInputDevice = mConsoleInputDevice;
- config.devices = EMPTY_STRING_ARRAY;
+ config.devices = AssignedDevices.devices(EMPTY_STRING_ARRAY);
config.platformVersion = "~1.0";
config.audioConfig =
Optional.ofNullable(customImageConfig.getAudioConfig())
diff --git a/libs/vmconfig/src/lib.rs b/libs/vmconfig/src/lib.rs
index e520f0e..8357f99 100644
--- a/libs/vmconfig/src/lib.rs
+++ b/libs/vmconfig/src/lib.rs
@@ -15,6 +15,7 @@
//! Struct for VM configuration with JSON (de)serialization and AIDL parcelables
use android_system_virtualizationservice::{
+ aidl::android::system::virtualizationservice::AssignedDevices::AssignedDevices,
aidl::android::system::virtualizationservice::CpuTopology::CpuTopology,
aidl::android::system::virtualizationservice::DiskImage::DiskImage as AidlDiskImage,
aidl::android::system::virtualizationservice::Partition::Partition as AidlPartition,
@@ -124,13 +125,16 @@
memoryMib: memory_mib,
cpuTopology: cpu_topology,
platformVersion: self.platform_version.to_string(),
- devices: self
- .devices
- .iter()
- .map(|x| {
- x.to_str().map(String::from).ok_or(anyhow!("Failed to convert {x:?} to String"))
- })
- .collect::<Result<_>>()?,
+ devices: AssignedDevices::Devices(
+ self.devices
+ .iter()
+ .map(|x| {
+ x.to_str()
+ .map(String::from)
+ .ok_or(anyhow!("Failed to convert {x:?} to String"))
+ })
+ .collect::<Result<_>>()?,
+ ),
consoleInputDevice: self.console_input_device.clone(),
usbConfig: usb_config,
balloon: true,