Skip to content

feat(paging): add atomic page table types - #631

Open
llp42 wants to merge 3 commits into
rust-osdev:masterfrom
llp42:feat/atomic-page-table
Open

llp42 wants to merge 3 commits into
rust-osdev:masterfrom
llp42:feat/atomic-page-table

Conversation

@llp42

@llp42 llp42 commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

Related to #416.

The CPU sets the accessed and dirty bits of live entries atomically. The crate only has non-atomic PageTableEntry and PageTable, so kernels keep their own AtomicU64 arrays.

This adds PageTableEntry::bits/from_bits, the PageTableEntryBits/PageTableEntryBitsMut traits, and AtomicPageTableEntry/AtomicPageTable. The traits require only bits/set_bits and derive the flags, address, frame and setters. The atomic entry wraps AtomicU64 with explicit ordered operations. AtomicPageTable mirrors PageTable's API and layout.

The trait methods use relaxed loads and stores, and the setters are not a single read-modify-write, so live updates use the explicit atomic operations. The atomic types exist on targets with 64-bit atomics. PageTable and PageTableEntry are otherwise unchanged. This does not fix the mapper's &mut PageTable requirement, so #416 stays open.

Tested with the feature matrix, clippy and rustdoc with -Dwarnings, MSRV 1.98, the CI cross targets, and Miri.

llp42 added 3 commits November 8, 2026 08:02
The CPU sets the accessed and dirty bits of live page table entries
atomically, so software accesses to a live table should be atomic too.
The crate only offers `PageTableEntry` and `PageTable`, both non-atomic,
so kernels keep their own `AtomicU64` arrays and reimplement the flag and
address handling.

`PageTableEntry::bits` and `from_bits` expose the raw value. The
`PageTableEntryBits` and `PageTableEntryBitsMut` traits encode the
operations common to the plain and atomic entries: `bits` and `set_bits`
are required, and `is_unused`, `flags`, `addr`, `frame` and the setters
are derived from them. `PageTableEntry` keeps its inherent methods,
including the `const` ones, and implements the traits through the raw
value.

`AtomicPageTableEntry` is a `#[repr(transparent)]` wrapper around
`AtomicU64` with explicit load, store, swap, compare-exchange and fetch
operations taking `PageTableEntry` values, plus the trait methods with
relaxed loads and stores. `AtomicPageTable` is `#[repr(C, align(4096))]`
and mirrors `PageTable`'s API: `new`, `zero`, `iter`, `iter_mut`,
`is_empty`, indexing, `Clone`, `Default` and `Debug`.

The atomic types exist on targets with 64-bit atomics. `PageTable` and
the existing `PageTableEntry` API are otherwise unchanged.
The trait defaults now decode and encode entries directly from the raw
value, and the non-const `PageTableEntry` methods delegate to them.
Only the `const` operations stay inherent: `bits`, `is_unused` and
`flags`. They use the same private helpers as the trait defaults, so the
address mask, flag decoding and frame checks exist once.

No behavior change, and `PageTableEntry` keeps its public API.
Recent nightlies add `set_bit` and `get_bit` to the integer types, which
collides with `bit_field::BitField` and becomes an error under
`-Dwarnings`. Allow the lint until `bit_field` avoids the collision.
@Freax13

Freax13 commented Nov 8, 2026

Copy link
Copy Markdown
Member

Thank you for you contribution!

Let's take a step back. Do we want atomic types *and* non-atomic types or should we only expose atomic types? What are the different use-cases? We should provide some guidance in the documentation to help users make the right choice for their use-cases.

@llp42

llp42 commented Nov 8, 2026

Copy link
Copy Markdown
Contributor Author

Thank you for you contribution!

Let's take a step back. Do we want atomic types and non-atomic types or should we only expose atomic types? What are the different use-cases? We should provide some guidance in the documentation to help users make the right choice for their use-cases.

At runtime, AtomicU64 covers every page table use case, including private tables via get_mut or relaxed access.

  • (a) const entry inspection: small API break; const construction still works.
  • (b) no 64-bit atomics: x86_64 and i686 have AtomicU64. The only exception is the thumbv7em ARM build, which is a compile-only portability check; remove it.
  • (c) concurrent external writers using plain stores: a semantic constraint, not an API break; boot-before-handoff is fine.
  • (d) existing PageTable API compatibility: the real API break.

So the decision is (d). If breaking compatibility is acceptable, atomic-only is viable on x86_64.

@llp42
llp42 force-pushed the feat/atomic-page-table branch 2 times, most recently from 02a0b26 to f34a70b Compare November 8, 2026 13:39

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants