Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutable references in page table implementation? #416

Open
phil-opp opened this issue Mar 26, 2023 · 1 comment
Open

Mutable references in page table implementation? #416

phil-opp opened this issue Mar 26, 2023 · 1 comment

Comments

@phil-opp
Copy link
Member

phil-opp commented Mar 26, 2023

The current API of RecursivePageTable, OffsetPageTable, and MappedPageTable encourages the creation of &mut PageTable references to the active page table hierarchy. This might be problematic because the page tables are also accessed by the hardware at the same time. The hardware might even modify the page table, e.g. set the accessed or dirty flags.

To avoid any semantic issues, it would be a good idea to also provide methods based on raw *mut PageTable pointers. We should also update the implementations to never create &mut references internally either. We might even want to use volatile operations...

See also phil-opp/blog_os#1202

@jdreaver
Copy link

jdreaver commented May 11, 2023

Hey @phil-opp, I recently went down the rabbit hole researching references to "volatile" memory in Rust. If you haven't seen them yet, here are some convincing resources that support your idea to use raw pointers and volatile operations:

Many of those resources are more concerned with spurious reads, but what I got from them is when interacting with memory "owned" by the hardware and that can be modified by the hardware, it is better to wrap raw pointers and use volatile reads/writes. My current thinking is Rust references are more appropriate for data created by Rust, either on the heap or the stack, that is fully "owned" by Rust.

In my OS, I wrote some simple wrapper types around raw pointers for registers, and a register_struct! macro that allows easily constructing types that contain these registers at specified offsets. (I took inspiration from voladdress).

I actually came across this specific issue because I wanted to wrap a type I have for physical memory allocation in a Mutex so I could use it as an impl Allocator when I need to create physically contiguous memory chunks, and Allocator uses &self on its methods. However, I also needed it for Mapper.identity_map(), which requires both &mut self and a &mut FrameAllocator. I couldn't quite figure out how to make this work without aliasing mutable memory, and went searching for a solution.


P.S. I read both editions of your "Writing an OS in Rust" blog series and I learned so much! Thanks for investing in the bare metal Rust ecosystem. It is really rewarding to learn about and use.

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

No branches or pull requests

2 participants