Skip to content
Snippets Groups Projects
Verified Commit dc198cef authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Keep track of leaked grants and allow for cloning of grants

parent d432f7ce
No related branches found
No related tags found
No related merge requests found
...@@ -18,6 +18,7 @@ pub struct Grant { ...@@ -18,6 +18,7 @@ pub struct Grant {
size: usize, size: usize,
flags: EntryFlags, flags: EntryFlags,
mapped: bool, mapped: bool,
owned: bool,
//TODO: This is probably a very heavy way to keep track of fmap'd files, perhaps move to the context? //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>, pub desc_opt: Option<FileDescriptor>,
} }
...@@ -43,6 +44,7 @@ impl Grant { ...@@ -43,6 +44,7 @@ impl Grant {
size, size,
flags, flags,
mapped: true, mapped: true,
owned: false,
desc_opt: None, desc_opt: None,
} }
} }
...@@ -66,6 +68,7 @@ impl Grant { ...@@ -66,6 +68,7 @@ impl Grant {
size, size,
flags, flags,
mapped: true, mapped: true,
owned: true,
desc_opt: None, desc_opt: None,
} }
} }
...@@ -101,10 +104,95 @@ impl Grant { ...@@ -101,10 +104,95 @@ impl Grant {
size, size,
flags, flags,
mapped: true, mapped: true,
owned: false,
desc_opt, 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 { pub fn start_address(&self) -> VirtualAddress {
self.start self.start
} }
...@@ -117,9 +205,17 @@ impl Grant { ...@@ -117,9 +205,17 @@ impl Grant {
self.flags self.flags
} }
pub unsafe fn set_mapped(&mut self, mapped: bool) {
self.mapped = mapped;
}
pub fn unmap(mut self) { pub fn unmap(mut self) {
assert!(self.mapped); assert!(self.mapped);
if self.owned {
println!("Grant::unmap: leaked {:?}", self);
}
let mut active_table = unsafe { ActivePageTable::new() }; let mut active_table = unsafe { ActivePageTable::new() };
let mut flush_all = MapperFlushAll::new(); let mut flush_all = MapperFlushAll::new();
...@@ -144,6 +240,10 @@ impl Grant { ...@@ -144,6 +240,10 @@ impl Grant {
pub fn unmap_inactive(mut self, new_table: &mut InactivePageTable, temporary_page: &mut TemporaryPage) { pub fn unmap_inactive(mut self, new_table: &mut InactivePageTable, temporary_page: &mut TemporaryPage) {
assert!(self.mapped); assert!(self.mapped);
if self.owned {
println!("Grant::unmap_inactive: leaked {:?}", self);
}
let mut active_table = unsafe { ActivePageTable::new() }; let mut active_table = unsafe { ActivePageTable::new() };
active_table.with(new_table, temporary_page, |mapper| { active_table.with(new_table, temporary_page, |mapper| {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment