Skip to content

Commit 14c63aa

Browse files
committed
Only perform a single TLB flush after identity mapping
This commit changes the BIOS bootloader to only flush the TLB once, after it has identity-mapped every physical memory frame. This should be a bit more efficient, as we don't perform a separate `invlpg` for every page table entry we create, and instead only flush the entire thing by reloading `CR3` when we're actually ready to use it. This is based on a suggestion by @phil-opp, here: #260 (comment) This change doesn't actually seem to make all that big an impact in boot times on QEMU v7.1 on its own, relative to PR #260, but it might make an additional improvement on top of that PR.
1 parent ac46d04 commit 14c63aa

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

src/bin/bios.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,28 @@ fn bootloader_main(
109109
PhysFrame::containing_address(PhysAddr::new(4096 * 512 * 512));
110110
let end_frame = PhysFrame::containing_address(PhysAddr::new(max_phys_addr - 1));
111111
for frame in PhysFrame::range_inclusive(start_frame, end_frame) {
112-
unsafe {
112+
let flusher = unsafe {
113113
bootloader_page_table
114114
.identity_map(
115115
frame,
116116
PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
117117
&mut frame_allocator,
118118
)
119119
.unwrap()
120-
.flush()
121120
};
121+
// skip flushing the entry from the TLB for now, as we will
122+
// flush the entire TLB at the end of the loop.
123+
flusher.ignore();
122124
}
123125
}
124126

127+
// once all the physical memory is mapped, flush the TLB by reloading the
128+
// CR3 register.
129+
//
130+
// we perform a single flush here rather than flushing each individual entry as
131+
// it's mapped using `invlpg`, for efficiency.
132+
x86_64::instructions::tlb::flush_all();
133+
125134
let framebuffer_addr = PhysAddr::new(unsafe { VBEModeInfo_physbaseptr }.into());
126135
let mut error = None;
127136
let framebuffer_info = unsafe {

0 commit comments

Comments
 (0)