[pvmfw][vmbase] Move page table update functions to vmbase
to simplify the task of moving MemoryTracker to vmbase for reuse
in both rialto and pvmfw.
Bug: 284462758
Test: m pvmfw_img
Change-Id: Ic4c912caf0d5526cfe70eac2bfbfcf62ec45dacf
diff --git a/vmbase/src/memory/dbm.rs b/vmbase/src/memory/dbm.rs
index 235c0e0..333d3f6 100644
--- a/vmbase/src/memory/dbm.rs
+++ b/vmbase/src/memory/dbm.rs
@@ -14,9 +14,9 @@
//! Hardware management of the access flag and dirty state.
-use super::page_table::is_leaf_pte;
+use super::page_table::{is_leaf_pte, PT_ASID};
use super::util::flush_region;
-use crate::{isb, read_sysreg, write_sysreg};
+use crate::{dsb, isb, read_sysreg, tlbi, write_sysreg};
use aarch64_paging::paging::{Attributes, Descriptor, MemoryRegion};
/// Sets whether the hardware management of access and dirty state is enabled with
@@ -68,3 +68,34 @@
}
Ok(())
}
+
+/// Clears read-only flag on a PTE, making it writable-dirty. Used when dirty state is managed
+/// in software to handle permission faults on read-only descriptors.
+/// 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 mark_dirty_block(
+ va_range: &MemoryRegion,
+ desc: &mut Descriptor,
+ level: usize,
+) -> Result<(), ()> {
+ let flags = desc.flags().ok_or(())?;
+ if !is_leaf_pte(&flags, level) {
+ return Ok(());
+ }
+ if flags.contains(Attributes::DBM) {
+ assert!(flags.contains(Attributes::READ_ONLY), "unexpected PTE writable state");
+ desc.modify_flags(Attributes::empty(), Attributes::READ_ONLY);
+ // Updating the read-only bit of a PTE requires TLB invalidation.
+ // A TLB maintenance instruction is only guaranteed to be complete after a DSB instruction.
+ // An ISB instruction is required to ensure the effects of completed TLB maintenance
+ // instructions are visible to instructions fetched afterwards.
+ // See ARM ARM E2.3.10, and G5.9.
+ tlbi!("vale1", PT_ASID, va_range.start().0);
+ dsb!("ish");
+ isb!();
+ Ok(())
+ } else {
+ Err(())
+ }
+}