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_>,
|
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 {
|
struct VmarInner {
|
||||||
/// Whether the vmar is destroyed
|
/// Whether the vmar is destroyed
|
||||||
is_destroyed: bool,
|
is_destroyed: bool,
|
||||||
@ -295,12 +285,7 @@ impl Vmar_ {
|
|||||||
if !self.is_root_vmar() {
|
if !self.is_root_vmar() {
|
||||||
return_errno_with_message!(Errno::EACCES, "The vmar is not root vmar");
|
return_errno_with_message!(Errno::EACCES, "The vmar is not root vmar");
|
||||||
}
|
}
|
||||||
let mut cursor = self
|
self.vm_space.clear();
|
||||||
.vm_space
|
|
||||||
.cursor_mut(&(self.base..self.base + self.size))
|
|
||||||
.unwrap();
|
|
||||||
cursor.unmap(self.size);
|
|
||||||
drop(cursor);
|
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
inner.child_vmar_s.clear();
|
inner.child_vmar_s.clear();
|
||||||
inner.vm_mappings.clear();
|
inner.vm_mappings.clear();
|
||||||
|
@ -21,8 +21,8 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::mm::{
|
arch::mm::{
|
||||||
current_page_table_paddr, tlb_flush_addr, tlb_flush_addr_range, PageTableEntry,
|
current_page_table_paddr, tlb_flush_addr, tlb_flush_addr_range,
|
||||||
PagingConsts,
|
tlb_flush_all_excluding_global, PageTableEntry, PagingConsts,
|
||||||
},
|
},
|
||||||
cpu::CpuExceptionInfo,
|
cpu::CpuExceptionInfo,
|
||||||
mm::{
|
mm::{
|
||||||
@ -102,6 +102,29 @@ impl VmSpace {
|
|||||||
self.pt.activate();
|
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(
|
pub(crate) fn handle_page_fault(
|
||||||
&self,
|
&self,
|
||||||
info: &CpuExceptionInfo,
|
info: &CpuExceptionInfo,
|
||||||
@ -136,10 +159,20 @@ impl VmSpace {
|
|||||||
prop.flags -= PageFlags::W;
|
prop.flags -= PageFlags::W;
|
||||||
};
|
};
|
||||||
|
|
||||||
// SAFETY: It is safe to protect memory in the userspace.
|
loop {
|
||||||
while let Some(range) = unsafe { cursor.protect_next(end - cursor.virt_addr(), &mut op) } {
|
// SAFETY: It is safe to protect memory in the userspace.
|
||||||
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 page_fault_handler = {
|
||||||
let new_handler = Once::new();
|
let new_handler = Once::new();
|
||||||
|
Reference in New Issue
Block a user