All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boqun Feng <boqun.feng@gmail.com>
To: Benno Lossin <benno.lossin@proton.me>
Cc: "Alice Ryhl" <aliceryhl@google.com>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Matthew Wilcox" <willy@infradead.org>,
	"Al Viro" <viro@zeniv.linux.org.uk>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	"Kees Cook" <keescook@chromium.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Wedson Almeida Filho" <wedsonaf@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Andreas Hindborg" <a.hindborg@samsung.com>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Arve Hjønnevåg" <arve@android.com>,
	"Todd Kjos" <tkjos@android.com>,
	"Martijn Coenen" <maco@android.com>,
	"Joel Fernandes" <joel@joelfernandes.org>,
	"Carlos Llamas" <cmllamas@google.com>,
	"Suren Baghdasaryan" <surenb@google.com>,
	"Arnd Bergmann" <arnd@arndb.de>,
	"Trevor Gross" <tmgross@umich.edu>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	rust-for-linux@vger.kernel.org,
	"Christian Brauner" <brauner@kernel.org>
Subject: Re: [PATCH v6 4/4] rust: add abstraction for `struct page`
Date: Fri, 19 Apr 2024 10:23:44 -0700	[thread overview]
Message-ID: <ZiKooOjXh209i8je@boqun-archlinux> (raw)
In-Reply-To: <079c88af-2e6d-45fe-bf58-afebbf7583b4@proton.me>

