Skip to content
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

rust: task: use safe current macro #1053

Open
wants to merge 32 commits into
base: rust-dev
Choose a base branch
from

Commits on Dec 28, 2023

  1. Configuration menu
    Copy the full SHA
    aa935a1 View commit details
    Browse the repository at this point in the history
  2. rust: upgrade to Rust 1.75.0

    This is the next upgrade to the Rust toolchain, from 1.74.1 to 1.75.0
    (i.e. the latest) [1].
    
    See the upgrade policy [2] and the comments on the first upgrade in
    commit 3ed03f4 ("rust: upgrade to Rust 1.68.2").
    
    # Unstable features
    
    The `const_maybe_uninit_zeroed` unstable feature [3] was stabilized in
    Rust 1.75.0, which we were using in the PHYLIB abstractions.
    
    The only unstable features allowed to be used outside the `kernel` crate
    are still `new_uninit,offset_of`, though other code to be upstreamed
    may increase the list.
    
    Please see [4] for details.
    
    # Other improvements
    
    Rust 1.75.0 stabilized `pointer_byte_offsets` [5] which we could
    potentially use as an alternative for `ptr_metadata` in the future.
    
    # Required changes
    
    For this upgrade, no changes were required (i.e. on our side).
    
    # `alloc` upgrade and reviewing
    
    The vast majority of changes are due to our `alloc` fork being upgraded
    at once.
    
    There are two kinds of changes to be aware of: the ones coming from
    upstream, which we should follow as closely as possible, and the updates
    needed in our added fallible APIs to keep them matching the newer
    infallible APIs coming from upstream.
    
    Instead of taking a look at the diff of this patch, an alternative
    approach is reviewing a diff of the changes between upstream `alloc` and
    the kernel's. This allows to easily inspect the kernel additions only,
    especially to check if the fallible methods we already have still match
    the infallible ones in the new version coming from upstream.
    
    Another approach is reviewing the changes introduced in the additions in
    the kernel fork between the two versions. This is useful to spot
    potentially unintended changes to our additions.
    
    To apply these approaches, one may follow steps similar to the following
    to generate a pair of patches that show the differences between upstream
    Rust and the kernel (for the subset of `alloc` we use) before and after
    applying this patch:
    
        # Get the difference with respect to the old version.
        git -C rust checkout $(linux/scripts/min-tool-version.sh rustc)
        git -C linux ls-tree -r --name-only HEAD -- rust/alloc |
            cut -d/ -f3- |
            grep -Fv README.md |
            xargs -IPATH cp rust/library/alloc/src/PATH linux/rust/alloc/PATH
        git -C linux diff --patch-with-stat --summary -R > old.patch
        git -C linux restore rust/alloc
    
        # Apply this patch.
        git -C linux am rust-upgrade.patch
    
        # Get the difference with respect to the new version.
        git -C rust checkout $(linux/scripts/min-tool-version.sh rustc)
        git -C linux ls-tree -r --name-only HEAD -- rust/alloc |
            cut -d/ -f3- |
            grep -Fv README.md |
            xargs -IPATH cp rust/library/alloc/src/PATH linux/rust/alloc/PATH
        git -C linux diff --patch-with-stat --summary -R > new.patch
        git -C linux restore rust/alloc
    
    Now one may check the `new.patch` to take a look at the additions (first
    approach) or at the difference between those two patches (second
    approach). For the latter, a side-by-side tool is recommended.
    
    Link: https://github.com/rust-lang/rust/blob/stable/RELEASES.md#version-1750-2023-12-28 [1]
    Link: https://rust-for-linux.com/rust-version-policy [2]
    Link: rust-lang/rust#91850 [3]
    Link: Rust-for-Linux#2 [4]
    Link: rust-lang/rust#96283 [5]
    Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
    Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
    Reviewed-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
    Link: https://lore.kernel.org/r/20231224172128.271447-1-ojeda@kernel.org
    ojeda authored and fbq committed Dec 28, 2023
    Configuration menu
    Copy the full SHA
    e562737 View commit details
    Browse the repository at this point in the history
  3. rust: file: add Rust abstraction for struct file

    This abstraction makes it possible to manipulate the open files for a
    process. The new `File` struct wraps the C `struct file`. When accessing
    it using the smart pointer `ARef<File>`, the pointer will own a
    reference count to the file. When accessing it as `&File`, then the
    reference does not own a refcount, but the borrow checker will ensure
    that the reference count does not hit zero while the `&File` is live.
    
    Since this is intended to manipulate the open files of a process, we
    introduce a `from_fd` constructor that corresponds to the C `fget`
    method. In future patches, it will become possible to create a new fd in
    a process and bind it to a `File`. Rust Binder will use these to send
    fds from one process to another.
    
    We also provide a method for accessing the file's flags. Rust Binder
    will use this to access the flags of the Binder fd to check whether the
    non-blocking flag is set, which affects what the Binder ioctl does.
    
    This introduces a struct for the EBADF error type, rather than just
    using the Error type directly. This has two advantages:
    * `File::from_fd` returns a `Result<ARef<File>, BadFdError>`, which the
      compiler will represent as a single pointer, with null being an error.
      This is possible because the compiler understands that `BadFdError`
      has only one possible value, and it also understands that the
      `ARef<File>` smart pointer is guaranteed non-null.
    * Additionally, we promise to users of the method that the method can
      only fail with EBADF, which means that they can rely on this promise
      without having to inspect its implementation.
    That said, there are also two disadvantages:
    * Defining additional error types involves boilerplate.
    * The question mark operator will only utilize the `From` trait once,
      which prevents you from using the question mark operator on
      `BadFdError` in methods that return some third error type that the
      kernel `Error` is convertible into. (However, it works fine in methods
      that return `Error`.)
    
    Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com>
    Co-developed-by: Daniel Xu <dxu@dxuuu.xyz>
    Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
    Co-developed-by: Alice Ryhl <aliceryhl@google.com>
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20231206-alice-file-v2-1-af617c0d9d94@google.com
    [boqun: Resolve conflicts against net-next]
    wedsonaf authored and fbq committed Dec 28, 2023
    Configuration menu
    Copy the full SHA
    39f11a3 View commit details
    Browse the repository at this point in the history
  4. rust: cred: add Rust abstraction for struct cred

    Add a wrapper around `struct cred` called `Credential`, and provide
    functionality to get the `Credential` associated with a `File`.
    
    Rust Binder must check the credentials of processes when they attempt to
    perform various operations, and these checks usually take a
    `&Credential` as parameter. The security_binder_set_context_mgr function
    would be one example. This patch is necessary to access these security_*
    methods from Rust.
    
    Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com>
    Co-developed-by: Alice Ryhl <aliceryhl@google.com>
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20231206-alice-file-v2-2-af617c0d9d94@google.com
    wedsonaf authored and fbq committed Dec 28, 2023
    Configuration menu
    Copy the full SHA
    1d0fab6 View commit details
    Browse the repository at this point in the history
  5. rust: security: add abstraction for secctx

    Adds an abstraction for viewing the string representation of a security
    context.
    
    This is needed by Rust Binder because it has feature where a process can
    view the string representation of the security context for incoming
    transactions. The process can use that to authenticate incoming
    transactions, and since the feature is provided by the kernel, the
    process can trust that the security context is legitimate.
    
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20231206-alice-file-v2-3-af617c0d9d94@google.com
    Darksonn authored and fbq committed Dec 28, 2023
    Configuration menu
    Copy the full SHA
    dab0fe4 View commit details
    Browse the repository at this point in the history
  6. rust: file: add FileDescriptorReservation

    Allow for the creation of a file descriptor in two steps: first, we
    reserve a slot for it, then we commit or drop the reservation. The first
    step may fail (e.g., the current process ran out of available slots),
    but commit and drop never fail (and are mutually exclusive).
    
    This is needed by Rust Binder when fds are sent from one process to
    another. It has to be a two-step process to properly handle the case
    where multiple fds are sent: The operation must fail or succeed
    atomically, which we achieve by first reserving the fds we need, and
    only installing the files once we have reserved enough fds to send the
    files.
    
    Fd reservations assume that the value of `current` does not change
    between the call to get_unused_fd_flags and the call to fd_install (or
    put_unused_fd). By not implementing the Send trait, this abstraction
    ensures that the `FileDescriptorReservation` cannot be moved into a
    different process.
    
    Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com>
    Co-developed-by: Alice Ryhl <aliceryhl@google.com>
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20231206-alice-file-v2-4-af617c0d9d94@google.com
    wedsonaf authored and fbq committed Dec 28, 2023
    Configuration menu
    Copy the full SHA
    5a5888c View commit details
    Browse the repository at this point in the history
  7. rust: file: add Kuid wrapper

    Adds a wrapper around `kuid_t` called `Kuid`. This allows us to define
    various operations on kuids such as equality and current_euid. It also
    lets us provide conversions from kuid into userspace values.
    
    Rust Binder needs these operations because it needs to compare kuids for
    equality, and it needs to tell userspace about the pid and uid of
    incoming transactions.
    
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20231206-alice-file-v2-5-af617c0d9d94@google.com
    Darksonn authored and fbq committed Dec 28, 2023
    Configuration menu
    Copy the full SHA
    e98a9c7 View commit details
    Browse the repository at this point in the history
  8. rust: file: add DeferredFdCloser

    To close an fd from kernel space, we could call `ksys_close`. However,
    if we do this to an fd that is held using `fdget`, then we may trigger a
    use-after-free. Introduce a helper that can be used to close an fd even
    if the fd is currently held with `fdget`. This is done by grabbing an
    extra refcount to the file and dropping it in a task work once we return
    to userspace.
    
    This is necessary for Rust Binder because otherwise the user might try
    to have Binder close its fd for /dev/binder, which would cause problems
    as this happens inside an ioctl on /dev/binder, and ioctls hold the fd
    using `fdget`.
    
    Additional motivation can be found in commit 80cd795 ("binder: fix
    use-after-free due to ksys_close() during fdget()") and in the comments
    on `binder_do_fd_close`.
    
    If there is some way to detect whether an fd is currently held with
    `fdget`, then this could be optimized to skip the allocation and task
    work when this is not the case. Another possible optimization would be
    to combine several fds into a single task work, since this is used with
    fd arrays that might hold several fds.
    
    That said, it might not be necessary to optimize it, because Rust Binder
    has two ways to send fds: BINDER_TYPE_FD and BINDER_TYPE_FDA. With
    BINDER_TYPE_FD, it is userspace's responsibility to close the fd, so
    this mechanism is used only by BINDER_TYPE_FDA, but fd arrays are used
    rarely these days.
    
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20231206-alice-file-v2-6-af617c0d9d94@google.com
    [boqun: Resolve conflicts against net-next]
    Darksonn authored and fbq committed Dec 28, 2023
    Configuration menu
    Copy the full SHA
    befd131 View commit details
    Browse the repository at this point in the history
  9. rust: file: add abstraction for poll_table

    The existing `CondVar` abstraction is a wrapper around `wait_list`, but
    it does not support all use-cases of the C `wait_list` type. To be
    specific, a `CondVar` cannot be registered with a `struct poll_table`.
    This limitation has the advantage that you do not need to call
    `synchronize_rcu` when destroying a `CondVar`.
    
    However, we need the ability to register a `poll_table` with a
    `wait_list` in Rust Binder. To enable this, introduce a type called
    `PollCondVar`, which is like `CondVar` except that you can register a
    `poll_table`. We also introduce `PollTable`, which is a safe wrapper
    around `poll_table` that is intended to be used with `PollCondVar`.
    
    The destructor of `PollCondVar` unconditionally calls `synchronize_rcu`
    to ensure that the removal of epoll waiters has fully completed before
    the `wait_list` is destroyed.
    
    That said, `synchronize_rcu` is rather expensive and is not needed in
    all cases: If we have never registered a `poll_table` with the
    `wait_list`, then we don't need to call `synchronize_rcu`. (And this is
    a common case in Binder - not all processes use Binder with epoll.) The
    current implementation does not account for this, but if we find that it
    is necessary to improve this, a future patch could change store a
    boolean next to the `wait_list` to keep track of whether a `poll_table`
    has ever been registered.
    
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20231206-alice-file-v2-7-af617c0d9d94@google.com
    [ boqun: Removes unused POLLFREE definition ]
    Darksonn authored and fbq committed Dec 28, 2023
    Configuration menu
    Copy the full SHA
    0d01533 View commit details
    Browse the repository at this point in the history
  10. rust: macros: add decl_generics to parse_generics()

    The generic parameters on a type definition can specify default values.
    Currently `parse_generics()` cannot handle this though. For example when
    parsing the following generics:
    
        <T: Clone, const N: usize = 0>
    
    The `impl_generics` will be set to `T: Clone, const N: usize = 0` and
    `ty_generics` will be set to `T, N`. Now using the `impl_generics` on an
    impl block:
    
        impl<$($impl_generics)*> Foo {}
    
    will result in invalid Rust code, because default values are only
    available on type definitions.
    
    Therefore add parsing support for generic parameter default values using
    a new kind of generics called `decl_generics` and change the old
    behavior of `impl_generics` to not contain the generic parameter default
    values.
    
    Now `Generics` has three fields:
    - `impl_generics`: the generics with bounds
      (e.g. `T: Clone, const N: usize`)
    - `decl_generics`: the generics with bounds and default values
      (e.g. `T: Clone, const N: usize = 0`)
    - `ty_generics`:  contains the generics without bounds and without
      default values (e.g. `T, N`)
    
    `impl_generics` is designed to be used on `impl<$impl_generics>`,
    `decl_generics` for the type definition, so `struct Foo<$decl_generics>`
    and `ty_generics` whenever you use the type, so `Foo<$ty_generics>`.
    
    Here is an example that uses all three different types of generics:
    
        let (Generics { decl_generics, impl_generics, ty_generics }, rest) = parse_generics(input);
        quote! {
            struct Foo<$($decl_generics)*> {
                // ...
            }
    
            impl<$impl_generics> Foo<$ty_generics> {
                fn foo() {
                    // ...
                }
            }
        }
    
    The next commit contains a fix to the `#[pin_data]` macro making it
    compatible with generic parameter default values by relying on this new
    behavior.
    
    Signed-off-by: Benno Lossin <benno.lossin@proton.me>
    Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
    Link: https://lore.kernel.org/r/20231213220447.3613500-1-benno.lossin@proton.me
    Benno Lossin authored and fbq committed Dec 28, 2023
    Configuration menu
    Copy the full SHA
    ba17aad View commit details
    Browse the repository at this point in the history
  11. rust: add improved version of ForeignOwnable::borrow_mut

    Previously, the `ForeignOwnable` trait had a method called `borrow_mut`
    that was intended to provide mutable access to the inner value. However,
    the method accidentally made it possible to change the address of the
    object being modified, which usually isn't what we want. (And when we
    want that, it can be done by calling `from_foreign` and `into_foreign`,
    like how the old `borrow_mut` was implemented.)
    
    In this patch, we introduce an alternate definition of `borrow_mut` that
    solves the previous problem. Conceptually, given a pointer type `P` that
    implements `ForeignOwnable`, the `borrow_mut` method gives you the same
    kind of access as an `&mut P` would, except that it does not let you
    change the pointer `P` itself.
    
    This is analogous to how the existing `borrow` method provides the same
    kind of access to the inner value as an `&P`.
    
    Note that for types like `Arc`, having an `&mut Arc<T>` only gives you
    immutable access to the inner `T`. This is because mutable references
    assume exclusive access, but there might be other handles to the same
    reference counted value, so the access isn't exclusive. The `Arc` type
    implements this by making `borrow_mut` return the same type as `borrow`.
    
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Reviewed-by: Benno Lossin <benno.lossin@proton.me>
    Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
    Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
    Link: https://lore.kernel.org/r/20230710074642.683831-1-aliceryhl@google.com
    Darksonn authored and fbq committed Dec 28, 2023
    Configuration menu
    Copy the full SHA
    884a0c6 View commit details
    Browse the repository at this point in the history
  12. rust: macros: allow generic parameter default values in #[pin_data]

    Add support for generic parameters defaults in `#[pin_data]` by using
    the newly introduced `decl_generics` instead of the `impl_generics`.
    
    Before this would not compile:
    
        #[pin_data]
        struct Foo<const N: usize = 0> {
            // ...
        }
    
    because it would be expanded to this:
    
        struct Foo<const N: usize = 0> {
            // ...
        }
    
        const _: () = {
            struct __ThePinData<const N: usize = 0> {
                __phantom: ::core::marker::PhantomData<fn(Foo<N>) -> Foo<N>>,
            }
            impl<const N: usize = 0> ::core::clone::Clone for __ThePinData<N> {
                fn clone(&self) -> Self {
                    *self
                }
            }
    
            // [...] rest of expansion omitted
        };
    
    The problem is with the `impl<const N: usize = 0>`, since that is
    invalid Rust syntax. It should not mention the default value at all,
    since default values only make sense on type definitions.
    
    The new `impl_generics` do not contain the default values, thus
    generating correct Rust code.
    
    This is used by the next commit that puts `#[pin_data]` on
    `kernel::workqueue::Work`.
    
    Signed-off-by: Benno Lossin <benno.lossin@proton.me>
    Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
    Reviewed-by: Gary Guo <gary@garyguo.net>
    Link: https://lore.kernel.org/r/20231213220447.3613500-2-benno.lossin@proton.me
    Benno Lossin authored and fbq committed Dec 28, 2023
    Configuration menu
    Copy the full SHA
    1fd25cc View commit details
    Browse the repository at this point in the history
  13. rust: Refactor the build target to allow the use of builtin targets

    Eventually we want all architectures to be using the target as defined
    by rustc. However currently some architectures can't do that and are
    using the target.json specification. This puts in place the foundation
    to allow the use of the builtin target definition or a target.json
    specification.
    
    Signed-off-by: Jamie Cunliffe <Jamie.Cunliffe@arm.com>
    Link: https://lore.kernel.org/r/20231020155056.3495121-2-Jamie.Cunliffe@arm.com
    JamieCunliffe authored and fbq committed Dec 28, 2023
    Configuration menu
    Copy the full SHA
    7ca8daf View commit details
    Browse the repository at this point in the history
  14. rust: workqueue: add #[pin_data] to Work

    The previous two patches made it possible to add `#[pin_data]` on
    structs with default generic parameter values.
    This patch makes `Work` use `#[pin_data]` and removes an invocation of
    `pin_init_from_closure`. This function is intended as a low level manual
    escape hatch, so it is better to rely on the safe `pin_init!` macro.
    
    Signed-off-by: Benno Lossin <benno.lossin@proton.me>
    Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
    Reviewed-by: Gary Guo <gary@garyguo.net>
    Link: https://lore.kernel.org/r/20231213220447.3613500-3-benno.lossin@proton.me
    Benno Lossin authored and fbq committed Dec 28, 2023
    Configuration menu
    Copy the full SHA
    8f7e376 View commit details
    Browse the repository at this point in the history
  15. arm64: rust: Enable Rust support for AArch64

    This commit provides the build flags for Rust for AArch64. The core Rust
    support already in the kernel does the rest. This enables the PAC ret
    and BTI options in the Rust build flags to match the options that are
    used when building C.
    
    The Rust samples have been tested with this commit.
    
    Signed-off-by: Jamie Cunliffe <Jamie.Cunliffe@arm.com>
    Acked-by: Will Deacon <will@kernel.org>
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
    Link: https://lore.kernel.org/r/20231020155056.3495121-3-Jamie.Cunliffe@arm.com
    JamieCunliffe authored and fbq committed Dec 28, 2023
    Configuration menu
    Copy the full SHA
    df91439 View commit details
    Browse the repository at this point in the history

