All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alice Ryhl <aliceryhl@google.com>
To: Timur Tabi <ttabi@nvidia.com>
Cc: Miguel Ojeda <ojeda@kernel.org>,
	Danilo Krummrich <dakr@kernel.org>, Gary Guo <gary@garyguo.net>,
	mmaurer@google.com, Alexandre Courbot <acourbot@nvidia.com>,
	Joel Fernandes <joelagnelf@nvidia.com>,
	ecourtney@nvidia.com, rust-for-linux@vger.kernel.org,
	nouveau@lists.freedesktop.org
Subject: Re: [PATCH v9 2/6] rust: uaccess: add write_dma() for copying from DMA buffers to userspace
Date: Mon, 16 Mar 2026 20:42:14 +0000	[thread overview]
Message-ID: <abhrJgPEiIRCvmwe@google.com> (raw)
In-Reply-To: <20260316055736.1690546-3-ttabi@nvidia.com>

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.

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.

> +    /// Writes raw data to this user pointer from a DMA coherent allocation.
> +    ///
> +    /// # Arguments
> +    ///
> +    /// * `data` - The DMA coherent allocation to copy from.
> +    /// * `offset` - The byte offset into `data` to start copying from.
> +    /// * `count` - The number of bytes to copy.

This is not the usual Rust style for documentation. We would generally
just write it in words:

	Copies `count` bytes from `alloc` starting from `offset` into
	this userspace slice.

Yes, argument lists are *occassionally* used, but it's rare.

> +    /// # Errors
> +    ///
> +    /// Returns [`EOVERFLOW`] if `offset + count` overflows.
> +    /// Returns [`ERANGE`] if `offset + count` exceeds the size of `data`, or `count` exceeds
> +    ///     the size of the user-space buffer.
> +    /// Returns [`EFAULT`] if the write happens on a bad address, or if the write goes out of
> +    ///     bounds of this [`UserSliceWriter`].

Using a list to format the possible errors seems sensible to me. But I
don't think you intended for this to be rendered like this in the final
docs:

	Returns `EOVERFLOW` if `offset + count` overflows. Returns
	`ERANGE` if `offset + count` exceeds the size of `data`, or
	`count` exceeds the size of the user-space buffer. Returns
	`EFAULT` if the write happens on a bad address, or if the
	write goes out of bounds of this `UserSliceWriter`.

Please use a markdown list to format this, and check the generated html
docs.

Alice

WARNING: multiple messages have this Message-ID (diff)
From: Alice Ryhl <aliceryhl@google.com>
To: Timur Tabi <ttabi@nvidia.com>
Cc: Miguel Ojeda <ojeda@kernel.org>,
	Danilo Krummrich <dakr@kernel.org>, Gary Guo <gary@garyguo.net>,
	 mmaurer@google.com, Alexandre Courbot <acourbot@nvidia.com>,
	 John Hubbard <jhubbard@nvidia.com>,
	Joel Fernandes <joelagnelf@nvidia.com>,
	ecourtney@nvidia.com,  rust-for-linux@vger.kernel.org,
	nouveau@lists.freedesktop.org
Subject: Re: [PATCH v9 2/6] rust: uaccess: add write_dma() for copying from DMA buffers to userspace
Date: Mon, 16 Mar 2026 20:42:14 +0000	[thread overview]
Message-ID: <abhrJgPEiIRCvmwe@google.com> (raw)
In-Reply-To: <20260316055736.1690546-3-ttabi@nvidia.com>

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.

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.

> +    /// Writes raw data to this user pointer from a DMA coherent allocation.
> +    ///
> +    /// # Arguments
> +    ///
> +    /// * `data` - The DMA coherent allocation to copy from.
> +    /// * `offset` - The byte offset into `data` to start copying from.
> +    /// * `count` - The number of bytes to copy.

This is not the usual Rust style for documentation. We would generally
just write it in words:

	Copies `count` bytes from `alloc` starting from `offset` into
	this userspace slice.

Yes, argument lists are *occassionally* used, but it's rare.

> +    /// # Errors
> +    ///
> +    /// Returns [`EOVERFLOW`] if `offset + count` overflows.
> +    /// Returns [`ERANGE`] if `offset + count` exceeds the size of `data`, or `count` exceeds
> +    ///     the size of the user-space buffer.
> +    /// Returns [`EFAULT`] if the write happens on a bad address, or if the write goes out of
> +    ///     bounds of this [`UserSliceWriter`].

Using a list to format the possible errors seems sensible to me. But I
don't think you intended for this to be rendered like this in the final
docs:

	Returns `EOVERFLOW` if `offset + count` overflows. Returns
	`ERANGE` if `offset + count` exceeds the size of `data`, or
	`count` exceeds the size of the user-space buffer. Returns
	`EFAULT` if the write happens on a bad address, or if the
	write goes out of bounds of this `UserSliceWriter`.

Please use a markdown list to format this, and check the generated html
docs.

Alice

  reply	other threads:[~2026-03-16 20:42 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 [this message]
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
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=abhrJgPEiIRCvmwe@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.