pvmfw: Move MemoryTracker to a global variable

Exception handlers that maniplulate memory need access to MemoryTracker. To
prepare for the implementation of such handlers, move the MemoryTracker
into a global variable, and wrap it with a SpinMutex.

Bug: 245267332
Test: atest MicrodroidTestApp

Change-Id: Ib5b16006e25addca991c6c6d7854c9368d60a28b
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index 8be5f7d..2416714 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -31,6 +31,7 @@
         "libvirtio_drivers",
         "libvmbase",
         "libzeroize_nostd",
+        "libspin_nostd",
     ],
 }
 
diff --git a/pvmfw/src/entry.rs b/pvmfw/src/entry.rs
index 1309d73..5dd1d2d 100644
--- a/pvmfw/src/entry.rs
+++ b/pvmfw/src/entry.rs
@@ -19,7 +19,7 @@
 use crate::fdt;
 use crate::heap;
 use crate::helpers;
-use crate::memory::MemoryTracker;
+use crate::memory::{MemoryTracker, MEMORY};
 use crate::mmu;
 use crate::rand;
 use core::arch::asm;
@@ -217,8 +217,8 @@
     unsafe { page_table.activate() };
     debug!("... Success!");
 
-    let mut memory = MemoryTracker::new(page_table);
-    let slices = MemorySlices::new(fdt, payload, payload_size, &mut memory)?;
+    MEMORY.lock().replace(MemoryTracker::new(page_table));
+    let slices = MemorySlices::new(fdt, payload, payload_size, MEMORY.lock().as_mut().unwrap())?;
 
     rand::init().map_err(|e| {
         error!("Failed to initialize rand: {e}");
@@ -226,13 +226,20 @@
     })?;
 
     // This wrapper allows main() to be blissfully ignorant of platform details.
-    crate::main(slices.fdt, slices.kernel, slices.ramdisk, bcc_slice, debug_policy, &mut memory)?;
+    crate::main(
+        slices.fdt,
+        slices.kernel,
+        slices.ramdisk,
+        bcc_slice,
+        debug_policy,
+        MEMORY.lock().as_mut().unwrap(),
+    )?;
 
     helpers::flushed_zeroize(bcc_slice);
     helpers::flush(slices.fdt.as_slice());
 
     info!("Expecting a bug making MMIO_GUARD_UNMAP return NOT_SUPPORTED on success");
-    memory.mmio_unmap_all().map_err(|e| {
+    MEMORY.lock().as_mut().unwrap().mmio_unmap_all().map_err(|e| {
         error!("Failed to unshare MMIO ranges: {e}");
         RebootReason::InternalError
     })?;
@@ -240,6 +247,7 @@
         error!("Failed to unshare the UART: {e}");
         RebootReason::InternalError
     })?;
+    MEMORY.lock().take().unwrap();
 
     Ok(slices.kernel.as_ptr() as usize)
 }
diff --git a/pvmfw/src/memory.rs b/pvmfw/src/memory.rs
index 2d5eb5c..d90808b 100644
--- a/pvmfw/src/memory.rs
+++ b/pvmfw/src/memory.rs
@@ -31,6 +31,7 @@
 use core::result;
 use hyp::get_hypervisor;
 use log::error;
+use spin::mutex::SpinMutex;
 use tinyvec::ArrayVec;
 
 /// Base of the system's contiguous "main" memory.
@@ -40,6 +41,9 @@
 
 pub type MemoryRange = Range<usize>;
 
+pub static MEMORY: SpinMutex<Option<MemoryTracker>> = SpinMutex::new(None);
+unsafe impl Send for MemoryTracker {}
+
 #[derive(Clone, Copy, Debug, Default)]
 enum MemoryType {
     #[default]