Commits on Jan 4, 2024

  1. rust: task: add as_raw() to Task

    Added new function `Task::as_raw()` which returns the raw pointer
    for the underlying task struct. I also refactored `Task` to instead
    use the newly created function instead of `self.0.get()` as I feel
    like `self.as_raw()` is more intuitive.
    
    Signed-off-by: Antonio Hickey <antoniohickey99@gmail.com>
    antonio-hickey committed Jan 4, 2024
    Configuration menu
    Copy the full SHA
    f3bc6f9 View commit details
    Browse the repository at this point in the history
  2. rust: task: use safe current! macro

    Refactor the `Task::pid_in_current_ns()` to use the safe abstraction
    `current!()` instead of the unsafe `bindings::get_current()` binding.
    
    Signed-off-by: Antonio Hickey <antoniohickey99@gmail.com>
    antonio-hickey committed Jan 4, 2024
    Configuration menu
    Copy the full SHA
    b54bde5 View commit details
    Browse the repository at this point in the history

Commits on Jan 8, 2024

  1. rust: macros: add decl_generics to parse_generics()

    The generic parameters on a type definition can specify default values.
    Currently `parse_generics()` cannot handle this though. For example when
    parsing the following generics:
    
        <T: Clone, const N: usize = 0>
    
    The `impl_generics` will be set to `T: Clone, const N: usize = 0` and
    `ty_generics` will be set to `T, N`. Now using the `impl_generics` on an
    impl block:
    
        impl<$($impl_generics)*> Foo {}
    
    will result in invalid Rust code, because default values are only
    available on type definitions.
    
    Therefore add parsing support for generic parameter default values using
    a new kind of generics called `decl_generics` and change the old
    behavior of `impl_generics` to not contain the generic parameter default
    values.
    
    Now `Generics` has three fields:
    - `impl_generics`: the generics with bounds
      (e.g. `T: Clone, const N: usize`)
    - `decl_generics`: the generics with bounds and default values
      (e.g. `T: Clone, const N: usize = 0`)
    - `ty_generics`:  contains the generics without bounds and without
      default values (e.g. `T, N`)
    
    `impl_generics` is designed to be used on `impl<$impl_generics>`,
    `decl_generics` for the type definition, so `struct Foo<$decl_generics>`
    and `ty_generics` whenever you use the type, so `Foo<$ty_generics>`.
    
    Here is an example that uses all three different types of generics:
    
        let (Generics { decl_generics, impl_generics, ty_generics }, rest) = parse_generics(input);
        quote! {
            struct Foo<$($decl_generics)*> {
                // ...
            }
    
            impl<$impl_generics> Foo<$ty_generics> {
                fn foo() {
                    // ...
                }
            }
        }
    
    The next commit contains a fix to the `#[pin_data]` macro making it
    compatible with generic parameter default values by relying on this new
    behavior.
    
    Signed-off-by: Benno Lossin <benno.lossin@proton.me>
    Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
    Link: https://lore.kernel.org/r/20231213220447.3613500-1-benno.lossin@proton.me
    Benno Lossin authored and fbq committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    0e52e55 View commit details
    Browse the repository at this point in the history
  2. rust: macros: allow generic parameter default values in #[pin_data]

    Add support for generic parameters defaults in `#[pin_data]` by using
    the newly introduced `decl_generics` instead of the `impl_generics`.
    
    Before this would not compile:
    
        #[pin_data]
        struct Foo<const N: usize = 0> {
            // ...
        }
    
    because it would be expanded to this:
    
        struct Foo<const N: usize = 0> {
            // ...
        }
    
        const _: () = {
            struct __ThePinData<const N: usize = 0> {
                __phantom: ::core::marker::PhantomData<fn(Foo<N>) -> Foo<N>>,
            }
            impl<const N: usize = 0> ::core::clone::Clone for __ThePinData<N> {
                fn clone(&self) -> Self {
                    *self
                }
            }
    
            // [...] rest of expansion omitted
        };
    
    The problem is with the `impl<const N: usize = 0>`, since that is
    invalid Rust syntax. It should not mention the default value at all,
    since default values only make sense on type definitions.
    
    The new `impl_generics` do not contain the default values, thus
    generating correct Rust code.
    
    This is used by the next commit that puts `#[pin_data]` on
    `kernel::workqueue::Work`.
    
    Signed-off-by: Benno Lossin <benno.lossin@proton.me>
    Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
    Reviewed-by: Gary Guo <gary@garyguo.net>
    Link: https://lore.kernel.org/r/20231213220447.3613500-2-benno.lossin@proton.me
    Benno Lossin authored and fbq committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    9a1d84e View commit details
    Browse the repository at this point in the history
  3. rust: workqueue: add #[pin_data] to Work

    The previous two patches made it possible to add `#[pin_data]` on
    structs with default generic parameter values.
    This patch makes `Work` use `#[pin_data]` and removes an invocation of
    `pin_init_from_closure`. This function is intended as a low level manual
    escape hatch, so it is better to rely on the safe `pin_init!` macro.
    
    Signed-off-by: Benno Lossin <benno.lossin@proton.me>
    Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
    Reviewed-by: Gary Guo <gary@garyguo.net>
    Link: https://lore.kernel.org/r/20231213220447.3613500-3-benno.lossin@proton.me
    Benno Lossin authored and fbq committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    b01a973 View commit details
    Browse the repository at this point in the history
  4. rust: sync: add CondVar::notify_sync

    Wake up another thread synchronously.
    
    This method behaves like `notify_one`, except that it hints to the
    scheduler that the current thread is about to go to sleep, so it should
    schedule the target thread on the same CPU.
    
    This is used by Rust Binder as a performance optimization. When sending
    a transaction to a different process, we usually know which thread will
    handle it, so we can schedule that thread for execution next on this
    CPU for better cache locality.
    
    Reviewed-by: Benno Lossin <benno.lossin@proton.me>
    Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
    Reviewed-by: Tiago Lam <tiagolam@gmail.com>
    Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20240108-rb-new-condvar-methods-v4-1-88e0c871cc05@google.com
    Darksonn authored and fbq committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    d02944d View commit details
    Browse the repository at this point in the history
  5. rust: time: add msecs to jiffies conversion

    Defines type aliases and conversions for msecs and jiffies.
    
    This is used by Rust Binder for process freezing. There, we want to
    sleep until the freeze operation completes, but we want to be able to
    abort the process freezing if it doesn't complete within some timeout.
    The freeze timeout is supplied in msecs.
    
    Note that we need to convert to jiffies in Binder. It is not enough to
    introduce a variant of `CondVar::wait_timeout` that takes the timeout in
    msecs because we need to be able to restart the sleep with the remaining
    sleep duration if it is interrupted, and if the API takes msecs rather
    than jiffies, then that would require a conversion roundtrip jiffies->
    msecs->jiffies that is best avoided.
    
    Suggested-by: Boqun Feng <boqun.feng@gmail.com>
    Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
    Reviewed-by: Benno Lossin <benno.lossin@proton.me>
    Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
    Reviewed-by: Tiago Lam <tiagolam@gmail.com>
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20240108-rb-new-condvar-methods-v4-2-88e0c871cc05@google.com
    Darksonn authored and fbq committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    b13bfeb View commit details
    Browse the repository at this point in the history
  6. rust: sync: add CondVar::wait_timeout

    Sleep on a condition variable with a timeout.
    
    This is used by Rust Binder for process freezing. There, we want to
    sleep until the freeze operation completes, but we want to be able to
    abort the process freezing if it doesn't complete within some timeout.
    
    Note that it is not enough to avoid jiffies by introducing a variant of
    `CondVar::wait_timeout` that takes the timeout in msecs because we need
    to be able to restart the sleep with the remaining sleep duration if it
    is interrupted, and if the API takes msecs rather than jiffies, then
    that would require a conversion roundtrip jiffies->msecs->jiffies that
    is best avoided.
    
    Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
    Reviewed-by: Tiago Lam <tiagolam@gmail.com>
    Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20240108-rb-new-condvar-methods-v4-3-88e0c871cc05@google.com
    Darksonn authored and fbq committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    af3c12d View commit details
    Browse the repository at this point in the history
  7. rust: sync: update integer types in CondVar

    Reduce the chances of compilation failures due to integer type
    mismatches in `CondVar`.
    
    When an integer is defined using a #define in C, bindgen doesn't know
    which integer type it is supposed to be, so it will just use `u32` by
    default (if it fits in an u32). Whenever the right type is something
    else, we insert a cast in Rust. However, this means that the code has a
    lot of extra casts, and sometimes the code will be missing casts if u32
    happens to be correct on the developer's machine, even though the type
    might be something else on a different platform.
    
    This patch updates all uses of such constants in
    `rust/kernel/sync/condvar.rs` to use constants defined with the right
    type. This allows us to remove various unnecessary casts, while also
    future-proofing for the case where `unsigned int != u32`.
    
    I wrote this patch at the suggestion of Benno in [1].
    
    Link: https://lore.kernel.org/all/nAEg-6vbtX72ZY3oirDhrSEf06TBWmMiTt73EklMzEAzN4FD4mF3TPEyAOxBZgZtjzoiaBYtYr3s8sa9wp1uYH9vEWRf2M-Lf4I0BY9rAgk=@proton.me/ [1]
    Suggested-by: Benno Lossin <benno.lossin@proton.me>
    Reviewed-by: Tiago Lam <tiagolam@gmail.com>
    Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
    Reviewed-by: Benno Lossin <benno.lossin@proton.me>
    Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20240108-rb-new-condvar-methods-v4-4-88e0c871cc05@google.com
    Darksonn authored and fbq committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    80a1985 View commit details
    Browse the repository at this point in the history
  8. rust: file: add Rust abstraction for struct file

    This abstraction makes it possible to manipulate the open files for a
    process. The new `File` struct wraps the C `struct file`. When accessing
    it using the smart pointer `ARef<File>`, the pointer will own a
    reference count to the file. When accessing it as `&File`, then the
    reference does not own a refcount, but the borrow checker will ensure
    that the reference count does not hit zero while the `&File` is live.
    
    Since this is intended to manipulate the open files of a process, we
    introduce a `from_fd` constructor that corresponds to the C `fget`
    method. In future patches, it will become possible to create a new fd in
    a process and bind it to a `File`. Rust Binder will use these to send
    fds from one process to another.
    
    We also provide a method for accessing the file's flags. Rust Binder
    will use this to access the flags of the Binder fd to check whether the
    non-blocking flag is set, which affects what the Binder ioctl does.
    
    This introduces a struct for the EBADF error type, rather than just
    using the Error type directly. This has two advantages:
    * `File::from_fd` returns a `Result<ARef<File>, BadFdError>`, which the
      compiler will represent as a single pointer, with null being an error.
      This is possible because the compiler understands that `BadFdError`
      has only one possible value, and it also understands that the
      `ARef<File>` smart pointer is guaranteed non-null.
    * Additionally, we promise to users of the method that the method can
      only fail with EBADF, which means that they can rely on this promise
      without having to inspect its implementation.
    That said, there are also two disadvantages:
    * Defining additional error types involves boilerplate.
    * The question mark operator will only utilize the `From` trait once,
      which prevents you from using the question mark operator on
      `BadFdError` in methods that return some third error type that the
      kernel `Error` is convertible into. (However, it works fine in methods
      that return `Error`.)
    
    Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com>
    Co-developed-by: Daniel Xu <dxu@dxuuu.xyz>
    Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
    Co-developed-by: Alice Ryhl <aliceryhl@google.com>
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20231206-alice-file-v2-1-af617c0d9d94@google.com
    [boqun: Resolve conflicts against net-next]
    wedsonaf authored and fbq committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    5f46355 View commit details
    Browse the repository at this point in the history
  9. rust: cred: add Rust abstraction for struct cred

    Add a wrapper around `struct cred` called `Credential`, and provide
    functionality to get the `Credential` associated with a `File`.
    
    Rust Binder must check the credentials of processes when they attempt to
    perform various operations, and these checks usually take a
    `&Credential` as parameter. The security_binder_set_context_mgr function
    would be one example. This patch is necessary to access these security_*
    methods from Rust.
    
    Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com>
    Co-developed-by: Alice Ryhl <aliceryhl@google.com>
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20231206-alice-file-v2-2-af617c0d9d94@google.com
    wedsonaf authored and fbq committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    87c2ee2 View commit details
    Browse the repository at this point in the history
  10. rust: security: add abstraction for secctx

    Adds an abstraction for viewing the string representation of a security
    context.
    
    This is needed by Rust Binder because it has feature where a process can
    view the string representation of the security context for incoming
    transactions. The process can use that to authenticate incoming
    transactions, and since the feature is provided by the kernel, the
    process can trust that the security context is legitimate.
    
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20231206-alice-file-v2-3-af617c0d9d94@google.com
    Darksonn authored and fbq committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    31608a9 View commit details
    Browse the repository at this point in the history
  11. rust: file: add FileDescriptorReservation

    Allow for the creation of a file descriptor in two steps: first, we
    reserve a slot for it, then we commit or drop the reservation. The first
    step may fail (e.g., the current process ran out of available slots),
    but commit and drop never fail (and are mutually exclusive).
    
    This is needed by Rust Binder when fds are sent from one process to
    another. It has to be a two-step process to properly handle the case
    where multiple fds are sent: The operation must fail or succeed
    atomically, which we achieve by first reserving the fds we need, and
    only installing the files once we have reserved enough fds to send the
    files.
    
    Fd reservations assume that the value of `current` does not change
    between the call to get_unused_fd_flags and the call to fd_install (or
    put_unused_fd). By not implementing the Send trait, this abstraction
    ensures that the `FileDescriptorReservation` cannot be moved into a
    different process.
    
    Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com>
    Co-developed-by: Alice Ryhl <aliceryhl@google.com>
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20231206-alice-file-v2-4-af617c0d9d94@google.com
    wedsonaf authored and fbq committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    fd6acd6 View commit details
    Browse the repository at this point in the history
  12. rust: file: add Kuid wrapper

    Adds a wrapper around `kuid_t` called `Kuid`. This allows us to define
    various operations on kuids such as equality and current_euid. It also
    lets us provide conversions from kuid into userspace values.
    
    Rust Binder needs these operations because it needs to compare kuids for
    equality, and it needs to tell userspace about the pid and uid of
    incoming transactions.
    
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20231206-alice-file-v2-5-af617c0d9d94@google.com
    [boqun: Resolve conflicts with wait_timeout patchset]
    Darksonn authored and fbq committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    8257138 View commit details
    Browse the repository at this point in the history
  13. rust: file: add DeferredFdCloser

    To close an fd from kernel space, we could call `ksys_close`. However,
    if we do this to an fd that is held using `fdget`, then we may trigger a
    use-after-free. Introduce a helper that can be used to close an fd even
    if the fd is currently held with `fdget`. This is done by grabbing an
    extra refcount to the file and dropping it in a task work once we return
    to userspace.
    
    This is necessary for Rust Binder because otherwise the user might try
    to have Binder close its fd for /dev/binder, which would cause problems
    as this happens inside an ioctl on /dev/binder, and ioctls hold the fd
    using `fdget`.
    
    Additional motivation can be found in commit 80cd795 ("binder: fix
    use-after-free due to ksys_close() during fdget()") and in the comments
    on `binder_do_fd_close`.
    
    If there is some way to detect whether an fd is currently held with
    `fdget`, then this could be optimized to skip the allocation and task
    work when this is not the case. Another possible optimization would be
    to combine several fds into a single task work, since this is used with
    fd arrays that might hold several fds.
    
    That said, it might not be necessary to optimize it, because Rust Binder
    has two ways to send fds: BINDER_TYPE_FD and BINDER_TYPE_FDA. With
    BINDER_TYPE_FD, it is userspace's responsibility to close the fd, so
    this mechanism is used only by BINDER_TYPE_FDA, but fd arrays are used
    rarely these days.
    
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20231206-alice-file-v2-6-af617c0d9d94@google.com
    [boqun: Resolve conflicts against net-next]
    Darksonn authored and fbq committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    a49b634 View commit details
    Browse the repository at this point in the history
  14. rust: file: add abstraction for poll_table

    The existing `CondVar` abstraction is a wrapper around `wait_list`, but
    it does not support all use-cases of the C `wait_list` type. To be
    specific, a `CondVar` cannot be registered with a `struct poll_table`.
    This limitation has the advantage that you do not need to call
    `synchronize_rcu` when destroying a `CondVar`.
    
    However, we need the ability to register a `poll_table` with a
    `wait_list` in Rust Binder. To enable this, introduce a type called
    `PollCondVar`, which is like `CondVar` except that you can register a
    `poll_table`. We also introduce `PollTable`, which is a safe wrapper
    around `poll_table` that is intended to be used with `PollCondVar`.
    
    The destructor of `PollCondVar` unconditionally calls `synchronize_rcu`
    to ensure that the removal of epoll waiters has fully completed before
    the `wait_list` is destroyed.
    
    That said, `synchronize_rcu` is rather expensive and is not needed in
    all cases: If we have never registered a `poll_table` with the
    `wait_list`, then we don't need to call `synchronize_rcu`. (And this is
    a common case in Binder - not all processes use Binder with epoll.) The
    current implementation does not account for this, but if we find that it
    is necessary to improve this, a future patch could change store a
    boolean next to the `wait_list` to keep track of whether a `poll_table`
    has ever been registered.
    
    Signed-off-by: Alice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20231206-alice-file-v2-7-af617c0d9d94@google.com
    [ boqun: Removes unused POLLFREE definition ]
    Darksonn authored and fbq committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    779be36 View commit details
    Browse the repository at this point in the history

Commits on Jan 16, 2024

  1. Configuration menu
    Copy the full SHA
    7822673 View commit details
    Browse the repository at this point in the history