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")?)
         }
     }