mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-26 10:53:25 +00:00
Improve efficiency of global TLB flushing
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
720b952996
commit
99a22ff124
@ -101,16 +101,6 @@ pub(super) struct Vmar_ {
|
||||
parent: Weak<Vmar_>,
|
||||
}
|
||||
|
||||
impl Drop for Vmar_ {
|
||||
fn drop(&mut self) {
|
||||
let mut cursor = self
|
||||
.vm_space
|
||||
.cursor_mut(&(self.base..self.base + self.size))
|
||||
.unwrap();
|
||||
cursor.unmap(self.size);
|
||||
}
|
||||
}
|
||||
|
||||
struct VmarInner {
|
||||
/// Whether the vmar is destroyed
|
||||
is_destroyed: bool,
|
||||
@ -295,12 +285,7 @@ impl Vmar_ {
|
||||
if !self.is_root_vmar() {
|
||||
return_errno_with_message!(Errno::EACCES, "The vmar is not root vmar");
|
||||
}
|
||||
let mut cursor = self
|
||||
.vm_space
|
||||
.cursor_mut(&(self.base..self.base + self.size))
|
||||
.unwrap();
|
||||
cursor.unmap(self.size);
|
||||
drop(cursor);
|
||||
self.vm_space.clear();
|
||||
let mut inner = self.inner.lock();
|
||||
inner.child_vmar_s.clear();
|
||||
inner.vm_mappings.clear();
|
||||
|
@ -21,8 +21,8 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
arch::mm::{
|
||||
current_page_table_paddr, tlb_flush_addr, tlb_flush_addr_range, PageTableEntry,
|
||||
PagingConsts,
|
||||
current_page_table_paddr, tlb_flush_addr, tlb_flush_addr_range,
|
||||
tlb_flush_all_excluding_global, PageTableEntry, PagingConsts,
|
||||
},
|
||||
cpu::CpuExceptionInfo,
|
||||
mm::{
|
||||
@ -102,6 +102,29 @@ impl VmSpace {
|
||||
self.pt.activate();
|
||||
}
|
||||
|
||||
/// Clears all mappings.
|
||||
pub fn clear(&self) {
|
||||
let mut cursor = self.pt.cursor_mut(&(0..MAX_USERSPACE_VADDR)).unwrap();
|
||||
loop {
|
||||
// SAFETY: It is safe to un-map memory in the userspace.
|
||||
let result = unsafe { cursor.take_next(MAX_USERSPACE_VADDR - cursor.virt_addr()) };
|
||||
match result {
|
||||
PageTableItem::Mapped { page, .. } => {
|
||||
drop(page);
|
||||
}
|
||||
PageTableItem::NotMapped { .. } => {
|
||||
break;
|
||||
}
|
||||
PageTableItem::MappedUntracked { .. } => {
|
||||
panic!("found untracked memory mapped into `VmSpace`");
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: currently this method calls x86_64::flush_all(), which rewrite the Cr3 register.
|
||||
// We should replace it with x86_64::flush_pcid(InvPicdCommand::AllExceptGlobal) after enabling PCID.
|
||||
tlb_flush_all_excluding_global();
|
||||
}
|
||||
|
||||
pub(crate) fn handle_page_fault(
|
||||
&self,
|
||||
info: &CpuExceptionInfo,
|
||||
@ -136,10 +159,20 @@ impl VmSpace {
|
||||
prop.flags -= PageFlags::W;
|
||||
};
|
||||
|
||||
loop {
|
||||
// SAFETY: It is safe to protect memory in the userspace.
|
||||
while let Some(range) = unsafe { cursor.protect_next(end - cursor.virt_addr(), &mut op) } {
|
||||
tlb_flush_addr(range.start);
|
||||
unsafe {
|
||||
if cursor
|
||||
.protect_next(end - cursor.virt_addr(), &mut op)
|
||||
.is_none()
|
||||
{
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
// TODO: currently this method calls x86_64::flush_all(), which rewrite the Cr3 register.
|
||||
// We should replace it with x86_64::flush_pcid(InvPicdCommand::AllExceptGlobal) after enabling PCID.
|
||||
tlb_flush_all_excluding_global();
|
||||
|
||||
let page_fault_handler = {
|
||||
let new_handler = Once::new();
|
||||
|
Reference in New Issue
Block a user