[pvmfw] Move memory flush functions to vmbase

To facilitate reusing the memory management code in rialto later.

Bug: 284462758
Test: m pvmfw_img
Change-Id: I9a544c783ff322d4894f0b3d7e10c0643908d48f
diff --git a/vmbase/src/memory/dbm.rs b/vmbase/src/memory/dbm.rs
index 3a52c2d..235c0e0 100644
--- a/vmbase/src/memory/dbm.rs
+++ b/vmbase/src/memory/dbm.rs
@@ -14,7 +14,10 @@
 
 //! Hardware management of the access flag and dirty state.
 
+use super::page_table::is_leaf_pte;
+use super::util::flush_region;
 use crate::{isb, read_sysreg, write_sysreg};
+use aarch64_paging::paging::{Attributes, Descriptor, MemoryRegion};
 
 /// Sets whether the hardware management of access and dirty state is enabled with
 /// the given boolean.
@@ -45,3 +48,23 @@
     const DBM_AVAILABLE: usize = 1 << 1;
     read_sysreg!("id_aa64mmfr1_el1") & DBM_AVAILABLE != 0
 }
+
+/// Flushes a memory range the descriptor refers to, if the descriptor is in writable-dirty state.
+/// As the return type is required by the crate `aarch64_paging`, we cannot address the lint
+/// issue `clippy::result_unit_err`.
+#[allow(clippy::result_unit_err)]
+pub fn flush_dirty_range(
+    va_range: &MemoryRegion,
+    desc: &mut Descriptor,
+    level: usize,
+) -> Result<(), ()> {
+    // Only flush ranges corresponding to dirty leaf PTEs.
+    let flags = desc.flags().ok_or(())?;
+    if !is_leaf_pte(&flags, level) {
+        return Ok(());
+    }
+    if !flags.contains(Attributes::READ_ONLY) {
+        flush_region(va_range.start().0, va_range.len());
+    }
+    Ok(())
+}