pvmfw: Implement software dirty state handling
Flush only dirty pages when dropping RW memory regions. Implement
handling of dirty bit in software. Mark writable regions read-only
and make the pages writable-dirty when access causes a permission
fault.
Bug: 269738062
Test: atest MicrodroidTestApp
Change-Id: I2e73a7cc867bae8b68c2a3b68d382405327f99e8
diff --git a/pvmfw/src/exceptions.rs b/pvmfw/src/exceptions.rs
index 39641b0..e819729 100644
--- a/pvmfw/src/exceptions.rs
+++ b/pvmfw/src/exceptions.rs
@@ -89,15 +89,27 @@
}
}
+#[inline]
+fn handle_translation_fault(far: usize) -> Result<(), HandleExceptionError> {
+ let mut guard = MEMORY.try_lock().ok_or(HandleExceptionError::PageTableUnavailable)?;
+ let memory = guard.as_mut().ok_or(HandleExceptionError::PageTableNotInitialized)?;
+ Ok(memory.handle_mmio_fault(far)?)
+}
+
+#[inline]
+fn handle_permission_fault(far: usize) -> Result<(), HandleExceptionError> {
+ let mut guard = MEMORY.try_lock().ok_or(HandleExceptionError::PageTableUnavailable)?;
+ let memory = guard.as_mut().ok_or(HandleExceptionError::PageTableNotInitialized)?;
+ Ok(memory.handle_permission_fault(far)?)
+}
+
fn handle_exception(esr: Esr, far: usize) -> Result<(), HandleExceptionError> {
// Handle all translation faults on both read and write, and MMIO guard map
// flagged invalid pages or blocks that caused the exception.
+ // Handle permission faults for DBM flagged entries, and flag them as dirty on write.
match esr {
- Esr::DataAbortTranslationFault => {
- let mut locked = MEMORY.try_lock().ok_or(HandleExceptionError::PageTableUnavailable)?;
- let memory = locked.as_mut().ok_or(HandleExceptionError::PageTableNotInitialized)?;
- Ok(memory.handle_mmio_fault(far)?)
- }
+ Esr::DataAbortTranslationFault => handle_translation_fault(far),
+ Esr::DataAbortPermissionFault => handle_permission_fault(far),
_ => Err(HandleExceptionError::UnknownException),
}
}