Prevent drop on AddrSpace

This commit is contained in:
Wildan M
2026-02-27 10:47:45 +07:00
parent d34090f352
commit c72e0a67f9
5 changed files with 62 additions and 30 deletions
+30 -16
View File
@@ -3,6 +3,7 @@ use arrayvec::ArrayVec;
use core::{
cmp,
fmt::Debug,
mem::ManuallyDrop,
num::NonZeroUsize,
ops::Bound,
sync::atomic::{AtomicU32, Ordering},
@@ -133,6 +134,9 @@ impl AddrSpaceWrapper {
}
}
}
pub fn into_drop(self, token: &mut CleanLockToken) {
self.inner.into_inner().into_drop(token);
}
}
#[derive(Debug)]
@@ -721,6 +725,28 @@ impl AddrSpace {
Ok(selected_span.base)
}
pub fn into_drop(self, token: &mut CleanLockToken) {
ManuallyDrop::new(self).inner_drop(token);
}
fn inner_drop(&mut self, token: &mut CleanLockToken) {
for mut grant in core::mem::take(&mut self.grants).into_iter() {
// Unpinning the grant is allowed, because pinning only occurs in UserScheme calls to
// prevent unmapping the mapped range twice (which would corrupt only the scheme
// provider), but it won't be able to double free any range after this address space
// has been dropped!
grant.info.unpin();
// TODO: Optimize away clearing the actual page tables? Since this address space is no
// longer arc-rwlock wrapped, it cannot be referenced `External`ly by borrowing grants,
// so it should suffice to iterate over PageInfos and decrement and maybe deallocate
// the underlying pages (and send some funmaps).
let res = grant.unmap(&mut self.table.utable, &mut NopFlusher);
let _ = res.unmap(token);
}
}
}
#[derive(Debug)]
@@ -2257,23 +2283,11 @@ pub struct Table {
impl Drop for AddrSpace {
fn drop(&mut self) {
//TODO: DANGER: unmap requires a CleanLockToken, this cheats!
let mut token = unsafe { CleanLockToken::new() };
for mut grant in core::mem::take(&mut self.grants).into_iter() {
// Unpinning the grant is allowed, because pinning only occurs in UserScheme calls to
// prevent unmapping the mapped range twice (which would corrupt only the scheme
// provider), but it won't be able to double free any range after this address space
// has been dropped!
grant.info.unpin();
// TODO: Optimize away clearing the actual page tables? Since this address space is no
// longer arc-rwlock wrapped, it cannot be referenced `External`ly by borrowing grants,
// so it should suffice to iterate over PageInfos and decrement and maybe deallocate
// the underlying pages (and send some funmaps).
let res = grant.unmap(&mut self.table.utable, &mut NopFlusher);
let _ = res.unmap(&mut token);
self.inner_drop(&mut token);
#[cfg(feature = "drop_panic")]
{
panic!("AddrSpace dropped");
}
}
}