Skip to content

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

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

LuigiPiucco
Copy link
Contributor

@LuigiPiucco LuigiPiucco commented May 19, 2025

This PR relaxes the ub_check in the read_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)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels May 19, 2025
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@RalfJung
Copy link
Member

RalfJung commented May 20, 2025

Cc @rust-lang/opsem @nikic

Copy link
Member

@RalfJung RalfJung left a 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?

@rust-log-analyzer

This comment has been minimized.

@RalfJung
Copy link
Member

@rustbot author

@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 23, 2025
@rustbot
Copy link
Collaborator

rustbot commented May 23, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@rustbot rustbot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label May 23, 2025
@LuigiPiucco LuigiPiucco force-pushed the volatile-null branch 2 times, most recently from ccb7d35 to aae2722 Compare May 23, 2025 16:22
@RalfJung
Copy link
Member

RalfJung commented May 23, 2025

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.

@LuigiPiucco
Copy link
Contributor Author

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.

@RalfJung
Copy link
Member

RalfJung commented May 23, 2025

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...

@LuigiPiucco
Copy link
Contributor Author

@rustbot ready

If the PR needs further revision, would you prefer to run the author/ready sequence every time, or to avoid it if we're both replying quickly? I don't mind the pings, but if you do I can adjust.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 23, 2025
@RalfJung
Copy link
Member

An explicit "ready for review" signal is always a good idea. :)

Copy link
Member

@RalfJung RalfJung left a 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.

@RalfJung RalfJung added T-lang Relevant to the language team T-opsem Relevant to the opsem team labels May 23, 2025
@rustbot

This comment has been minimized.

@LuigiPiucco
Copy link
Contributor Author

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.

@rust-log-analyzer

This comment has been minimized.

@RalfJung
Copy link
Member

RalfJung commented Jun 2, 2025

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.

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.

@RalfJung RalfJung added the I-lang-nominated Nominated for discussion during a lang team meeting. label Jun 2, 2025
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.
@traviscross traviscross added the P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang label Jun 4, 2025
Comment on lines +2031 to +2033
/// 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].
Copy link
Member

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?

@nikomatsakis
Copy link
Contributor

@rfcbot reviewed

We need to allow Rust code to do anything that is needed to target esoteric systems.

@traviscross
Copy link
Contributor

@rfcbot reviewed

Makes sense and seems necessary.

@scottmcm
Copy link
Member

scottmcm commented Jun 4, 2025

I'm always sad when I see volatile, so being kinda sad about this is consistent with that, I guess. If types folks are confident it's fine, then 🤷 I guess.

@rfcbot reviewed

@tmandry
Copy link
Member

tmandry commented Jun 4, 2025

@rfcbot reviewed

@rfcbot rfcbot added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels Jun 4, 2025
@rfcbot
Copy link
Collaborator

rfcbot commented Jun 4, 2025

🔔 This is now entering its final comment period, as per the review above. 🔔

@RalfJung
Copy link
Member

RalfJung commented Jun 4, 2025 via email

@RalfJung
Copy link
Member

RalfJung commented Jun 4, 2025 via email

@traviscross traviscross removed I-lang-nominated Nominated for discussion during a lang team meeting. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang labels Jun 4, 2025
@rust-log-analyzer

This comment has been minimized.

@LuigiPiucco
Copy link
Contributor Author

I forgot to bless the lint's tests. Poor CI...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-lang Relevant to the language team T-opsem Relevant to the opsem team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

What about: Targets where NULL is a valid pointer