diff --git a/context/memory.rs b/context/memory.rs index c0b885b6b5f3243d21f97e30b1946cb8dc4cd6fd..9cd57f2ad383bfc5bb50c24994c6d6f301fedb66 100644 --- a/context/memory.rs +++ b/context/memory.rs @@ -39,14 +39,22 @@ impl Memory { pub fn map(&mut self, flush: bool, clear: bool) { let mut active_table = unsafe { ActivePageTable::new() }; + let mut flush_all = false; + //TODO: Clear pages? for page in self.pages() { active_table.map(page, self.flags); + if flush { - active_table.flush(page); + //active_table.flush(page); + flush_all = true; } } + if flush_all { + active_table.flush_all(); + } + if clear { assert!(flush); unsafe { memset(self.start_address().get() as *mut u8, 0, self.size); } @@ -56,24 +64,40 @@ impl Memory { pub fn unmap(&mut self, flush: bool) { let mut active_table = unsafe { ActivePageTable::new() }; + let mut flush_all = false; + for page in self.pages() { active_table.unmap(page); + if flush { - active_table.flush(page); + //active_table.flush(page); + flush_all = true; } } + + if flush_all { + active_table.flush_all(); + } } pub fn remap(&mut self, new_flags: EntryFlags, flush: bool) { let mut active_table = unsafe { ActivePageTable::new() }; + let mut flush_all = false; + for page in self.pages() { active_table.remap(page, new_flags); + if flush { - active_table.flush(page); + //active_table.flush(page); + flush_all = true; } } + if flush_all { + active_table.flush_all(); + } + self.flags = new_flags; } @@ -82,32 +106,48 @@ impl Memory { //TODO: Calculate page changes to minimize operations if new_size > self.size { + let mut flush_all = false; + let start_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size)); let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + new_size - 1)); for page in Page::range_inclusive(start_page, end_page) { if active_table.translate_page(page).is_none() { active_table.map(page, self.flags); + if flush { - active_table.flush(page); + //active_table.flush(page); + flush_all = true; } } } + if flush_all { + active_table.flush_all(); + } + if clear { assert!(flush); unsafe { memset((self.start.get() + self.size) as *mut u8, 0, new_size - self.size); } } } else if new_size < self.size { + let mut flush_all = false; + let start_page = Page::containing_address(VirtualAddress::new(self.start.get() + new_size)); let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size - 1)); for page in Page::range_inclusive(start_page, end_page) { if active_table.translate_page(page).is_some() { active_table.unmap(page); + if flush { - active_table.flush(page); + //active_table.flush(page); + flush_all = true; } } } + + if flush_all { + active_table.flush_all(); + } } self.size = new_size; diff --git a/syscall/process.rs b/syscall/process.rs index 78e0bc69c1e7462806b0ca68158600c6fb0300bb..ad1d107ca0f6b11eb927a7395ffd0ed148a3ea68 100644 --- a/syscall/process.rs +++ b/syscall/process.rs @@ -49,7 +49,7 @@ pub fn clone(flags: usize) -> Result<usize> { pub fn exit(status: usize) -> ! { println!("Exit {}", status); - + { let contexts = context::contexts(); let context_lock = contexts.current().expect("tried to exit without context");