diff --git a/posts/DRAFT-paging.md b/posts/DRAFT-paging.md index a512981c..5d4c0dbb 100644 --- a/posts/DRAFT-paging.md +++ b/posts/DRAFT-paging.md @@ -180,18 +180,18 @@ const fn p4_table(&self) -> Table { Table(Page { number: 0o_777_777_777_777 }) } -fn p3_table(&self) -> Table { +unsafe fn p3_table(&self) -> Table { Table(Page { number: 0o_777_777_777_000 | self.p4_index() }) } -fn p2_table(&self) -> Table { +unsafe fn p2_table(&self) -> Table { Table(Page { number: 0o_777_777_000_000 | (self.p4_index() << 9) | self.p3_index(), }) } -fn p1_table(&self) -> Table { +unsafe fn p1_table(&self) -> Table { Table(Page { number: 0o_777_000_000_000 | (self.p4_index() << 18) | (self.p3_index() << 9) | self.p2_index(), @@ -202,6 +202,8 @@ We use the octal numbers since they make it easy to express the 9 bit table inde The P4 table is the same for all addresses, so we can make the function `const`. The associated page has index 511 in all four pages, thus the four `777` blocks. The P3 table, however, is different for different P4 indexes. So the last block varies from `000` to `776`, dependent on the page's P4 index. The P2 table additionally depends on the P3 index and to get the P1 table we use the recursive mapping only once (thus only one `777` block). +Since the P3, P2, and P1 tables may not exist, the corresponding functions are marked `unsafe`. It's only safe to call them if the entry in the parent table is `PRESENT` and does not have the `HUGE_PAGE` bit set. Else we would interpret random memory as a page table and get wrong results. + The `p*_index` methods look like this: ```rust diff --git a/src/memory/paging/mod.rs b/src/memory/paging/mod.rs index 9d710605..d6cf0b22 100644 --- a/src/memory/paging/mod.rs +++ b/src/memory/paging/mod.rs @@ -135,15 +135,21 @@ impl Page { Table(Page { number: 0o_777_777_777_777 }) } - fn p3_table(&self) -> Table { + /// # Safety + /// Only valid if the corresponding entry in the parent table is PRESENT and not HUGE_PAGE. + unsafe fn p3_table(&self) -> Table { Table(Page { number: 0o_777_777_777_000 | self.p4_index() }) } - fn p2_table(&self) -> Table { + /// # Safety + /// Only valid if the corresponding entry in the parent table is PRESENT and not HUGE_PAGE. + unsafe fn p2_table(&self) -> Table { Table(Page { number: 0o_777_777_000_000 | (self.p4_index() << 9) | self.p3_index() }) } - fn p1_table(&self) -> Table { + /// # Safety + /// Only valid if the corresponding entry in the parent table is PRESENT and not HUGE_PAGE. + unsafe fn p1_table(&self) -> Table { Table(Page { number: 0o_777_000_000_000 | (self.p4_index() << 18) | (self.p3_index() << 9) | self.p2_index(),