From: Alice Ryhl <aliceryhl@google.com>
To: Timur Tabi <ttabi@nvidia.com>
Cc: "gary@garyguo.net" <gary@garyguo.net>,
"mmaurer@google.com" <mmaurer@google.com>,
"rust-for-linux@vger.kernel.org" <rust-for-linux@vger.kernel.org>,
Eliot Courtney <ecourtney@nvidia.com>,
"nouveau@lists.freedesktop.org" <nouveau@lists.freedesktop.org>,
Joel Fernandes <joelagnelf@nvidia.com>,
"dakr@kernel.org" <dakr@kernel.org>,
"ojeda@kernel.org" <ojeda@kernel.org>,
Alexandre Courbot <acourbot@nvidia.com>
Subject: Re: [PATCH v9 2/6] rust: uaccess: add write_dma() for copying from DMA buffers to userspace
Date: Mon, 16 Mar 2026 21:51:13 +0000 [thread overview]
Message-ID: <abh7UWSgRHtQlAxI@google.com> (raw)
In-Reply-To: <e47d8712100d8aba2b77425cb4912cb2c3966e19.camel@nvidia.com>
On Mon, Mar 16, 2026 at 09:42:44PM +0000, Timur Tabi wrote:
> On Mon, 2026-03-16 at 20:42 +0000, Alice Ryhl wrote:
> > On Mon, Mar 16, 2026 at 12:57:32AM -0500, Timur Tabi wrote:
> > > Add UserSliceWriter::write_dma() to copy data from a CoherentAllocation<u8>
> > > to userspace. This provides a safe interface for copying DMA buffer
> > > contents to userspace without requiring callers to work with raw pointers.
> > >
> > > Because write_dma() and write_slice() have common code, factor that code
> > > out into a helper function, write_raw().
> > >
> > > The method handles bounds checking and offset calculation internally,
> > > wrapping the unsafe copy_to_user() call.
> > >
> > > Signed-off-by: Timur Tabi <ttabi@nvidia.com>
> > > Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
> >
> > > + /// # Safety
> > > + ///
> > > + /// The caller must ensure that `ptr` points to a valid slice of `len` bytes (i.e., it is
> > > + /// valid for reads of `len` bytes).
> >
> > I don't know how I feel about this 'valid slice' thing. The memory might
> > be dma memory after all ... just say it's valid for reads of `len`
> > bytes.
>
> Shouldn't the safety comment also say that `len` is valid for writes to self.ptr, not just reads for
> `ptr`? I know there is a "if len > self.length" check. Does that check obviate the need for a
> safety comment that references self.ptr?
You do not need the caller to do anything special about the userspace
part of the write. That's just safe because 'copy_to_user' either
succeeds safely or returns an error. Only reading from `ptr` is
dangerous here.
> Maybe I should rename `ptr`, to avoid confusion with self.ptr. Would be okay to rename it to
> `from`, since it's copying from that kernel address?
Yes, that is a good suggestion.
> > After all, in below SAFETY: comments, you also argue that it's valid for
> > reads, not that it points at a valid slice.
> >
> > > + unsafe fn write_raw(&mut self, ptr: *const u8, len: usize) -> Result {
> > > if len > self.length {
> > > return Err(EFAULT);
> > > }
> > > - // SAFETY: `data_ptr` points into an immutable slice of length `len`, so we may read
> > > - // that many bytes from it.
> > > - let res = unsafe { bindings::copy_to_user(self.ptr.as_mut_ptr(), data_ptr, len) };
> > > + // SAFETY:
> > > + // - `self.ptr` is a userspace pointer, and `len <= self.length` is checked above to
> > > + // ensure we don't exceed the caller-specified bounds.
> > > + // - `ptr` is valid for reading `len` bytes as required by this function's safety
> > > contract.
> > > + // - `copy_to_user` validates the userspace address at runtime and returns non-zero on
> > > + // failure (e.g., bad address or unmapped memory).
> > > + let res =
> > > + unsafe { bindings::copy_to_user(self.ptr.as_mut_ptr(), ptr.cast::<c_void>(), len)
> > > };
> >
> > Points 1 and 3 in this bulleted list do not seem to address any actual
> > safety requirements of `copy_to_user`. Yes, the function validates
> > userspace addresses at runtime, and this is part of why its
> > implementation is safe, but it's not a precondition on the caller.
> > There's no way to call `copy_to_user` where it would not validate the
> > userspace address at runtime.
>
> Fair enough, but I'm struggling to come up with a safety comment that doesn't just repeat what's in
> the function comment:
>
> /// The caller must ensure that `ptr` is valid for reads of `len` bytes.
>
> (and maybe also valid for writes to self.ptr).
>
> It seems to me that we're just extending the safety conditions copy_to_user() directly to
> write_raw(). That is, the reason write_raw() is unsafe is because copy_to_user() is unsafe.
> Therefore, shouldn't the safety comment for copy_to_user just be:
>
> // SAFETY: Caller guarantees `ptr` is valid for `len` bytes (see this function's safety contract).
Yes, that's a good safety comment for copy_to_user(). I think most
commonly it is worded like this: "By this methods safety requirements,
the caller guarantees that `ptr` is valid for reading `len` bytes."
Alice
WARNING: multiple messages have this Message-ID (diff)
From: Alice Ryhl <aliceryhl@google.com>
To: Timur Tabi <ttabi@nvidia.com>
Cc: John Hubbard <jhubbard@nvidia.com>,
"gary@garyguo.net" <gary@garyguo.net>,
"mmaurer@google.com" <mmaurer@google.com>,
"rust-for-linux@vger.kernel.org"
<rust-for-linux@vger.kernel.org>,
Eliot Courtney <ecourtney@nvidia.com>,
"nouveau@lists.freedesktop.org" <nouveau@lists.freedesktop.org>,
Joel Fernandes <joelagnelf@nvidia.com>,
"dakr@kernel.org" <dakr@kernel.org>,
"ojeda@kernel.org" <ojeda@kernel.org>,
Alexandre Courbot <acourbot@nvidia.com>
Subject: Re: [PATCH v9 2/6] rust: uaccess: add write_dma() for copying from DMA buffers to userspace
Date: Mon, 16 Mar 2026 21:51:13 +0000 [thread overview]
Message-ID: <abh7UWSgRHtQlAxI@google.com> (raw)
In-Reply-To: <e47d8712100d8aba2b77425cb4912cb2c3966e19.camel@nvidia.com>
On Mon, Mar 16, 2026 at 09:42:44PM +0000, Timur Tabi wrote:
> On Mon, 2026-03-16 at 20:42 +0000, Alice Ryhl wrote:
> > On Mon, Mar 16, 2026 at 12:57:32AM -0500, Timur Tabi wrote:
> > > Add UserSliceWriter::write_dma() to copy data from a CoherentAllocation<u8>
> > > to userspace. This provides a safe interface for copying DMA buffer
> > > contents to userspace without requiring callers to work with raw pointers.
> > >
> > > Because write_dma() and write_slice() have common code, factor that code
> > > out into a helper function, write_raw().
> > >
> > > The method handles bounds checking and offset calculation internally,
> > > wrapping the unsafe copy_to_user() call.
> > >
> > > Signed-off-by: Timur Tabi <ttabi@nvidia.com>
> > > Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
> >
> > > + /// # Safety
> > > + ///
> > > + /// The caller must ensure that `ptr` points to a valid slice of `len` bytes (i.e., it is
> > > + /// valid for reads of `len` bytes).
> >
> > I don't know how I feel about this 'valid slice' thing. The memory might
> > be dma memory after all ... just say it's valid for reads of `len`
> > bytes.
>
> Shouldn't the safety comment also say that `len` is valid for writes to self.ptr, not just reads for
> `ptr`? I know there is a "if len > self.length" check. Does that check obviate the need for a
> safety comment that references self.ptr?
You do not need the caller to do anything special about the userspace
part of the write. That's just safe because 'copy_to_user' either
succeeds safely or returns an error. Only reading from `ptr` is
dangerous here.
> Maybe I should rename `ptr`, to avoid confusion with self.ptr. Would be okay to rename it to
> `from`, since it's copying from that kernel address?
Yes, that is a good suggestion.
> > After all, in below SAFETY: comments, you also argue that it's valid for
> > reads, not that it points at a valid slice.
> >
> > > + unsafe fn write_raw(&mut self, ptr: *const u8, len: usize) -> Result {
> > > if len > self.length {
> > > return Err(EFAULT);
> > > }
> > > - // SAFETY: `data_ptr` points into an immutable slice of length `len`, so we may read
> > > - // that many bytes from it.
> > > - let res = unsafe { bindings::copy_to_user(self.ptr.as_mut_ptr(), data_ptr, len) };
> > > + // SAFETY:
> > > + // - `self.ptr` is a userspace pointer, and `len <= self.length` is checked above to
> > > + // ensure we don't exceed the caller-specified bounds.
> > > + // - `ptr` is valid for reading `len` bytes as required by this function's safety
> > > contract.
> > > + // - `copy_to_user` validates the userspace address at runtime and returns non-zero on
> > > + // failure (e.g., bad address or unmapped memory).
> > > + let res =
> > > + unsafe { bindings::copy_to_user(self.ptr.as_mut_ptr(), ptr.cast::<c_void>(), len)
> > > };
> >
> > Points 1 and 3 in this bulleted list do not seem to address any actual
> > safety requirements of `copy_to_user`. Yes, the function validates
> > userspace addresses at runtime, and this is part of why its
> > implementation is safe, but it's not a precondition on the caller.
> > There's no way to call `copy_to_user` where it would not validate the
> > userspace address at runtime.
>
> Fair enough, but I'm struggling to come up with a safety comment that doesn't just repeat what's in
> the function comment:
>
> /// The caller must ensure that `ptr` is valid for reads of `len` bytes.
>
> (and maybe also valid for writes to self.ptr).
>
> It seems to me that we're just extending the safety conditions copy_to_user() directly to
> write_raw(). That is, the reason write_raw() is unsafe is because copy_to_user() is unsafe.
> Therefore, shouldn't the safety comment for copy_to_user just be:
>
> // SAFETY: Caller guarantees `ptr` is valid for `len` bytes (see this function's safety contract).
Yes, that's a good safety comment for copy_to_user(). I think most
commonly it is worded like this: "By this methods safety requirements,
the caller guarantees that `ptr` is valid for reading `len` bytes."
Alice
next prev parent reply other threads:[~2026-03-16 21:51 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-16 5:57 [PATCH v9 0/6] gpu: nova-core: expose the logging buffers via debugfs Timur Tabi
2026-03-16 5:57 ` [PATCH v9 1/6] rust: device: add device name method Timur Tabi
2026-03-16 11:49 ` Gary Guo
2026-03-16 5:57 ` [PATCH v9 2/6] rust: uaccess: add write_dma() for copying from DMA buffers to userspace Timur Tabi
2026-03-16 20:42 ` Alice Ryhl
2026-03-16 20:42 ` Alice Ryhl
2026-03-16 21:42 ` Timur Tabi
2026-03-16 21:42 ` Timur Tabi
2026-03-16 21:51 ` Alice Ryhl [this message]
2026-03-16 21:51 ` Alice Ryhl
2026-03-17 21:43 ` Miguel Ojeda
2026-03-17 21:43 ` Miguel Ojeda
2026-03-17 23:02 ` Timur Tabi
2026-03-17 23:02 ` Timur Tabi
2026-03-16 5:57 ` [PATCH v9 3/6] rust: dma: implement BinaryWriter for CoherentAllocation<u8> Timur Tabi
2026-03-16 20:46 ` Alice Ryhl
2026-03-16 20:46 ` Alice Ryhl
2026-03-16 21:57 ` Gary Guo
2026-03-16 21:57 ` Gary Guo
2026-03-17 4:22 ` Alexandre Courbot
2026-03-17 4:22 ` Alexandre Courbot
2026-03-16 5:57 ` [PATCH v9 4/6] gpu: nova-core: Replace module_pci_driver! with explicit module init Timur Tabi
2026-03-16 16:28 ` Gary Guo
2026-03-16 5:57 ` [PATCH v9 5/6] gpu: nova-core: create debugfs root in " Timur Tabi
2026-03-16 16:28 ` Gary Guo
2026-03-16 5:57 ` [PATCH v9 6/6] gpu: nova-core: create GSP-RM logging buffers debugfs entries Timur Tabi
2026-03-16 16:29 ` Gary Guo
2026-03-16 22:05 ` [PATCH v9 0/6] gpu: nova-core: expose the logging buffers via debugfs John Hubbard
2026-03-17 1:53 ` Eliot Courtney
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=abh7UWSgRHtQlAxI@google.com \
--to=aliceryhl@google.com \
--cc=acourbot@nvidia.com \
--cc=dakr@kernel.org \
--cc=ecourtney@nvidia.com \
--cc=gary@garyguo.net \
--cc=joelagnelf@nvidia.com \
--cc=mmaurer@google.com \
--cc=nouveau@lists.freedesktop.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=ttabi@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.