On Fri, Apr 19, 2024 at 08:36:11AM +0000, Benno Lossin wrote:
> On 19.04.24 01:04, Boqun Feng wrote:
> > On Thu, Apr 18, 2024 at 03:56:11PM -0700, Boqun Feng wrote:
> >> On Thu, Apr 18, 2024 at 10:08:40PM +0000, Benno Lossin wrote:
> >>> On 18.04.24 20:52, Boqun Feng wrote:
> >>>> On Thu, Apr 18, 2024 at 08:59:20AM +0000, Alice Ryhl wrote:
> >>>>> +    /// Runs a piece of code with a raw pointer to a slice of this page, with bounds checking.
> >>>>> +    ///
> >>>>> +    /// If `f` is called, then it will be called with a pointer that points at `off` bytes into the
> >>>>> +    /// page, and the pointer will be valid for at least `len` bytes. The pointer is only valid on
> >>>>> +    /// this task, as this method uses a local mapping.
> >>>>> +    ///
> >>>>> +    /// If `off` and `len` refers to a region outside of this page, then this method returns
> >>>>> +    /// `EINVAL` and does not call `f`.
> >>>>> +    ///
> >>>>> +    /// # Using the raw pointer
> >>>>> +    ///
> >>>>> +    /// It is up to the caller to use the provided raw pointer correctly. The pointer is valid for
> >>>>> +    /// `len` bytes and for the duration in which the closure is called. The pointer might only be
> >>>>> +    /// mapped on the current thread, and when that is the case, dereferencing it on other threads
> >>>>> +    /// is UB. Other than that, the usual rules for dereferencing a raw pointer apply: don't cause
> >>>>> +    /// data races, the memory may be uninitialized, and so on.
> >>>>> +    ///
> >>>>> +    /// If multiple threads map the same page at the same time, then they may reference with
> >>>>> +    /// different addresses. However, even if the addresses are different, the underlying memory is
> >>>>> +    /// still the same for these purposes (e.g., it's still a data race if they both write to the
> >>>>> +    /// same underlying byte at the same time).
> >>>>> +    fn with_pointer_into_page<T>(
> >>>>> +        &self,
> >>>>> +        off: usize,
> >>>>> +        len: usize,
> >>>>> +        f: impl FnOnce(*mut u8) -> Result<T>,
> >>>>
> >>>> I wonder whether the way to go here is making this function signature:
> >>>>
> >>>>       fn with_slice_in_page<T> (
> >>>>           &self,
> >>>> 	       off: usize,
> >>>> 	       len: usize,
> >>>> 	       f: iml FnOnce(&UnsafeCell<[u8]>) -> Result<T>
> >>>>       ) -> Result<T>
> >>>>
> >>>> , because in this way, it makes a bit more clear that what memory that
> >>>> `f` can access, in other words, the users are less likely to use the
> >>>> pointer in a wrong way.
> >>>>
> >>>> But that depends on whether `&UnsafeCell<[u8]>` is the correct
> >>>> abstraction and the ecosystem around it: for example, I feel like these
> >>>> two functions:
> >>>>
> >>>> 	    fn len(slice: &UnsafeCell<[u8]>) -> usize
> >>>> 	    fn as_ptr(slice: &UnsafeCell<[u8]>) -> *mut u8
> >>>>
> >>>> should be trivially safe, but I might be wrong. Again this is just for
> >>>> future discussion.
> >>>
> >>> I think the "better" type would be `&[UnsafeCell<u8>]`. Since there you
> >>> can always access the length.
> >>>
> >>
> >> Hmm.. here is the thing, having `&UnsafeCell<[u8]>` means having a `*mut
> >> [u8]>`, and it should always be safe to get a "length" of `*mut [u8]`,
> >> right? I haven't found any method doing that, but the length should be
> >> just a part of fat pointer, so I think getting that is a defined
> >> behavior. But maybe I'm missing something.
> 
> There is `to_raw_parts` [1], but that is unstable. (Note that
> `<[T] as Pointee>::Metadata = usize`, see [2])
> 

Oh, that's good to know, thank you! ;-)

> >>
> > 
> > Hmm... but I guess one of the problems of this approach, is how to
> > construct a `&UnsafeCell<[u8]>` from a pointer and length...
> 
> We could use `from_raw_parts` [3]. But when making the slice the outer
> type, we can use a stable function to convert a pointer and a length to
> a slice [4].
> 

Yes, but there appears no way to get a pointer with larger provenance
from a `&[UnsafeCell<u8>]`, right?

> > 
> > Regards,
> > Boqun
> > 
> >>> Another question would be if page allows for uninitialized bits, in that
> >>> case, we would need `&[Opaque<u8>]`.
> >>>
> >>
> >> Yes, or `&Opaque<[u8>]`.
> 
> I don't think that putting the slice on the inside is what we want. Also

Hmm.. why? So in `&UnsafeCell<[u8]>` vs `&[UnsafeCell<u8>]` case, I
think the former represent "a slice of u8 that can be modified in the
same time" very well, and this is what a pointer-and-length pair usually
represents in kernel, I think. But yes, the latter is OK to me as well,
just hard to play the provenance game I guess?

> note that `Opaque<T>` requires that `T: Sized` and that is not the case
> for `[u8]`.

Oh, you're right. In case of MaybeUninit, it requires `T: Sized`, so
`Opaque<[u8]>` doesn't quite work.

Moving forward, maybe the first step is to see whether `&[Opaque<u8>]`
and `&[UnsafeCell<u8>]` can have a good way to generate a pointer with
proper provenance? Time to ping t-opsem maybe?

Regards,
Boqun

> 
> [1]: https://doc.rust-lang.org/nightly/core/primitive.pointer.html#method.to_raw_parts
> [2]: https://doc.rust-lang.org/nightly/core/ptr/trait.Pointee.html#pointer-metadata
> [3]: https://doc.rust-lang.org/nightly/core/ptr/fn.from_raw_parts.html
> [4]: https://doc.rust-lang.org/nightly/core/slice/fn.from_raw_parts.html
> 
> -- 
> Cheers,
> Benno
> 

  reply	other threads:[~2024-04-19 17:24 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-18  8:59 [PATCH v6 0/4] Memory management patches needed by Rust Binder Alice Ryhl
2024-04-18  8:59 ` [PATCH v6 1/4] rust: uaccess: add userspace pointers Alice Ryhl
2024-04-19 17:11   ` Boqun Feng
2024-04-19 18:12     ` Alice Ryhl
2024-04-18  8:59 ` [PATCH v6 2/4] uaccess: always export _copy_[from|to]_user with CONFIG_RUST Alice Ryhl
2024-05-14 17:27   ` Andrew Morton
2024-05-15  7:34     ` Arnd Bergmann
2024-04-18  8:59 ` [PATCH v6 3/4] rust: uaccess: add typed accessors for userspace pointers Alice Ryhl
2024-04-18 13:01   ` Benno Lossin
2024-04-18 13:17     ` Alice Ryhl
2024-04-18 16:23       ` Benno Lossin
2024-04-18 17:19         ` Boqun Feng
2024-04-18 19:35           ` Alice Ryhl
2024-04-18 20:01             ` Boqun Feng
2024-04-18 17:52     ` Trevor Gross
2024-04-25 16:13   ` Gary Guo
2024-04-26  7:13     ` Alice Ryhl
2024-04-18  8:59 ` [PATCH v6 4/4] rust: add abstraction for `struct page` Alice Ryhl
2024-04-18 18:52   ` Boqun Feng
2024-04-18 22:08     ` Benno Lossin
2024-04-18 22:56       ` Boqun Feng
2024-04-18 23:04         ` Boqun Feng
2024-04-19  8:36           ` Benno Lossin
2024-04-19 17:23             ` Boqun Feng [this message]
2024-04-19 19:24               ` Benno Lossin
2024-04-19 19:35                 ` Boqun Feng
2024-04-25 16:20         ` Gary Guo

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=ZiKooOjXh209i8je@boqun-archlinux \
    --to=boqun.feng@gmail.com \
    --cc=a.hindborg@samsung.com \
    --cc=akpm@linux-foundation.org \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=arnd@arndb.de \
    --cc=arve@android.com \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=brauner@kernel.org \
    --cc=cmllamas@google.com \
    --cc=gary@garyguo.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=joel@joelfernandes.org \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=maco@android.com \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=surenb@google.com \
    --cc=tkjos@android.com \
    --cc=tmgross@umich.edu \
    --cc=viro@zeniv.linux.org.uk \
    --cc=wedsonaf@gmail.com \
    --cc=willy@infradead.org \
    /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.