Keep track of leaked grants and allow for cloning of grants
This commit is contained in:
@@ -18,6 +18,7 @@ pub struct Grant {
|
||||
size: usize,
|
||||
flags: EntryFlags,
|
||||
mapped: bool,
|
||||
owned: bool,
|
||||
//TODO: This is probably a very heavy way to keep track of fmap'd files, perhaps move to the context?
|
||||
pub desc_opt: Option<FileDescriptor>,
|
||||
}
|
||||
@@ -43,6 +44,7 @@ impl Grant {
|
||||
size,
|
||||
flags,
|
||||
mapped: true,
|
||||
owned: false,
|
||||
desc_opt: None,
|
||||
}
|
||||
}
|
||||
@@ -66,6 +68,7 @@ impl Grant {
|
||||
size,
|
||||
flags,
|
||||
mapped: true,
|
||||
owned: true,
|
||||
desc_opt: None,
|
||||
}
|
||||
}
|
||||
@@ -101,10 +104,95 @@ impl Grant {
|
||||
size,
|
||||
flags,
|
||||
mapped: true,
|
||||
owned: false,
|
||||
desc_opt,
|
||||
}
|
||||
}
|
||||
|
||||
/// This function should only be used in clone!
|
||||
pub fn secret_clone(&self, new_start: VirtualAddress) -> Grant {
|
||||
assert!(self.mapped);
|
||||
|
||||
let mut active_table = unsafe { ActivePageTable::new() };
|
||||
|
||||
let mut flush_all = MapperFlushAll::new();
|
||||
|
||||
let start_page = Page::containing_address(self.start);
|
||||
let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size - 1));
|
||||
for page in Page::range_inclusive(start_page, end_page) {
|
||||
//TODO: One function to do both?
|
||||
let flags = active_table.translate_page_flags(page).expect("grant references unmapped memory");
|
||||
let frame = active_table.translate_page(page).expect("grant references unmapped memory");
|
||||
|
||||
let new_page = Page::containing_address(VirtualAddress::new(page.start_address().get() - self.start.get() + new_start.get()));
|
||||
if self.owned {
|
||||
let result = active_table.map(new_page, EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
|
||||
flush_all.consume(result);
|
||||
} else {
|
||||
let result = active_table.map_to(new_page, frame, flags);
|
||||
flush_all.consume(result);
|
||||
}
|
||||
}
|
||||
|
||||
flush_all.flush(&mut active_table);
|
||||
|
||||
if self.owned {
|
||||
unsafe {
|
||||
intrinsics::copy(self.start.get() as *const u8, new_start.get() as *mut u8, self.size);
|
||||
}
|
||||
|
||||
let mut flush_all = MapperFlushAll::new();
|
||||
|
||||
for page in Page::range_inclusive(start_page, end_page) {
|
||||
//TODO: One function to do both?
|
||||
let flags = active_table.translate_page_flags(page).expect("grant references unmapped memory");
|
||||
|
||||
let new_page = Page::containing_address(VirtualAddress::new(page.start_address().get() - self.start.get() + new_start.get()));
|
||||
let result = active_table.remap(new_page, flags);
|
||||
flush_all.consume(result);
|
||||
}
|
||||
|
||||
flush_all.flush(&mut active_table);
|
||||
}
|
||||
|
||||
Grant {
|
||||
start: new_start,
|
||||
size: self.size,
|
||||
flags: self.flags,
|
||||
mapped: true,
|
||||
owned: self.owned,
|
||||
desc_opt: self.desc_opt.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_to(&mut self, new_start: VirtualAddress, new_table: &mut InactivePageTable, temporary_page: &mut TemporaryPage) {
|
||||
assert!(self.mapped);
|
||||
|
||||
let mut active_table = unsafe { ActivePageTable::new() };
|
||||
|
||||
let mut flush_all = MapperFlushAll::new();
|
||||
|
||||
let start_page = Page::containing_address(self.start);
|
||||
let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size - 1));
|
||||
for page in Page::range_inclusive(start_page, end_page) {
|
||||
//TODO: One function to do both?
|
||||
let flags = active_table.translate_page_flags(page).expect("grant references unmapped memory");
|
||||
let (result, frame) = active_table.unmap_return(page, false);
|
||||
flush_all.consume(result);
|
||||
|
||||
active_table.with(new_table, temporary_page, |mapper| {
|
||||
let new_page = Page::containing_address(VirtualAddress::new(page.start_address().get() - self.start.get() + new_start.get()));
|
||||
let result = mapper.map_to(new_page, frame, flags);
|
||||
// Ignore result due to mapping on inactive table
|
||||
unsafe { result.ignore(); }
|
||||
});
|
||||
}
|
||||
|
||||
flush_all.flush(&mut active_table);
|
||||
|
||||
self.start = new_start;
|
||||
}
|
||||
|
||||
pub fn start_address(&self) -> VirtualAddress {
|
||||
self.start
|
||||
}
|
||||
@@ -117,9 +205,17 @@ impl Grant {
|
||||
self.flags
|
||||
}
|
||||
|
||||
pub unsafe fn set_mapped(&mut self, mapped: bool) {
|
||||
self.mapped = mapped;
|
||||
}
|
||||
|
||||
pub fn unmap(mut self) {
|
||||
assert!(self.mapped);
|
||||
|
||||
if self.owned {
|
||||
println!("Grant::unmap: leaked {:?}", self);
|
||||
}
|
||||
|
||||
let mut active_table = unsafe { ActivePageTable::new() };
|
||||
|
||||
let mut flush_all = MapperFlushAll::new();
|
||||
@@ -144,6 +240,10 @@ impl Grant {
|
||||
pub fn unmap_inactive(mut self, new_table: &mut InactivePageTable, temporary_page: &mut TemporaryPage) {
|
||||
assert!(self.mapped);
|
||||
|
||||
if self.owned {
|
||||
println!("Grant::unmap_inactive: leaked {:?}", self);
|
||||
}
|
||||
|
||||
let mut active_table = unsafe { ActivePageTable::new() };
|
||||
|
||||
active_table.with(new_table, temporary_page, |mapper| {
|
||||
|
||||
Reference in New Issue
Block a user