Set right A/D bits at the right place

This commit is contained in:
Zhang Junyang
2024-09-01 12:20:15 +08:00
committed by Tate, Hongliang Tian
parent 4e9460593d
commit f13e5d12c1
2 changed files with 15 additions and 9 deletions

View File

@ -245,7 +245,7 @@ impl VmMapping {
cursor.protect(PAGE_SIZE, |p| p.flags |= PageFlags::W); cursor.protect(PAGE_SIZE, |p| p.flags |= PageFlags::W);
} else { } else {
let new_frame = duplicate_frame(&frame)?; let new_frame = duplicate_frame(&frame)?;
prop.flags |= PageFlags::W; prop.flags |= PageFlags::W | PageFlags::ACCESSED | PageFlags::DIRTY;
cursor.map(new_frame, prop); cursor.map(new_frame, prop);
} }
return Ok(()); return Ok(());
@ -265,7 +265,12 @@ impl VmMapping {
} }
perms perms
}; };
let map_prop = PageProperty::new(vm_perms.into(), CachePolicy::Writeback); let mut page_flags = vm_perms.into();
page_flags |= PageFlags::ACCESSED;
if write {
page_flags |= PageFlags::DIRTY;
}
let map_prop = PageProperty::new(page_flags, CachePolicy::Writeback);
cursor.map(frame, map_prop); cursor.map(frame, map_prop);
} }
@ -328,14 +333,18 @@ impl VmMapping {
); );
let vm_perms = inner.perms - VmPerms::WRITE; let vm_perms = inner.perms - VmPerms::WRITE;
let vm_map_options = { PageProperty::new(vm_perms.into(), CachePolicy::Writeback) };
let parent = self.parent.upgrade().unwrap(); let parent = self.parent.upgrade().unwrap();
let vm_space = parent.vm_space(); let vm_space = parent.vm_space();
let mut cursor = vm_space.cursor_mut(&(start_addr..end_addr))?; let mut cursor = vm_space.cursor_mut(&(start_addr..end_addr))?;
let operate = move |commit_fn: &mut dyn FnMut() -> Result<Frame>| { let operate = move |commit_fn: &mut dyn FnMut() -> Result<Frame>| {
if let VmItem::NotMapped { .. } = cursor.query().unwrap() { if let VmItem::NotMapped { va, len } = cursor.query().unwrap() {
let mut page_flags = vm_perms.into();
if (va..len).contains(&page_fault_addr) {
page_flags |= PageFlags::ACCESSED;
}
let page_prop = PageProperty::new(page_flags, CachePolicy::Writeback);
let frame = commit_fn()?; let frame = commit_fn()?;
cursor.map(frame, vm_map_options); cursor.map(frame, page_prop);
} else { } else {
let next_addr = cursor.virt_addr() + PAGE_SIZE; let next_addr = cursor.virt_addr() + PAGE_SIZE;
if next_addr < end_addr { if next_addr < end_addr {

View File

@ -348,12 +348,9 @@ impl CursorMut<'_, '_> {
/// Map a frame into the current slot. /// Map a frame into the current slot.
/// ///
/// This method will bring the cursor to the next slot after the modification. /// This method will bring the cursor to the next slot after the modification.
pub fn map(&mut self, frame: Frame, mut prop: PageProperty) { pub fn map(&mut self, frame: Frame, prop: PageProperty) {
let start_va = self.virt_addr(); let start_va = self.virt_addr();
let end_va = start_va + frame.size(); let end_va = start_va + frame.size();
// TODO: this is a temporary fix to avoid the overhead of setting ACCESSED bit in userspace.
// When this bit is truly enabled, it needs to be set at a more appropriate location.
prop.flags |= PageFlags::ACCESSED;
// SAFETY: It is safe to map untyped memory into the userspace. // SAFETY: It is safe to map untyped memory into the userspace.
let old = unsafe { self.pt_cursor.map(frame.into(), prop) }; let old = unsafe { self.pt_cursor.map(frame.into(), prop) };