Move CpuTopology to CpuOptions
Add CpuOptions for easier expansion of options relating to CPUs.
Bug: N/A
Test: TH, /apex/com.android.virt/bin/vm run-microdroid --cpu-topology cpu_count=#|one_cpu|match_host
Change-Id: I24bc31211448ad9fa5fb80382fcc4626216fe08f
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index 2d31b87..6c01a23 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -31,7 +31,6 @@
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
AssignedDevices::AssignedDevices,
AssignableDevice::AssignableDevice,
- CpuTopology::CpuTopology,
DiskImage::DiskImage,
SharedPath::SharedPath,
InputDevice::InputDevice,
@@ -712,24 +711,6 @@
let shared_paths = assemble_shared_paths(&config.sharedPaths, &temporary_directory)?;
- let (cpus, host_cpu_topology) = match config.cpuTopology {
- CpuTopology::MATCH_HOST => (None, true),
- CpuTopology::ONE_CPU => (NonZeroU32::new(1), false),
- CpuTopology::CUSTOM => (
- NonZeroU32::new(
- u32::try_from(config.customVcpuCount)
- .context("bad customVcpuCount")
- .or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT)?,
- ),
- false,
- ),
- val => {
- return Err(anyhow!("Failed to parse CPU topology value {:?}", val))
- .with_log()
- .or_service_specific_exception(-1);
- }
- };
-
let (vfio_devices, dtbo) = match &config.devices {
AssignedDevices::Devices(devices) if !devices.is_empty() => {
let mut set = HashSet::new();
@@ -840,8 +821,7 @@
.and_then(NonZeroU32::new)
.unwrap_or(NonZeroU32::new(256).unwrap()),
swiotlb_mib: config.swiotlbMib.try_into().ok().and_then(NonZeroU32::new),
- cpus,
- host_cpu_topology,
+ cpus: config.cpuOptions.clone(),
console_out_fd,
console_in_fd,
log_fd,
@@ -1312,10 +1292,7 @@
vm_config.name.clone_from(&config.name);
vm_config.protectedVm = config.protectedVm;
- vm_config.cpuTopology = config.cpuTopology;
- if config.cpuTopology == CpuTopology::CUSTOM {
- bail!("AppConfig doesn't support CpuTopology::CUSTOM");
- }
+ vm_config.cpuOptions = config.cpuOptions.clone();
vm_config.hugePages = config.hugePages || vm_payload_config.hugepages;
vm_config.boostUclamp = config.boostUclamp;
diff --git a/android/virtmgr/src/atom.rs b/android/virtmgr/src/atom.rs
index e0fed85..33299aa 100644
--- a/android/virtmgr/src/atom.rs
+++ b/android/virtmgr/src/atom.rs
@@ -19,7 +19,8 @@
use crate::get_calling_uid;
use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::DeathReason::DeathReason;
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
- CpuTopology::CpuTopology,
+ CpuOptions::CpuOptions,
+ CpuOptions::CpuTopology::CpuTopology,
IVirtualMachine::IVirtualMachine,
VirtualMachineAppConfig::{Payload::Payload, VirtualMachineAppConfig},
VirtualMachineConfig::VirtualMachineConfig,
@@ -92,23 +93,15 @@
}
}
-fn get_num_vcpus(cpu_topology: CpuTopology, custom_vcpu_count: Option<i32>) -> i32 {
- match cpu_topology {
- CpuTopology::ONE_CPU => 1,
- CpuTopology::MATCH_HOST => {
+fn get_num_vcpus(cpu_options: &CpuOptions) -> i32 {
+ match cpu_options.cpuTopology {
+ CpuTopology::MatchHost(_) => {
get_num_cpus().and_then(|v| v.try_into().ok()).unwrap_or_else(|| {
warn!("Failed to determine the number of CPUs in the host");
INVALID_NUM_CPUS
})
}
- CpuTopology::CUSTOM => custom_vcpu_count.unwrap_or_else(|| {
- warn!("AppConfig doesn't support CpuTopology::CUSTOM");
- INVALID_NUM_CPUS
- }),
- _ => {
- warn!("invalid CpuTopology: {cpu_topology:?}");
- INVALID_NUM_CPUS
- }
+ CpuTopology::CpuCount(count) => count,
}
}
@@ -140,14 +133,14 @@
VirtualMachineConfig::AppConfig(config) => (
config.name.clone(),
vm_creation_requested::ConfigType::VirtualMachineAppConfig,
- get_num_vcpus(config.cpuTopology, None),
+ get_num_vcpus(&config.cpuOptions),
config.memoryMib,
get_apex_list(config),
),
VirtualMachineConfig::RawConfig(config) => (
config.name.clone(),
vm_creation_requested::ConfigType::VirtualMachineRawConfig,
- get_num_vcpus(config.cpuTopology, Some(config.customVcpuCount)),
+ get_num_vcpus(&config.cpuOptions),
config.memoryMib,
String::new(),
),
diff --git a/android/virtmgr/src/crosvm.rs b/android/virtmgr/src/crosvm.rs
index 00858cb..bb7712e 100644
--- a/android/virtmgr/src/crosvm.rs
+++ b/android/virtmgr/src/crosvm.rs
@@ -47,6 +47,8 @@
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
VirtualMachineAppConfig::DebugLevel::DebugLevel,
AudioConfig::AudioConfig as AudioConfigParcelable,
+ CpuOptions::CpuOptions,
+ CpuOptions::CpuTopology::CpuTopology,
DisplayConfig::DisplayConfig as DisplayConfigParcelable,
GpuConfig::GpuConfig as GpuConfigParcelable,
UsbConfig::UsbConfig as UsbConfigParcelable,
@@ -113,8 +115,7 @@
pub debug_config: DebugConfig,
pub memory_mib: NonZeroU32,
pub swiotlb_mib: Option<NonZeroU32>,
- pub cpus: Option<NonZeroU32>,
- pub host_cpu_topology: bool,
+ pub cpus: CpuOptions,
pub console_out_fd: Option<File>,
pub console_in_fd: Option<File>,
pub log_fd: Option<File>,
@@ -1109,30 +1110,31 @@
command.arg("--mem").arg(memory_mib.to_string());
- if let Some(cpus) = config.cpus {
+ fn cpu_arg_command(command: &mut Command, count: usize) {
#[cfg(target_arch = "aarch64")]
- command.arg("--cpus").arg(cpus.to_string() + ",sve=[auto=true]");
+ command.arg("--cpus").arg(count.to_string() + ",sve=[auto=true]");
#[cfg(not(target_arch = "aarch64"))]
- command.arg("--cpus").arg(cpus.to_string());
+ command.arg("--cpus").arg(count.to_string());
}
-
- if config.host_cpu_topology {
- if cfg!(virt_cpufreq) && check_if_all_cpus_allowed()? {
- command.arg("--host-cpu-topology");
- cfg_if::cfg_if! {
- if #[cfg(any(target_arch = "aarch64"))] {
+ match config.cpus.cpuTopology {
+ CpuTopology::MatchHost(_) => {
+ if cfg!(virt_cpufreq) && check_if_all_cpus_allowed()? {
+ command.arg("--host-cpu-topology");
+ #[cfg(target_arch = "aarch64")]
+ {
command.arg("--virt-cpufreq");
+ command.arg("--cpus").arg("sve=[auto=true]");
}
+ } else {
+ cpu_arg_command(
+ &mut command,
+ get_num_cpus()
+ .context("Could not determine the number of CPUs in the system")?,
+ )
}
- #[cfg(target_arch = "aarch64")]
- command.arg("--cpus").arg("sve=[auto=true]");
- } else if let Some(cpus) = get_num_cpus() {
- #[cfg(target_arch = "aarch64")]
- command.arg("--cpus").arg(cpus.to_string() + ",sve=[auto=true]");
- #[cfg(not(target_arch = "aarch64"))]
- command.arg("--cpus").arg(cpus.to_string());
- } else {
- bail!("Could not determine the number of CPUs in the system");
+ }
+ CpuTopology::CpuCount(count) => {
+ cpu_arg_command(&mut command, count.try_into().context("invalid cpu count")?)
}
}
diff --git a/android/virtualizationservice/aidl/android/system/virtualizationservice/CpuTopology.aidl b/android/virtualizationservice/aidl/android/system/virtualizationservice/CpuOptions.aidl
similarity index 63%
rename from android/virtualizationservice/aidl/android/system/virtualizationservice/CpuTopology.aidl
rename to android/virtualizationservice/aidl/android/system/virtualizationservice/CpuOptions.aidl
index 31a33f4..ae5044f 100644
--- a/android/virtualizationservice/aidl/android/system/virtualizationservice/CpuTopology.aidl
+++ b/android/virtualizationservice/aidl/android/system/virtualizationservice/CpuOptions.aidl
@@ -15,13 +15,17 @@
*/
package android.system.virtualizationservice;
-/** The vCPU topology that will be generated for the VM. */
-@Backing(type="byte")
-enum CpuTopology {
- /** One vCPU */
- ONE_CPU = 0,
- /** Match physical CPU topology of the host. */
- MATCH_HOST = 1,
- /** Number of vCPUs specified in the config. */
- CUSTOM = 2,
+/** CPU options that will be used for the VM's Vcpus. */
+@RustDerive(Clone=true)
+parcelable CpuOptions {
+ @RustDerive(Clone=true, PartialEq=true)
+ union CpuTopology {
+ /** Number of Vcpus to boot the VM with. */
+ int cpuCount = 1;
+
+ /** Match host number of Vcpus to boot the VM with. */
+ boolean matchHost;
+ }
+
+ CpuTopology cpuTopology;
}
diff --git a/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl b/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
index 114a851..5193e21 100644
--- a/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
+++ b/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
@@ -15,7 +15,7 @@
*/
package android.system.virtualizationservice;
-import android.system.virtualizationservice.CpuTopology;
+import android.system.virtualizationservice.CpuOptions;
import android.system.virtualizationservice.VirtualMachinePayloadConfig;
/** Configuration for running an App in a VM */
@@ -93,8 +93,8 @@
*/
int memoryMib;
- /** The vCPU topology that will be generated for the VM. Default to 1 vCPU. */
- CpuTopology cpuTopology = CpuTopology.ONE_CPU;
+ /** The vCPU options that will be generated for the VM. */
+ CpuOptions cpuOptions;
/**
* Encapsulates parameters that require android.permission.USE_CUSTOM_VIRTUAL_MACHINE.
diff --git a/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl b/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
index b6eff64..a822423 100644
--- a/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
+++ b/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
@@ -17,7 +17,7 @@
import android.system.virtualizationservice.AssignedDevices;
import android.system.virtualizationservice.AudioConfig;
-import android.system.virtualizationservice.CpuTopology;
+import android.system.virtualizationservice.CpuOptions;
import android.system.virtualizationservice.DiskImage;
import android.system.virtualizationservice.DisplayConfig;
import android.system.virtualizationservice.GpuConfig;
@@ -66,11 +66,8 @@
/** The amount of swiotlb to give the VM, in MiB. 0 or negative to use the default. */
int swiotlbMib;
- /** The vCPU topology that will be generated for the VM. Default to 1 vCPU. */
- CpuTopology cpuTopology = CpuTopology.ONE_CPU;
-
- /** The number of vCPUs. Ignored unless `cpuTopology == CUSTOM`. */
- int customVcpuCount;
+ /** The vCPU options that will be generated for the VM. */
+ CpuOptions cpuOptions;
/**
* A version or range of versions of the virtual platform that this config is compatible with.
diff --git a/android/vm/src/main.rs b/android/vm/src/main.rs
index 830d56c..ff846a1 100644
--- a/android/vm/src/main.rs
+++ b/android/vm/src/main.rs
@@ -19,7 +19,7 @@
mod run;
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
- CpuTopology::CpuTopology, IVirtualizationService::IVirtualizationService,
+ CpuOptions::CpuTopology::CpuTopology, IVirtualizationService::IVirtualizationService,
PartitionType::PartitionType, VirtualMachineAppConfig::DebugLevel::DebugLevel,
};
#[cfg(not(llpvm_changes))]
@@ -379,8 +379,13 @@
fn parse_cpu_topology(s: &str) -> Result<CpuTopology, String> {
match s {
- "one_cpu" => Ok(CpuTopology::ONE_CPU),
- "match_host" => Ok(CpuTopology::MATCH_HOST),
+ "one_cpu" => Ok(CpuTopology::CpuCount(1)),
+ "match_host" => Ok(CpuTopology::MatchHost(true)),
+ _ if s.starts_with("cpu_count=") => {
+ // Safe to unwrap as it's validated the string starts with cpu_count=
+ let val = s.strip_prefix("cpu_count=").unwrap();
+ Ok(CpuTopology::CpuCount(val.parse().map_err(|e| format!("Invalid CPU Count: {}", e))?))
+ }
_ => Err(format!("Invalid cpu topology {}", s)),
}
}
diff --git a/android/vm/src/run.rs b/android/vm/src/run.rs
index 0037327..eaf2522 100644
--- a/android/vm/src/run.rs
+++ b/android/vm/src/run.rs
@@ -17,6 +17,7 @@
use crate::create_partition::command_create_partition;
use crate::{get_service, RunAppConfig, RunCustomVmConfig, RunMicrodroidConfig};
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
+ CpuOptions::CpuOptions,
IVirtualizationService::IVirtualizationService,
PartitionType::PartitionType,
VirtualMachineAppConfig::{
@@ -160,6 +161,7 @@
..Default::default()
};
+ let cpu_options = CpuOptions { cpuTopology: config.common.cpu_topology };
if config.debug.enable_earlycon() {
if config.debug.debug != DebugLevel::FULL {
bail!("earlycon is only supported for debuggable VMs")
@@ -188,7 +190,7 @@
debugLevel: config.debug.debug,
protectedVm: config.common.protected,
memoryMib: config.common.mem.unwrap_or(0) as i32, // 0 means use the VM default
- cpuTopology: config.common.cpu_topology,
+ cpuOptions: cpu_options,
customConfig: Some(custom_config),
osName: os_name.to_string(),
hugePages: config.common.hugepages,
@@ -273,7 +275,7 @@
if let Some(gdb) = config.debug.gdb {
vm_config.gdbPort = gdb.get() as i32;
}
- vm_config.cpuTopology = config.common.cpu_topology;
+ vm_config.cpuOptions = CpuOptions { cpuTopology: config.common.cpu_topology.clone() };
vm_config.hugePages = config.common.hugepages;
vm_config.boostUclamp = config.common.boost_uclamp;
vm_config.teeServices = config.common.tee_services().to_vec();