(&mut self,
table: &mut InactivePageTable,
temporary_page: &mut temporary_page::TemporaryPage,
f: F)
| 108 | } |
| 109 | |
| 110 | pub fn with<F>(&mut self, |
| 111 | table: &mut InactivePageTable, |
| 112 | temporary_page: &mut temporary_page::TemporaryPage, |
| 113 | f: F) |
| 114 | where F: FnOnce(&mut Mapper) |
| 115 | { |
| 116 | use x86_64::registers::control_regs; |
| 117 | |
| 118 | { |
| 119 | // backup the original CR3 address in order to restore it lately |
| 120 | let backup = Frame::containing_address(control_regs::cr3().0 as usize); |
| 121 | |
| 122 | // map temporary_page to current p4 table |
| 123 | let p4_table = temporary_page.map_table_frame(backup.clone(), self); |
| 124 | |
| 125 | // overwrite recursive mapping and flush the tlb to ensure the correct page translation |
| 126 | self.p4_mut()[511].set(table.p4_frame.clone(), PRESENT | WRITABLE); |
| 127 | |
| 128 | // flush TLB |
| 129 | self.flush_all(); |
| 130 | |
| 131 | // execute f in the new context |
| 132 | f(self); |
| 133 | |
| 134 | // restore recursive mapping to original p4 table and flush the tlb again |
| 135 | p4_table[511].set(backup, PRESENT | WRITABLE); |
| 136 | |
| 137 | // flush TLB |
| 138 | self.flush_all(); |
| 139 | } |
| 140 | |
| 141 | temporary_page.unmap(self); |
| 142 | } |
| 143 | |
| 144 | /// Switch context |
| 145 | pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable { |
no test coverage detected