Merge "Refine CrosvmConfig balloon filed setting logic" into main am: 4ca58d12c6

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Virtualization/+/3513190

Change-Id: I30f3a2742583797da4c40d4e8b4eb4125dd1d540
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index 44385e2..1c4c2eb 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -935,6 +935,20 @@
             })
             .collect::<binder::Result<_>>()?;
 
+        let memory_reclaim_supported =
+            system_properties::read_bool("hypervisor.memory_reclaim.supported", false)
+                .unwrap_or(false);
+
+        let balloon = config.balloon && memory_reclaim_supported;
+
+        if !balloon {
+            warn!(
+                "Memory balloon not enabled:
+                config.balloon={},hypervisor.memory_reclaim.supported={}",
+                config.balloon, memory_reclaim_supported
+            );
+        }
+
         // Actually start the VM.
         let crosvm_config = CrosvmConfig {
             cid,
@@ -974,7 +988,7 @@
             boost_uclamp: config.boostUclamp,
             gpu_config,
             audio_config,
-            balloon: config.balloon,
+            balloon,
             usb_config,
             dump_dt_fd,
             enable_hypervisor_specific_auth_method: config.enableHypervisorSpecificAuthMethod,
@@ -1733,6 +1747,10 @@
             .or_service_specific_exception(-1)
     }
 
+    fn isMemoryBalloonEnabled(&self) -> binder::Result<bool> {
+        Ok(self.instance.balloon_enabled)
+    }
+
     fn getMemoryBalloon(&self) -> binder::Result<i64> {
         let balloon = self
             .instance
diff --git a/android/virtmgr/src/crosvm.rs b/android/virtmgr/src/crosvm.rs
index 77710c3..5f81e90 100644
--- a/android/virtmgr/src/crosvm.rs
+++ b/android/virtmgr/src/crosvm.rs
@@ -417,6 +417,8 @@
     pub vm_service: Mutex<Option<Strong<dyn IVirtualMachineService>>>,
     /// Recorded metrics of VM such as timestamp or cpu / memory usage.
     pub vm_metric: Mutex<VmMetric>,
+    // Whether virtio-balloon is enabled
+    pub balloon_enabled: bool,
     /// The latest lifecycle state which the payload reported itself to be in.
     payload_state: Mutex<PayloadState>,
     /// Represents the condition that payload_state was updated
@@ -449,6 +451,7 @@
         let cid = config.cid;
         let name = config.name.clone();
         let protected = config.protected;
+        let balloon_enabled = config.balloon;
         let requester_uid_name = User::from_uid(Uid::from_raw(requester_uid))
             .ok()
             .flatten()
@@ -469,6 +472,7 @@
             payload_state: Mutex::new(PayloadState::Starting),
             payload_state_updated: Condvar::new(),
             requester_uid_name,
+            balloon_enabled,
         };
         info!("{} created", &instance);
         Ok(instance)
@@ -722,6 +726,9 @@
 
     /// Returns current virtio-balloon size.
     pub fn get_memory_balloon(&self) -> Result<u64, Error> {
+        if !self.balloon_enabled {
+            bail!("virtio-balloon is not enabled");
+        }
         let socket_path_cstring = path_to_cstring(&self.crosvm_control_socket_path);
         let mut balloon_actual = 0u64;
         // SAFETY: Pointers are valid for the lifetime of the call. Null `stats` is valid.
@@ -741,6 +748,9 @@
     /// Inflates the virtio-balloon by `num_bytes` to reclaim guest memory. Called in response to
     /// memory-trimming notifications.
     pub fn set_memory_balloon(&self, num_bytes: u64) -> Result<(), Error> {
+        if !self.balloon_enabled {
+            bail!("virtio-balloon is not enabled");
+        }
         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 {
@@ -1038,8 +1048,7 @@
         .arg("--cid")
         .arg(config.cid.to_string());
 
-    if system_properties::read_bool("hypervisor.memory_reclaim.supported", false)? && config.balloon
-    {
+    if config.balloon {
         command.arg("--balloon-page-reporting");
     } else {
         command.arg("--no-balloon");
diff --git a/android/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachine.aidl b/android/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachine.aidl
index a01d385..e7aeefd 100644
--- a/android/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachine.aidl
+++ b/android/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachine.aidl
@@ -49,6 +49,7 @@
     void stop();
 
     /** Access to the VM's memory balloon. */
+    boolean isMemoryBalloonEnabled();
     long getMemoryBalloon();
     void setMemoryBalloon(long num_bytes);