-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Allow volatile access to non-Rust memory, including address 0 #141260
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
base: master
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
7ea9ad7
to
f652fc2
Compare
This comment has been minimized.
This comment has been minimized.
Cc @rust-lang/opsem @nikic |
2745d4f
to
d8b495b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a question, and I also pushed a commit where I did an edit pass over the read_volatile
docs. If you agree with what I did there, could you apply the same edits to write_volatile
?
This comment has been minimized.
This comment has been minimized.
@rustbot author |
Reminder, once the PR becomes ready for a review, use |
ccb7d35
to
aae2722
Compare
It'd help if you didn't amend and force-push my commit, then I could much easier see what you changed on top of my changes... Now I guess I'll have to download your PR and compare locally against my commit (which was 3ea26bd). In general, please do not force-push while review is still in progress. Github is terrible at dealing with force-pushes. The reviewer will ask you to squash the commits before approval. |
Sorry, I'll add new commits instead of amending from now on. Other projects I worked on seemed to prefer amending, that's why I was doing it like that. |
Yeah, every project finds their own way to work around github's deficiencies. :/ I've not yet seen a good way to deal with github's abysmal treatment of force-pushes, though. I often have to pretty much re-review a PR as github provides 0 support for figuring out what actually changes in a series of pushes and force-pushes. When you create your first PR here, a bot posts a message telling you about our PR workflow. But it's probably easy to forget that... |
@rustbot ready If the PR needs further revision, would you prefer to run the |
An explicit "ready for review" signal is always a good idea. :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point about the inter-thread synchronization, let's repeat that in the function-level docs. As usual, my read
comments apply to write
as well.
This comment has been minimized.
This comment has been minimized.
Would it be OK to change the Git history like in this branch? The tip is the same, I just squashed and reordered some commits, and removed the ones that got reverted (to correct the warning above). I can also rebase onto latest master if that would be good. |
This comment has been minimized.
This comment has been minimized.
Yeah, feel free to clean up the history. Force-pushes that keep the base commit the same are generally preferred as github's UI is better at dealing with them. You have conflicts though so a rebase on master is probably needed anyway, so you might as well do that. |
According to https://discourse.llvm.org/t/rfc-volatile-access-to-non-dereferenceable-memory-may-be-well-defined/86303/4, LLVM allows volatile operations on null and handles it correctly. This should be allowed in Rust as well, because I/O memory may be hard-coded to address 0 in some cases, like the AVR chip ATtiny1626. A test case that ensured a failure when passing null to volatile was removed, since it's now valid. Due to the addition of `maybe_is_aligned` to `ub_checks`, `maybe_is_aligned_and_not_null` was refactored to use it.
A distinction between usage on Rust memory vs. non-Rust memory was introduced. Documentation was reworded to explain what that means, and make explicit that: - No trapping can occur from volatile operations; - On Rust memory, all safety rules must be respected; - On Rust memory, the primary difference from regular access is that volatile always involves a memory dereference; - On Rust memory, the only data affected by an operation is the one pointed to in the argument(s) of the function; - On Rust memory, provenance follows the same rules as non-volatile access; - On non-Rust memory, any address known to not contain Rust memory is valid (including 0 and usize::MAX); - On non-Rust memory, no Rust memory may be affected (it is implicit that any other non-Rust memory may be affected, though, even if not referenced by the pointer). This should be relevant when, for example, reading register A causes a flag to change in register B, or writing to A causes B to change in some way. Everything affected mustn't be inside an allocation. - On non-Rust memory, provenance is irrelevant and a pointer with none can be used in a valid way.
49d14c8
to
80a4707
Compare
/// Rust does not currently have a rigorously and formally defined memory model, so the precise | ||
/// semantics of what "volatile" means here is subject to change over time. That being said, the | ||
/// semantics will almost always end up pretty similar to [C11's definition of volatile][c11]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we still need this paragraph. The next paragraph says basically as much as C says, after all.
@rust-lang/opsem what do you think?
@rfcbot reviewed We need to allow Rust code to do anything that is needed to target esoteric systems. |
@rfcbot reviewed Makes sense and seems necessary. |
I'm always sad when I see @rfcbot reviewed |
@rfcbot reviewed |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
Also remove a now-unneeded `allow` line.
@scottmcm FWIW I think volatile can be justified in a quite principled way. There's a lot of baggage around volatile and it is misunderstood by many, but at its core is a sensible semantics that I hope we can carve out over time.
Happy to discuss this more at some point in a suitable venue :)
|
@LuigiPiucco that wording you suggested sounds good. :)
|
This comment has been minimized.
This comment has been minimized.
I forgot to bless the lint's tests. Poor CI... |
This PR relaxes the
ub_check
in theread_volatile
/write_volatile
pointer operations to allow passing null. This is needed to support processors which hard-code peripheral registers on address 0, like the AVR chip ATtiny1626. LLVM understands this as valid and handles it correctly, as tested in my PR to add a note about it (rustc generates the same LLVM IR as expected there when this PR is applied, and consequently the same AVR assembly).Follow-up and implementation of the discussions in:
r? @RalfJung
Also fixes rust-lang/unsafe-code-guidelines#29 (about as good as it'll get, null will likely never be a "normal" address in Rust)