Merge changes I1f98c2ce,Id047977a

* changes:
  Update kernel to builds 10298368
  Update kernel to builds 10298368
diff --git a/apkdmverity/src/main.rs b/apkdmverity/src/main.rs
index 506af48..55953a9 100644
--- a/apkdmverity/src/main.rs
+++ b/apkdmverity/src/main.rs
@@ -153,28 +153,17 @@
 }
 
 #[cfg(test)]
-ignorabletest::test_main!(tests::all_tests());
+ignorabletest::test_main!();
 
 #[cfg(test)]
 mod tests {
     use crate::*;
-    use ignorabletest::{list_tests, test};
+    use ignorabletest::test;
     use std::fs::{File, OpenOptions};
     use std::io::Write;
     use std::ops::Deref;
     use std::os::unix::fs::FileExt;
 
-    list_tests! {all_tests: [
-        correct_inputs,
-        incorrect_apk,
-        incorrect_merkle_tree,
-        tampered_apk,
-        tampered_idsig,
-        inputs_are_block_devices,
-        correct_custom_roothash,
-        verify_command,
-    ]}
-
     struct TestContext<'a> {
         data_backing_file: &'a Path,
         hash_backing_file: &'a Path,
diff --git a/libs/devicemapper/src/lib.rs b/libs/devicemapper/src/lib.rs
index 1b18b49..0170795 100644
--- a/libs/devicemapper/src/lib.rs
+++ b/libs/devicemapper/src/lib.rs
@@ -233,13 +233,13 @@
 }
 
 #[cfg(test)]
-ignorabletest::test_main!(tests::all_tests());
+ignorabletest::test_main!();
 
 #[cfg(test)]
 mod tests {
     use super::*;
     use crypt::{CipherType, DmCryptTargetBuilder};
-    use ignorabletest::{list_tests, test};
+    use ignorabletest::test;
     use rustutils::system_properties;
     use std::fs::{read, File, OpenOptions};
     use std::io::Write;
@@ -262,13 +262,6 @@
         different_key: b"drowgnolyllaergnolsetybowtytriht",
     };
 
