Merge "Add early_virtmgr support to libvmclient" into main
diff --git a/android/virtmgr/Android.bp b/android/virtmgr/Android.bp
index 0148ff6..d0d7915 100644
--- a/android/virtmgr/Android.bp
+++ b/android/virtmgr/Android.bp
@@ -34,7 +34,6 @@
         "libapkverify",
         "libavf_features",
         "libavflog",
-        "libbase_rust",
         "libbinder_rs",
         "libcfg_if",
         "libclap",
diff --git a/android/virtmgr/src/crosvm.rs b/android/virtmgr/src/crosvm.rs
index 0f41932..b2be736 100644
--- a/android/virtmgr/src/crosvm.rs
+++ b/android/virtmgr/src/crosvm.rs
@@ -57,7 +57,6 @@
 use rpcbinder::RpcServer;
 
 /// external/crosvm
-use base::UnixSeqpacketListener;
 use vm_control::{BalloonControlCommand, VmRequest, VmResponse};
 
 const CROSVM_PATH: &str = "/apex/com.android.virt/bin/crosvm";
@@ -1057,8 +1056,8 @@
         command.arg(add_preserved_fd(&mut preserved_fds, kernel));
     }
 
-    let control_sock = UnixSeqpacketListener::bind(crosvm_control_socket_path)
-        .context("failed to create control server")?;
+    let control_sock = create_crosvm_control_listener(crosvm_control_socket_path)
+        .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 {
@@ -1272,3 +1271,22 @@
     let (read_fd, write_fd) = pipe2(OFlag::O_CLOEXEC)?;
     Ok((read_fd.into(), write_fd.into()))
 }
+
+/// Creates and binds a unix seqpacket listening socket to be passed as crosvm's `--socket`
+/// argument. See `UnixSeqpacketListener::bind` in crosvm's code for reference.
+fn create_crosvm_control_listener(crosvm_control_socket_path: &Path) -> Result<OwnedFd> {
+    use nix::sys::socket;
+    let fd = socket::socket(
+        socket::AddressFamily::Unix,
+        socket::SockType::SeqPacket,
+        socket::SockFlag::empty(),
+        None,
+    )
+    .context("socket failed")?;
+    socket::bind(fd.as_raw_fd(), &socket::UnixAddr::new(crosvm_control_socket_path)?)
+        .context("bind failed")?;
+    // The exact backlog size isn't imporant. crosvm uses 128 internally. We use 127 here
+    // because of a `nix` bug.
+    socket::listen(&fd, socket::Backlog::new(127).unwrap()).context("listen failed")?;
+    Ok(fd)
+}
diff --git a/build/apex/Android.bp b/build/apex/Android.bp
index f493202..be62d18 100644
--- a/build/apex/Android.bp
+++ b/build/apex/Android.bp
@@ -107,6 +107,7 @@
             filesystems: microdroid_filesystem_images,
             prebuilts: [
                 "rialto_bin",
+                "android_bootloader_crosvm_aarch64",
             ],
         },
         x86_64: {
@@ -125,6 +126,9 @@
                 default: [],
             }),
             filesystems: microdroid_filesystem_images,
+            prebuilts: [
+                "android_bootloader_crosvm_x86_64",
+            ],
         },
     },
     binaries: [
@@ -138,7 +142,6 @@
         "microdroid.json",
         "microdroid_kernel",
         "com.android.virt.init.rc",
-        "android_bootloader_crosvm_aarch64",
     ] + select(soong_config_variable("ANDROID", "avf_microdroid_guest_gki_version"), {
         "android15_66": [
             "microdroid_gki-android15-6.6_initrd_debuggable",
diff --git a/docs/device_assignment.md b/docs/device_assignment.md
index 4b2296c..6011d8f 100644
--- a/docs/device_assignment.md
+++ b/docs/device_assignment.md
@@ -205,6 +205,18 @@
 * `<sysfs_path>`: Sysfs path of the device in host, used to bind to the VFIO
   driver. Must be non-empty and unique in the XML.
 
+### List support assignable devices
+
+In order to query list of the devices that can be assigned to a pVM, run the
+following command:
+
+```bash
+adb shell /apex/com.android.virt/bin/vm info
+```
+
+All supported assignable devices will be located under the "Assignable devices:"
+section of the output.
+
 ## Boot with VM DTBO
 
 Bootloader should provide VM DTBO to both Android and pvmfw.
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java
index cb21ccf..de1b081 100644
--- a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -78,7 +78,8 @@
     private static final String TAG = "VirtualMachineConfig";
 
     private static String[] EMPTY_STRING_ARRAY = {};
-    private static final String U_BOOT_PREBUILT_PATH = "/apex/com.android.virt/etc/u-boot.bin";
+    private static final String U_BOOT_PREBUILT_PATH_ARM = "/apex/com.android.virt/etc/u-boot.bin";
+    private static final String U_BOOT_PREBUILT_PATH_X86 = "/apex/com.android.virt/etc/u-boot.rom";
 
     // These define the schema of the config file persisted on disk.
     // Please bump up the version number when adding a new key.
@@ -668,7 +669,11 @@
                         .orElse(null);
 
         if (config.kernel == null && config.bootloader == null) {
-            config.bootloader = openOrNull(new File(U_BOOT_PREBUILT_PATH), MODE_READ_ONLY);
+          if (Arrays.stream(Build.SUPPORTED_ABIS).anyMatch("x86_64"::equals)) {
+            config.bootloader = openOrNull(new File(U_BOOT_PREBUILT_PATH_X86), MODE_READ_ONLY);
+          } else {
+            config.bootloader = openOrNull(new File(U_BOOT_PREBUILT_PATH_ARM), MODE_READ_ONLY);
+          }
         }
 
         config.params =