From f67e7bb128636e66e22545a32f45dab8c9b9793b Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 22 Jul 2019 10:47:33 +0200 Subject: [PATCH] Update paging introduction post to use page fault error code (#644) We previously did not use the error code because of https://github.com/phil-opp/blog_os/issues/513, which is now fixed. --- .../posts/08-paging-introduction/index.md | 33 ++++++++++++------ .../qemu-page-fault-protection.png | Bin 0 -> 12536 bytes .../qemu-page-fault.png | Bin 11599 -> 12035 bytes 3 files changed, 23 insertions(+), 10 deletions(-) create mode 100644 blog/content/second-edition/posts/08-paging-introduction/qemu-page-fault-protection.png diff --git a/blog/content/second-edition/posts/08-paging-introduction/index.md b/blog/content/second-edition/posts/08-paging-introduction/index.md index 5ee100e10..d93f317a4 100644 --- a/blog/content/second-edition/posts/08-paging-introduction/index.md +++ b/blog/content/second-edition/posts/08-paging-introduction/index.md @@ -278,18 +278,19 @@ use x86_64::structures::idt::PageFaultErrorCode; extern "x86-interrupt" fn page_fault_handler( stack_frame: &mut InterruptStackFrame, - _error_code: PageFaultErrorCode, + error_code: PageFaultErrorCode, ) { use x86_64::registers::control::Cr2; println!("EXCEPTION: PAGE FAULT"); println!("Accessed Address: {:?}", Cr2::read()); + println!("Error Code: {:?}", error_code); println!("{:#?}", stack_frame); hlt_loop(); } ``` -The [`CR2`] register is automatically set by the CPU on a page fault and contains the accessed virtual address that caused the page fault. We use the [`Cr2::read`] function of the `x86_64` crate to read and print it. Normally the [`PageFaultErrorCode`] type would provide more information about the type of memory access that caused the page fault, but there is currently an [LLVM bug] that passes an invalid error code, so we ignore it for now. We can't continue execution without resolving the page fault, so we enter a [`hlt_loop`] at the end. +The [`CR2`] register is automatically set by the CPU on a page fault and contains the accessed virtual address that caused the page fault. We use the [`Cr2::read`] function of the `x86_64` crate to read and print it. The [`PageFaultErrorCode`] type provides more information about the type of memory access that caused the page fault, for example whether it was caused by a read or write operation. For this reason we print it too. We can't continue execution without resolving the page fault, so we enter a [`hlt_loop`] at the end. [`CR2`]: https://en.wikipedia.org/wiki/Control_register#CR2 [`Cr2::read`]: https://docs.rs/x86_64/0.7.0/x86_64/registers/control/struct.Cr2.html#method.read @@ -323,27 +324,39 @@ pub extern "C" fn _start() -> ! { When we run it, we see that our page fault handler is called: -![EXCEPTION: Page Fault, Accessed Address: VirtAddr(0xdeadbeaf), InterruptStackFrame: {…}](qemu-page-fault.png) +![EXCEPTION: Page Fault, Accessed Address: VirtAddr(0xdeadbeaf), Error Code: CAUSED_BY_WRITE, InterruptStackFrame: {…}](qemu-page-fault.png) -The `CR2` register indeed contains `0xdeadbeaf`, the address that we tried to access. +The `CR2` register indeed contains `0xdeadbeaf`, the address that we tried to access. The error code tells us through the [`CAUSED_BY_WRITE`] that the fault occurred while trying to perform a write operation. It tells us even more through the [bits that are _not_ set][`PageFaultErrorCode`]. For example, the fact that the `PROTECTION_VIOLATION` flag is not set means that the page fault occurred because the target page wasn't present. -We see that the current instruction pointer is `0x20430a`, so we know that this address points to a code page. Code pages are mapped read-only by the bootloader, so reading from this address works but writing causes a page fault. You can try this by changing the `0xdeadbeaf` pointer to `0x20430a`: +[`CAUSED_BY_WRITE`]: https://docs.rs/x86_64/0.7.0/x86_64/structures/idt/struct.PageFaultErrorCode.html#associatedconstant.CAUSED_BY_WRITE + +We see that the current instruction pointer is `0x2031b2`, so we know that this address points to a code page. Code pages are mapped read-only by the bootloader, so reading from this address works but writing causes a page fault. You can try this by changing the `0xdeadbeaf` pointer to `0x2031b2`: ```rust // Note: The actual address might be different for you. Use the address that // your page fault handler reports. -let ptr = 0x20430a as *mut u32; -// read from a code page -> works +let ptr = 0x2031b2 as *mut u32; + +// read from a code page unsafe { let x = *ptr; } -// write to a code page -> page fault +println!("read worked"); + +// write to a code page unsafe { *ptr = 42; } +println!("write worked"); ``` -By commenting out the last line, we see that the read access works, but the write access causes a page fault. +By commenting out the last line, we see that the read access works, but the write access causes a page fault: + +![QEMU with output: "read worked, EXCEPTION: Page Fault, Accessed Address: VirtAddr(0x2031b2), Error Code: PROTECTION_VIOLATION | CAUSED_BY_WRITE, InterruptStackFrame: {…}"](qemu-page-fault-protection.png) + +We see that the _"read worked"_ message is printed, which indicates that the read operation did not cause any errors. However, instead of the _"write worked"_ message a page fault occurs. This time the [`PROTECTION_VIOLATION`] flag is set in addition to the [`CAUSED_BY_WRITE`] flag, which indicates that the page was present, but the operation was not allowed on it. In this case, writes to the page are not allowed since code pages are mapped as read-only. + +[`PROTECTION_VIOLATION`]: https://docs.rs/x86_64/0.7.0/x86_64/structures/idt/struct.PageFaultErrorCode.html#associatedconstant.PROTECTION_VIOLATION ### Accessing the Page Tables -Let's try to take a look at the page tables that our kernel runs on: +Let's try to take a look at the page tables that define how our kernel is mapped: ```rust // in src/main.rs diff --git a/blog/content/second-edition/posts/08-paging-introduction/qemu-page-fault-protection.png b/blog/content/second-edition/posts/08-paging-introduction/qemu-page-fault-protection.png new file mode 100644 index 0000000000000000000000000000000000000000..be6bdcff501e372653efe66859652c5ba501a42b GIT binary patch literal 12536 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 Ds@&hP literal 0 HcmV?d00001 diff --git a/blog/content/second-edition/posts/08-paging-introduction/qemu-page-fault.png b/blog/content/second-edition/posts/08-paging-introduction/qemu-page-fault.png index 5657759750e232705f15b81b77c75fe66f5eb983..815328f87c2cdae191bc1407ca06893efb30cd35 100644 GIT binary patch delta 10533 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