libavf: add API to configure swiotlb size

Test: TH
Bug: 382781129
Change-Id: I1b22a8e3fd6e3800f29c81cadbc47ba8c2e21b3b
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index 15a80a6..6a268f9 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -774,6 +774,7 @@
                 .ok()
                 .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,
             console_out_fd,
diff --git a/android/virtmgr/src/crosvm.rs b/android/virtmgr/src/crosvm.rs
index 2bfa4e1..affd430 100644
--- a/android/virtmgr/src/crosvm.rs
+++ b/android/virtmgr/src/crosvm.rs
@@ -112,6 +112,7 @@
     pub protected: bool,
     pub debug_config: DebugConfig,
     pub memory_mib: NonZeroU32,
+    pub swiotlb_mib: Option<NonZeroU32>,
     pub cpus: Option<NonZeroU32>,
     pub host_cpu_topology: bool,
     pub console_out_fd: Option<File>,
@@ -1000,11 +1001,18 @@
             _ => command.arg("--protected-vm"),
         };
 
-        // 3 virtio-console devices + vsock = 4.
-        let virtio_pci_device_count = 4 + config.disks.len();
-        // crosvm virtio queue has 256 entries, so 2 MiB per device (2 pages per entry) should be
-        // enough.
-        let swiotlb_size_mib = 2 * virtio_pci_device_count as u32;
+        let swiotlb_size_mib = config.swiotlb_mib.map(u32::from).unwrap_or({
+            // 3 virtio-console devices + vsock = 4.
+            // TODO: Count more device types, like balloon, input, and sound.
+            let virtio_pci_device_count = 4 + config.disks.len();
+            // crosvm virtio queue has 256 entries, so 2 MiB per device (2 pages per entry) should
+            // be enough.
+            // NOTE: The above explanation isn't completely accurate, e.g., circa 2024q4, each
+            // virtio-block has 16 queues with 256 entries each and each virito-console has 2
+            // queues of 256 entries each. So, it is allocating less than 2 pages per entry, but
+            // seems to work well enough in practice.
+            2 * virtio_pci_device_count as u32
+        });
         command.arg("--swiotlb").arg(swiotlb_size_mib.to_string());
 
         // b/346770542 for consistent "usable" memory across protected and non-protected VMs.