Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e10010e

Browse filesBrowse files
authored
Merge pull request #444 from Wasabi375/page_table_bug
Ensure all page table frames are mapped as writable
2 parents 972aaa7 + f8a629c commit e10010e
Copy full SHA for e10010e

File tree

Expand file treeCollapse file tree

3 files changed

+43
-4
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+43
-4
lines changed

‎Changelog.md

Copy file name to clipboardExpand all lines: Changelog.md
+2Lines changed: 2 additions & 0 deletions
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

Copy file name to clipboardExpand all lines: common/src/lib.rs
+21-2Lines changed: 21 additions & 2 deletions
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),

‎common/src/load_kernel.rs

Copy file name to clipboardExpand all lines: common/src/load_kernel.rs
+20-2Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,17 @@ where
185185
let offset = frame - start_frame;
186186
let page = start_page + offset;
187187
let flusher = unsafe {
188+
// The parent table flags need to be both readable and writable to
189+
// support recursive page tables.
190+
// See https://github.com/rust-osdev/bootloader/issues/443#issuecomment-2130010621
188191
self.page_table
189-
.map_to(page, frame, segment_flags, self.frame_allocator)
192+
.map_to_with_table_flags(
193+
page,
194+
frame,
195+
segment_flags,
196+
Flags::PRESENT | Flags::WRITABLE,
197+
self.frame_allocator,
198+
)
190199
.map_err(|_err| "map_to failed")?
191200
};
192201
// we operate on an inactive page table, so there's no need to flush anything
@@ -280,8 +289,17 @@ where
280289

281290
// map frame
282291
let flusher = unsafe {
292+
// The parent table flags need to be both readable and writable to
293+
// support recursive page tables.
294+
// See https://github.com/rust-osdev/bootloader/issues/443#issuecomment-2130010621
283295
self.page_table
284-
.map_to(page, frame, segment_flags, self.frame_allocator)
296+
.map_to_with_table_flags(
297+
page,
298+
frame,
299+
segment_flags,
300+
Flags::PRESENT | Flags::WRITABLE,
301+
self.frame_allocator,
302+
)
285303
.map_err(|_err| "Failed to map new frame for bss memory")?
286304
};
287305
// we operate on an inactive page table, so we don't need to flush our changes

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.