-    list_tests! {all_tests: [
-        mapping_again_keeps_data_xts,
-        mapping_again_keeps_data_hctr2,
-        data_inaccessible_with_diff_key_xts,
-        data_inaccessible_with_diff_key_hctr2,
-    ]}
-
     // Create a file in given temp directory with given size
     fn prepare_tmpfile(test_dir: &Path, filename: &str, sz: u64) -> PathBuf {
         let filepath = test_dir.join(filename);
diff --git a/libs/ignorabletest/Android.bp b/libs/ignorabletest/Android.bp
index 0947243..10aef8e 100644
--- a/libs/ignorabletest/Android.bp
+++ b/libs/ignorabletest/Android.bp
@@ -8,6 +8,7 @@
     edition: "2021",
     rustlibs: [
         "liblibtest_mimic",
+        "liblinkme",
     ],
     proc_macros: ["libpaste"],
     apex_available: [
@@ -22,5 +23,12 @@
     cfgs: ["test"],
     rustlibs: [
         "libignorabletest",
+        "liblinkme",
+    ],
+    // Without this flag we get linker errors saying to add it. See
+    // https://github.com/dtolnay/linkme/issues/49 and related issues.
+    ld_flags: [
+        "-z",
+        "nostart-stop-gc",
     ],
 }
diff --git a/libs/ignorabletest/README.md b/libs/ignorabletest/README.md
index e03864f..77140bd 100644
--- a/libs/ignorabletest/README.md
+++ b/libs/ignorabletest/README.md
@@ -56,23 +56,11 @@
 ```
 
 Somewhere in your main module, you need to use the `test_main` macro to generate an entry point for
-the test harness. This needs to be provided with a list of all tests, which can be generated by the `list_tests!` macro:
+the test harness:
 
 ```rust
 #[cfg(test)]
-ignorabletest::test_main!(tests::all_tests());
-
-#[cfg(test)]
-mod tests {
-    use ignorabletest::{list_tests, test};
-
-    list_tests! {all_tests: [
-        one_plus_one,
-        clap_hands,
-    ]}
-
-    // ...
-}
+ignorabletest::test_main!();
 ```
 
 You can then run your tests as usual with `atest`.
diff --git a/libs/ignorabletest/src/lib.rs b/libs/ignorabletest/src/lib.rs
index 746c0dd..c7243e6 100644
--- a/libs/ignorabletest/src/lib.rs
+++ b/libs/ignorabletest/src/lib.rs
@@ -5,42 +5,17 @@
 #[doc(hidden)]
 pub use libtest_mimic as _libtest_mimic;
 #[doc(hidden)]
+pub use linkme as _linkme;
+#[doc(hidden)]
 pub use paste as _paste;
 
 /// Macro to generate the main function for the test harness.
 #[macro_export]
 macro_rules! test_main {
-    ($tests:expr) => {
+    () => {
         #[cfg(test)]
         fn main() {
-            ignorabletest::runner::main($tests)
-        }
-    };
-}
-
-/// Macro to generate a function which returns a list of tests to be run.
-///
-/// # Usage
-/// ```
-/// list_tests!{all_tests: [test_this, test_that]};
-///
-/// test!(test_this);
-/// fn test_this() {
-///   // ...
-/// }
-///
-/// test!(test_that);
-/// fn test_that() {
-///   // ...
-/// }
-/// ```
-#[macro_export]
-macro_rules! list_tests {
-    {$function_name:ident: [$( $test_name:ident ),* $(,)? ]} => {
-        pub fn $function_name() -> ::std::vec::Vec<$crate::_libtest_mimic::Trial> {
-            vec![
-                $( $crate::_paste::paste!([<__test_ $test_name>]()) ),*
-            ]
+            ignorabletest::runner::main()
         }
     };
 }
@@ -59,6 +34,7 @@
 macro_rules! test {
     ($test_name:ident) => {
         $crate::_paste::paste!(
+            #[$crate::_linkme::distributed_slice($crate::runner::IGNORABLETEST_TESTS)]
             fn [< __test_ $test_name >]() -> $crate::_libtest_mimic::Trial {
                 $crate::_libtest_mimic::Trial::test(
                     ::std::stringify!($test_name),
@@ -69,6 +45,7 @@
     };
     ($test_name:ident, ignore_if: $ignore_expr:expr) => {
         $crate::_paste::paste!(
+            #[$crate::_linkme::distributed_slice($crate::runner::IGNORABLETEST_TESTS)]
             fn [< __test_ $test_name >]() -> $crate::_libtest_mimic::Trial {
                 $crate::_libtest_mimic::Trial::test(
                     ::std::stringify!($test_name),
diff --git a/libs/ignorabletest/src/runner.rs b/libs/ignorabletest/src/runner.rs
index e1b14e0..4ec3d79 100644
--- a/libs/ignorabletest/src/runner.rs
+++ b/libs/ignorabletest/src/runner.rs
@@ -2,14 +2,21 @@
 
 use core::ops::{Deref, FnOnce};
 use libtest_mimic::{Arguments, Failed, Trial};
+use linkme::distributed_slice;
 use std::env;
 
 /// Command-line arguments to ignore, because they are not supported by libtest-mimic.
 const IGNORED_ARGS: [&str; 2] = ["-Zunstable-options", "--report-time"];
 
+/// The collection of all tests to run.
+#[doc(hidden)]
+#[distributed_slice]
+pub static IGNORABLETEST_TESTS: [fn() -> Trial] = [..];
+
 /// Runs all tests.
-pub fn main(tests: Vec<Trial>) {
+pub fn main() {
     let args = Arguments::from_iter(env::args().filter(|arg| !IGNORED_ARGS.contains(&arg.deref())));
+    let tests = IGNORABLETEST_TESTS.iter().map(|test| test()).collect();
     libtest_mimic::run(&args, tests).exit();
 }
 
diff --git a/pvmfw/src/gpt.rs b/pvmfw/src/gpt.rs
index e0ffdc3..b553705 100644
--- a/pvmfw/src/gpt.rs
+++ b/pvmfw/src/gpt.rs
@@ -14,7 +14,6 @@
 
 //! Support for parsing GUID partition tables.
 
-use crate::virtio::pci::VirtIOBlk;
 use core::cmp::min;
 use core::fmt;
 use core::mem::size_of;
@@ -25,6 +24,7 @@
 use uuid::Uuid;
 use virtio_drivers::device::blk::SECTOR_SIZE;
 use vmbase::util::ceiling_div;
+use vmbase::virtio::pci::VirtIOBlk;
 use zerocopy::FromBytes;
 
 pub enum Error {
diff --git a/pvmfw/src/instance.rs b/pvmfw/src/instance.rs
index 9a6a6e4..b96ae1e 100644
--- a/pvmfw/src/instance.rs
+++ b/pvmfw/src/instance.rs
@@ -22,7 +22,6 @@
 use crate::gpt::Partition;
 use crate::gpt::Partitions;
 use crate::rand;
-use crate::virtio::pci::VirtIOBlkIterator;
 use core::fmt;
 use core::mem::size_of;
 use diced_open_dice::DiceMode;
@@ -32,6 +31,7 @@
 use uuid::Uuid;
 use virtio_drivers::transport::pci::bus::PciRoot;
 use vmbase::util::ceiling_div;
+use vmbase::virtio::pci::VirtIOBlkIterator;
 use zerocopy::AsBytes;
 use zerocopy::FromBytes;
 
diff --git a/pvmfw/src/main.rs b/pvmfw/src/main.rs
index c6baf6d..c826cd8 100644
--- a/pvmfw/src/main.rs
+++ b/pvmfw/src/main.rs
@@ -34,7 +34,6 @@
 mod instance;
 mod memory;
 mod rand;
-mod virtio;
 
 use crate::bcc::Bcc;
 use crate::dice::PartialInputs;
@@ -42,7 +41,6 @@
 use crate::fdt::modify_for_next_stage;
 use crate::helpers::GUEST_PAGE_SIZE;
 use crate::instance::get_or_generate_instance_salt;
-use crate::virtio::pci;
 use alloc::boxed::Box;
 use core::ops::Range;
 use diced_open_dice::{bcc_handover_parse, DiceArtifacts};
@@ -55,6 +53,7 @@
 use pvmfw_embedded_key::PUBLIC_KEY;
 use vmbase::memory::flush;
 use vmbase::memory::MEMORY;
+use vmbase::virtio::pci;
 
 const NEXT_BCC_SIZE: usize = GUEST_PAGE_SIZE;
 
diff --git a/tests/benchmark/src/java/com/android/microdroid/benchmark/BenchmarkVmListener.java b/tests/benchmark/src/java/com/android/microdroid/benchmark/BenchmarkVmListener.java
index db1d021..e225a59 100644
--- a/tests/benchmark/src/java/com/android/microdroid/benchmark/BenchmarkVmListener.java
+++ b/tests/benchmark/src/java/com/android/microdroid/benchmark/BenchmarkVmListener.java
@@ -20,6 +20,7 @@
 
 import android.os.RemoteException;
 import android.system.virtualmachine.VirtualMachine;
+import android.system.virtualmachine.VirtualMachineException;
 import android.util.Log;
 
 import com.android.microdroid.test.device.MicrodroidDeviceTestBase.VmEventListener;
@@ -32,6 +33,8 @@
 class BenchmarkVmListener extends VmEventListener {
     private static final String TAG = "BenchmarkVm";
 
+    private boolean mPayloadReady;
+
     interface InnerListener {
         /** This is invoked when both the payload and {@link IBenchmarkService} are ready. */
         void onPayloadReady(VirtualMachine vm, IBenchmarkService benchmarkService)
@@ -46,6 +49,7 @@
 
     @Override
     public final void onPayloadReady(VirtualMachine vm) {
+        mPayloadReady = true;
         try {
             IBenchmarkService benchmarkService =
                     IBenchmarkService.Stub.asInterface(
@@ -60,7 +64,20 @@
         forceStop(vm);
     }
 
+    @Override
+    public void onError(VirtualMachine vm, int errorCode, String message) {
+        throw new RuntimeException("Error while benchmark (" + errorCode + "): " + message);
+    }
+
     static BenchmarkVmListener create(InnerListener listener) {
         return new BenchmarkVmListener(listener);
     }
+
+    @Override
+    public void runToFinish(String logTag, VirtualMachine vm)
+            throws VirtualMachineException, InterruptedException {
+        mPayloadReady = false;
+        super.runToFinish(logTag, vm);
+        assertThat(mPayloadReady).isTrue();
+    }
 }
diff --git a/vmbase/Android.bp b/vmbase/Android.bp
index 6420b2b..6db9ff8 100644
--- a/vmbase/Android.bp
+++ b/vmbase/Android.bp
@@ -65,12 +65,14 @@
     rustlibs: [
         "libaarch64_paging",
         "libbuddy_system_allocator",
+        "libfdtpci",
         "libhyp",
         "liblog_rust_nostd",
         "libonce_cell_nostd",
         "libsmccc",
         "libspin_nostd",
         "libtinyvec_nostd",
+        "libvirtio_drivers",
         "libzeroize_nostd",
     ],
     whole_static_libs: [
diff --git a/vmbase/src/lib.rs b/vmbase/src/lib.rs
index 80cdf4e..ebb3707 100644
--- a/vmbase/src/lib.rs
+++ b/vmbase/src/lib.rs
@@ -29,6 +29,7 @@
 pub mod power;
 pub mod uart;
 pub mod util;
+pub mod virtio;
 
 pub use bionic::STACK_CHK_GUARD;
 
diff --git a/pvmfw/src/virtio/hal.rs b/vmbase/src/virtio/hal.rs
similarity index 96%
rename from pvmfw/src/virtio/hal.rs
rename to vmbase/src/virtio/hal.rs
index f223a7e..ac5b967 100644
--- a/pvmfw/src/virtio/hal.rs
+++ b/vmbase/src/virtio/hal.rs
@@ -15,13 +15,13 @@
 //! HAL for the virtio_drivers crate.
 
 use super::pci::PCI_INFO;
+use crate::memory::{alloc_shared, dealloc_shared, phys_to_virt, virt_to_phys};
+use crate::util::RangeExt as _;
 use core::alloc::Layout;
 use core::mem::size_of;
 use core::ptr::{copy_nonoverlapping, NonNull};
 use log::trace;
 use virtio_drivers::{BufferDirection, Hal, PhysAddr, PAGE_SIZE};
-use vmbase::memory::{alloc_shared, dealloc_shared, phys_to_virt, virt_to_phys};
-use vmbase::util::RangeExt as _;
 
 /// The alignment to use for the temporary buffers allocated by `HalImpl::share`. There doesn't seem
 /// to be any particular alignment required by VirtIO for these, so 16 bytes should be enough to
@@ -29,6 +29,7 @@
 /// alignment to the memory sharing granule size anyway.
 const SHARED_BUFFER_ALIGNMENT: usize = size_of::<u128>();
 
+/// HAL implementation for the virtio_drivers crate.
 pub struct HalImpl;
 
 /// # Safety
diff --git a/pvmfw/src/virtio.rs b/vmbase/src/virtio/mod.rs
similarity index 100%
rename from pvmfw/src/virtio.rs
rename to vmbase/src/virtio/mod.rs
diff --git a/pvmfw/src/virtio/pci.rs b/vmbase/src/virtio/pci.rs
similarity index 96%
rename from pvmfw/src/virtio/pci.rs
rename to vmbase/src/virtio/pci.rs
index fd99c07..b54f7d1 100644
--- a/pvmfw/src/virtio/pci.rs
+++ b/vmbase/src/virtio/pci.rs
@@ -15,6 +15,7 @@
 //! Functions to scan the PCI bus for VirtIO devices.
 
 use super::hal::HalImpl;
+use crate::memory::{MemoryTracker, MemoryTrackerError};
 use alloc::boxed::Box;
 use core::fmt;
 use fdtpci::PciInfo;
@@ -30,7 +31,6 @@
         DeviceType, Transport,
     },
 };
-use vmbase::memory::{MemoryTracker, MemoryTrackerError};
 
 pub(super) static PCI_INFO: OnceBox<PciInfo> = OnceBox::new();
 
@@ -78,14 +78,17 @@
     Ok(unsafe { pci_info.make_pci_root() })
 }
 
+/// Virtio Block device.
 pub type VirtIOBlk = blk::VirtIOBlk<HalImpl, PciTransport>;
 
+/// Virtio Block device iterator.
 pub struct VirtIOBlkIterator<'a> {
     pci_root: &'a mut PciRoot,
     bus: BusDeviceIterator,
 }
 
 impl<'a> VirtIOBlkIterator<'a> {
+    /// Creates a new iterator.
     pub fn new(pci_root: &'a mut PciRoot) -> Self {
         let bus = pci_root.enumerate_bus(0);
         Self { pci_root, bus }