Skip to content

Commit 5e6bfe8

Browse files
committed
Ensure all page table frames are mapped as writable
1 parent 972aaa7 commit 5e6bfe8

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

Changelog.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Unreleased
22

3+
* Fix bug leading to page table frames that are not mapped as writable
4+
35
# 0.11.7 – 2024-02-16
46

57
* Set `NO_EXECUTE` flag for all writable memory regions by @phil-opp in https://github.com/rust-osdev/bootloader/pull/409

common/src/lib.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,18 @@ where
241241
context_switch_function_start_frame,
242242
context_switch_function_start_frame + 1,
243243
) {
244+
let page = Page::containing_address(VirtAddr::new(frame.start_address().as_u64()));
244245
match unsafe {
245-
kernel_page_table.identity_map(frame, PageTableFlags::PRESENT, frame_allocator)
246+
// The parent table flags need to be both readable and writable to
247+
// support recursive page tables.
248+
// See https://github.com/rust-osdev/bootloader/issues/443#issuecomment-2130010621
249+
kernel_page_table.map_to_with_table_flags(
250+
page,
251+
frame,
252+
PageTableFlags::PRESENT,
253+
PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
254+
frame_allocator,
255+
)
246256
} {
247257
Ok(tlb) => tlb.flush(),
248258
Err(err) => panic!("failed to identity map frame {:?}: {:?}", frame, err),
@@ -254,8 +264,17 @@ where
254264
.allocate_frame()
255265
.expect("failed to allocate GDT frame");
256266
gdt::create_and_load(gdt_frame);
267+
let gdt_page = Page::containing_address(VirtAddr::new(gdt_frame.start_address().as_u64()));
257268
match unsafe {
258-
kernel_page_table.identity_map(gdt_frame, PageTableFlags::PRESENT, frame_allocator)
269+
// The parent table flags need to be both readable and writable to
270+
// support recursive page tables.
271+
kernel_page_table.map_to_with_table_flags(
272+
gdt_page,
273+
gdt_frame,
274+
PageTableFlags::PRESENT,
275+
PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
276+
frame_allocator,
277+
)
259278
} {
260279
Ok(tlb) => tlb.flush(),
261280
Err(err) => panic!("failed to identity map frame {:?}: {:?}", gdt_frame, err),

0 commit comments

Comments
 (0)