From nobody Sun Feb 8 23:33:13 2026 Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5064D22171A; Sat, 10 May 2025 09:33:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746869591; cv=none; b=RMibqremqdHlLQpqtVH38LLEo1jW98qis/H5w2nLqZsd1eZjRwYv5BznMSPDat+npYwaeW+z8I8KUwmtUs6XlPHlP6O93o7IZcxr7S/LK5bMt1sZaZwlHaeQY+hKFRv1+iEOTXdTjJJbBzQaGOIlFo1MhYImj7yo5my9yskphVg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746869591; c=relaxed/simple; bh=dWjiyob69G2GucTul/lsXlGpP89mKJGQ4P8+IWoJ7pA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IpqKIPQCb2Q0KeeFqdFQk+nP8qolfe3nj5scFeHNhj/+6hbxEx0UBxvSCoAhood7WUNbk358D+BcHqt1xYG++JCSbJ4vcp6weFEBkJauilvEtytrJ61HJbLPyImV2/3oKJwHXeYozwjrjYdBF6GhcFfCqzgBERRwRhrNvpuADj0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=gfGkughh; arc=none smtp.client-ip=209.85.221.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gfGkughh" Received: by mail-wr1-f42.google.com with SMTP id ffacd0b85a97d-3a1b8e8b2b2so1284743f8f.2; Sat, 10 May 2025 02:33:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746869587; x=1747474387; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=SOE7sdT8D61vDqGwsVaxjwgujETa56pyZ4FYk1rPCD4=; b=gfGkughhRDp9XEwHhvE+jqkq90PrO7ZGIzuYUNKI4lYgaRpcjTE6mgnivB/CrG1+mF bLCdXrha99z03ztNIEe4ovu+HBgBeKPiNyw3qBTAYo7ueEgYTO6+THq7Q1ZTbsF1PjnV mJCtU+bCR6qZLiJ5eVzdwi0xf/W4lRTb7ROOSHaEHMML1NA20JM4RSgMdSa6zP+MfWZc /zP4GLSyGcbqhExQqA30YjFy7bD+3zQMXPzjjMZy/AkOPzAz3acMEZOHfMKOpq8bf04+ wGane6K5zgN+6be+wOE+32iA+f6hNSJ4f1qsXrXZmpwyjggNA10Z9BlYa+y+BzvP4uey GyQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746869587; x=1747474387; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=SOE7sdT8D61vDqGwsVaxjwgujETa56pyZ4FYk1rPCD4=; b=KlTPax8uR2vdLTiGvMneNZFNru2sLAUq/iPZvPG6KJ6JFnOl8rbpxAQPK07yxnisFt PuxU6FyiCs1lTkpWlgEy5y0nuYVpARZvuJixZ8UpBdfnmBdvu0HOUqNetRmPp1CofvSq XIBnmtWu/Gn9At2oWIz7JubH6kySqtFkkY7iXgB6iCejVoe4BKBdgJMhJgdFNjHeJkMQ DwJuThC9cN2Xu0NCuDwLdvOdOtLLjazXWhmUcJZ2UF12EYg34/StJWEvjXgoFJwtdpQx fxSWcaBug/Da9359ZrAuFIPhvU5Krxb8bixCKKVWBHcS0lgOAagxfvqueLrfIZkAWSWo 9jQQ== X-Forwarded-Encrypted: i=1; AJvYcCXNn46HKBaZQFqrVJRUKB1A4Yy8IFFdDFxkRNFiMcz3Kg4roTbi1BRWJt+uoimdKCritK4h/QY6FigtAjk7ug==@vger.kernel.org X-Gm-Message-State: AOJu0YwLTJAzU35q6BScfyPk68BCQAX/A0582OWh6gbDlbdB/5vBJ1mx K3vLOZjOwwCYd52QgmpKdCd7J3/hyIcxFnjXbVcn01vP3QltDIzPWMhWY3fH X-Gm-Gg: ASbGncsOklf8Ezk+9c1wD5QHMrdixs+Pb2F2du+RS29HYWmfIyQplYJEASmVpzpdLHP g6a5d9BC3cuhe5YQy8ck8hY9RecPGUdVCUougp95m9Ze2OCtbXzGUCG1uknQxI5lg4yMc/vusQX oR8w3+LYh3TXMqPJHLRlZe1VXgPL1QET0ItD4/Rw75/otvy9wFOX1nWEzaC7zY9blPXtRryaHw4 sfsWjSzXjG/Fx4lVs4fXA+WQ57kTEB1rmUaAoSZznO4uYSgY92/8cZGz0ljj6+R5xEpekNkDHBN lAJkiu8u+LZ/HS23tbpAmQ1FTQvvxPP2yLLFmG8= X-Google-Smtp-Source: AGHT+IFVbblIDN2ouLSx9sgtkfmF6TDVCexrpp5Doe3paIz95KUyn+eXRyz6dYaHj9TZC+ejqCcpgg== X-Received: by 2002:a05:6000:401e:b0:3a0:aee0:c647 with SMTP id ffacd0b85a97d-3a1f64374e1mr5493421f8f.17.1746869586609; Sat, 10 May 2025 02:33:06 -0700 (PDT) Received: from [10.0.1.56] ([2001:871:22a:99c5::1ad1]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-3a1f57ddde0sm5981485f8f.14.2025.05.10.02.33.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 10 May 2025 02:33:06 -0700 (PDT) From: Christian Schrefl Date: Sat, 10 May 2025 11:32:26 +0200 Subject: [PATCH v3 1/3] rust: add UnsafePinned type Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250510-rust_unsafe_pinned-v3-1-57ce151123f9@gmail.com> References: <20250510-rust_unsafe_pinned-v3-0-57ce151123f9@gmail.com> In-Reply-To: <20250510-rust_unsafe_pinned-v3-0-57ce151123f9@gmail.com> To: Sky , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , =?utf-8?q?Gerald_Wisb=C3=B6ck?= , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt Cc: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, llvm@lists.linux.dev, Christian Schrefl X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1746869583; l=8523; i=chrisi.schrefl@gmail.com; s=20250119; h=from:subject:message-id; bh=dWjiyob69G2GucTul/lsXlGpP89mKJGQ4P8+IWoJ7pA=; b=qz6jwCq5QCTjxafiO7g3wJAMoBTTNDpYvHhtgDrKF8imb7cwNHmpLvQ6G4jXPxK2xqz+C6zf/ cgmCZYY7ltoAhopI0I0sjxOMih2ndKndO8ovfWHIXrlA7XwFUdnc4qu X-Developer-Key: i=chrisi.schrefl@gmail.com; a=ed25519; pk=EIyitYCrzxWlybrqoGqiL2jyvO7Vp9X40n0dQ6HE4oU= `UnsafePinned` is useful for cases where a value might be shared with C code but not directly used by it. In particular this is added for storing additional data in the `MiscDeviceRegistration` which will be shared between `fops->open` and the containing struct. Similar to `Opaque` but guarantees that the value is always initialized and that the inner value is dropped when `UnsafePinned` is dropped. This was originally proposed for the IRQ abstractions [0] and is also useful for other where the inner data may be aliased, but is always valid and automatic `Drop` is desired. Since then the `UnsafePinned` type was added to upstream Rust [1] by Sky as a unstable feature, therefore this patch implements the subset of the upstream API for the `UnsafePinned` type required for additional data in `MiscDeviceRegistration` and in the implementation of the `Opaque` type. Some differences to the upstream type definition are required in the kernel implementation, because upstream type uses some compiler changes to opt out of certain optimizations, this is documented in the documentation and a comment on the `UnsafePinned` type. The documentation on is based on the upstream rust documentation with minor modifications for the kernel implementation. Link: https://lore.kernel.org/rust-for-linux/CAH5fLgiOASgjoYKFz6kWwzLaH07Dq= P2ph+3YyCDh2+gYqGpABA@mail.gmail.com [0] Link: https://github.com/rust-lang/rust/pull/137043 [1] Suggested-by: Alice Ryhl Reviewed-by: Gerald Wisb=C3=B6ck Reviewed-by: Alice Ryhl Co-developed-by: Sky Signed-off-by: Sky Signed-off-by: Christian Schrefl --- rust/kernel/types.rs | 6 ++ rust/kernel/types/unsafe_pinned.rs | 113 +++++++++++++++++++++++++++++++++= ++++ 2 files changed, 119 insertions(+) diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index 9d0471afc9648f2973235488b441eb109069adb1..705f420fdfbc4a576de1c454657= 8f2f04cdf615e 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -253,6 +253,9 @@ fn drop(&mut self) { /// /// [`Opaque`] is meant to be used with FFI objects that are never inte= rpreted by Rust code. /// +/// In cases where the contained data is only used by Rust, is not allowed= to be +/// uninitialized and automatic [`Drop`] is desired [`UnsafePinned`] shoul= d be used instead. +/// /// It is used to wrap structs from the C side, like for example `Opaque`. /// It gets rid of all the usual assumptions that Rust has for a value: /// @@ -578,3 +581,6 @@ pub enum Either { /// [`NotThreadSafe`]: type@NotThreadSafe #[allow(non_upper_case_globals)] pub const NotThreadSafe: NotThreadSafe =3D PhantomData; + +mod unsafe_pinned; +pub use unsafe_pinned::UnsafePinned; diff --git a/rust/kernel/types/unsafe_pinned.rs b/rust/kernel/types/unsafe_= pinned.rs new file mode 100644 index 0000000000000000000000000000000000000000..612b67b400ff361335803c29799= b6aeb375ed52c --- /dev/null +++ b/rust/kernel/types/unsafe_pinned.rs @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +//! The contents of this file partially come from the Rust standard librar= y, hosted in +//! the repository, licensed under +//! "Apache-2.0 OR MIT" and adapted for kernel use. For copyright details, +//! see . +//! +//! This file provides a implementation / polyfill of a subset of the upst= ream +//! rust `UnsafePinned` type. For details on the difference to the upstream +//! implementation see the comment on the [`UnsafePinned`] struct definiti= on. + +use core::{cell::UnsafeCell, marker::PhantomPinned}; +use pin_init::{cast_pin_init, PinInit, Wrapper}; + +/// This type provides a way to opt-out of typical aliasing rules; +/// specifically, `&mut UnsafePinned` is not guaranteed to be a unique = pointer. +/// +/// However, even if you define your type like `pub struct Wrapper(UnsafeP= inned<...>)`, it is still +/// very risky to have an `&mut Wrapper` that aliases anything else. Many = functions that work +/// generically on `&mut T` assume that the memory that stores `T` is uniq= uely owned (such as +/// `mem::swap`). In other words, while having aliasing with `&mut Wrapper= ` is not immediate +/// Undefined Behavior, it is still unsound to expose such a mutable refer= ence to code you do not +/// control! Techniques such as pinning via [`Pin`](core::pin::Pin) are ne= eded to ensure soundness. +/// +/// Similar to [`UnsafeCell`], [`UnsafePinned`] will not usually show up in +/// the public API of a library. It is an internal implementation detail o= f libraries that need to +/// support aliasing mutable references. +/// +/// Further note that this does *not* lift the requirement that shared ref= erences must be read-only! +/// Use [`UnsafeCell`] for that. +/// +/// This type blocks niches the same way [`UnsafeCell`] does. +/// +/// # Kernel implementation notes +/// +/// This implementation works because of the "`!Unpin` hack" in rustc, whi= ch allows (some kinds of) +/// mutual aliasing of `!Unpin` types. This hack might be removed at some = point, after which only +/// the `core::pin::UnsafePinned` type will allow this behavior. In order = to simplify the migration +/// to future rust versions only this polyfill of this type should be used= when this behavior is +/// required. +// +// As opposed to the upstream Rust type this contains a `PhantomPinned` an= d `UnsafeCell` +// - `PhantomPinned` to ensure the struct always is `!Unpin` and thus enab= les the `!Unpin` hack. +// This causes the LLVM `noalias` and `dereferenceable` attributes to be= removed from +// `&mut !Unpin` types. +// - In order to disable niche optimizations this implementation uses `Uns= afeCell` internally, +// the upstream version however currently does not. This will most likel= y change in the future +// but for now we don't expose this in the documentation, since adding t= he guarantee is simpler +// than removing it. Meaning that for now the fact that `UnsafePinned` c= ontains an `UnsafeCell` +// must not be relied on (Other than the niche blocking). +// See this Rust tracking issue: https://github.com/rust-lang/rust/issue= s/137750 +#[repr(transparent)] +pub struct UnsafePinned { + _ph: PhantomPinned, + value: UnsafeCell, +} + +impl UnsafePinned { + /// Constructs a new instance of [`UnsafePinned`] which will wrap the = specified value. + /// + /// All access to the inner value through `&UnsafePinned` or `&mut = UnsafePinned` or + /// `Pin<&mut UnsafePinned>` requires `unsafe` code. + #[inline(always)] + #[must_use] + pub const fn new(value: T) -> Self { + UnsafePinned { + value: UnsafeCell::new(value), + _ph: PhantomPinned, + } + } +} +impl UnsafePinned { + /// Get read-only access to the contents of a shared `UnsafePinned`. + /// + /// Note that `&UnsafePinned` is read-only if `&T` is read-only. Th= is means that if there is + /// mutation of the `T`, future reads from the `*const T` returned her= e are UB! Use + /// [`UnsafeCell`] if you also need interior mutability. + /// + /// [`UnsafeCell`]: core::cell::UnsafeCell + /// + /// ```rust,no_build + /// use kernel::types::UnsafePinned; + /// + /// unsafe { + /// let mut x =3D UnsafePinned::new(0); + /// let ptr =3D x.get(); // read-only pointer, assumes immutability + /// x.get_mut_unchecked().write(1); + /// ptr.read(); // UB! + /// } + /// ``` + /// + /// Note that the `get_mut_unchecked` function used by this example is + /// currently not implemented in the kernel implementation. + #[inline(always)] + #[must_use] + pub const fn get(&self) -> *const T { + self.value.get() + } + + /// Gets a mutable pointer to the wrapped value. + #[inline(always)] + #[must_use] + pub const fn raw_get_mut(this: *mut Self) -> *mut T { + this as *mut T + } +} + +impl Wrapper for UnsafePinned { + fn pin_init(init: impl PinInit) -> impl PinInit { + // SAFETY: `UnsafePinned` has a compatible layout to `T`. + unsafe { cast_pin_init(init) } + } +} --=20 2.49.0 From nobody Sun Feb 8 23:33:13 2026 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ECFFB221D8B; Sat, 10 May 2025 09:33:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746869591; cv=none; b=Tl5vH2QcIW1vRABkiuwtJE0ciUJBHbgLNV5A/HBORlo+LtpImjzVgB9cY4ufY5AsPxShpa+KCQUbA1HJc57qwrqi0iwt58SQW2vmcUnJ87yDaNsBB2vqu+6F7oVj6Q5jGqPNhu9IudVoafw/s2OyCE89OzsD7WeAyUd6HqyWv70= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746869591; c=relaxed/simple; bh=OgwyE3W4j5m9tlImAIMzZFHkRczAKc1EPWHJolrN6PY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gEW4UKD2v3CLqKpOFqZ6D6ndTSRgt8uqpXs/XSdsSJvzXmTOFZSRbPAoApMyvOr5SetoWvfrh6spnfrJAMqcf9LPO86ikdsqoAFpLIXwakkV5Rg/J28yYBbipjk8WMDU/Wkvcr9+4lVQd6OGA4WiXYHPGaRqKR9Bx4Vfxr+m7UA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=F+1hr038; arc=none smtp.client-ip=209.85.128.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="F+1hr038" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-43cfecdd8b2so20371715e9.2; Sat, 10 May 2025 02:33:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746869588; x=1747474388; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=z2gCa+XcfQ3b3bjRPwVH7s9yFYkkubMVDYMxKJoALEk=; b=F+1hr038QLvFRGU4V+JGYz7jJdE6Q2FYk37SF8AbdZN6cXV+1Eu4HaG+esOgLNIRXO lY73L5rd72Yif9zZ7oEQxNkVHZV5w1bhd7FudZTcYm6NjedDncxgttqaNDk+UOlRMiL9 AHe8oJvTykvboUDj4D8MDDTjNH25ckapnkDIM9KoDBKS857YkXyi313s+y9LA8GRvrTQ 5HB/v7xTlTkRS9Lxxaq4IYC+ePfpfqNIXTpKBOKDjzVuOQ6Fb/Ro0bQvh7bWOUYas988 K88HxiPuBP518NOO0hZcuJ+DZZ3svPqGMYY3KjzjpC3R6ZyD2fxgQoo+NZS/L/m/y9sG cNig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746869588; x=1747474388; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=z2gCa+XcfQ3b3bjRPwVH7s9yFYkkubMVDYMxKJoALEk=; b=qlLz7ozcNbtloXnhgPEdpbokbkXAIX8jGXF+gSXC09FyivcbXCv4rmZwDnVs8NV24o bEOzI3Wio2Mg4cQMx4k1Yi2b7SGKH020PJxG8PtiuVvDwYpCyYBYZEFgdNZhQRruaPga cipGJ2aebXSLXOHXHDswqC8niq87Mkz4rscSjwew1Pm9ZiSRGLzwx1f/uF0sNRE++EEV ALMCivztI9rFhp01/DLHgGrg8CjYWvEM2CDulBL66Xtvw2/bRzpQAcsOtdqNZuNCpL7O C1sx1w1uzrLSZWaKX8rBcpHyGv5yqh/UFcUg+fKZtt0gbizFFcp/p93cOlLwFzaa2bry DaLw== X-Forwarded-Encrypted: i=1; AJvYcCWgg7pwHF9l1aA1QR2FeRqG6jjC/QQXCq+ncE7yEAEc1/y3ljDzHRH/tm50rEGewP3aSxUfGdEKG/HxFzxQ2w==@vger.kernel.org X-Gm-Message-State: AOJu0Yx3mB548nH5idUML2VXgTPPY4QXzsD8CH+CkUjMLDtvqgutagkN EBbUCTOi0ubon2NZGHhNchDu/qtoA/DeYAAAV1nhy+Cyy9xNYr6j95ERS3LC X-Gm-Gg: ASbGnctXwIXbUfusfNhoFvz3ATKqk0QMXjRUIIjRQL8zApeDUoLv9WF+3a2p8vZ5eQg ECFLwIak2KU5iCdVWq4AhE2St0RMFS11CIqNyO24hRtg//c40hZsQN9Ow4Owi3x3SPsr+YdtrGJ H9pwrpfQGAve5Zz9tSN/awSRLd8BjRc1ZlSKBePAHjLSPqXyeu34rXzzCAPJHy04W+XSL3zAMtE apHrpt5smXcg5hGjzHMxzyyjZym2/giNBQtWgbEFVdw4hkW81Z9RbkW6VGoC4bumy6s3ZoXOs4O cjYWAPh64n8bUMAsy/Kx6AkvZdralVph0vtjcSo= X-Google-Smtp-Source: AGHT+IGCm+4I7ZaGlYHiR2J16ZZQIaYmQgSVd6mmPWOubr1d7yq4g5DXGnEX67rQPLE0Uax9YD4P1g== X-Received: by 2002:a05:6000:2dc6:b0:3a1:f537:2206 with SMTP id ffacd0b85a97d-3a1f6488450mr5070543f8f.45.1746869588131; Sat, 10 May 2025 02:33:08 -0700 (PDT) Received: from [10.0.1.56] ([2001:871:22a:99c5::1ad1]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-3a1f57ddde0sm5981485f8f.14.2025.05.10.02.33.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 10 May 2025 02:33:07 -0700 (PDT) From: Christian Schrefl Date: Sat, 10 May 2025 11:32:27 +0200 Subject: [PATCH v3 2/3] rust: implement `Wrapper` for `Opaque` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250510-rust_unsafe_pinned-v3-2-57ce151123f9@gmail.com> References: <20250510-rust_unsafe_pinned-v3-0-57ce151123f9@gmail.com> In-Reply-To: <20250510-rust_unsafe_pinned-v3-0-57ce151123f9@gmail.com> To: Sky , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , =?utf-8?q?Gerald_Wisb=C3=B6ck?= , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt Cc: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, llvm@lists.linux.dev, Christian Schrefl , Benno Lossin X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1746869583; l=3333; i=chrisi.schrefl@gmail.com; s=20250119; h=from:subject:message-id; bh=OgwyE3W4j5m9tlImAIMzZFHkRczAKc1EPWHJolrN6PY=; b=fKi+kNNz853y23QUsUt4vMcszaYEaMI/4LXUXy3T0Tur8/tSKH8R36WcSvmAWK+AGJbKB/9Du ESDtg4zvXkHAn680z4jVmkiscF2SUb6WO6kRj7jNQmYcKH5VEBT2XqY X-Developer-Key: i=chrisi.schrefl@gmail.com; a=ed25519; pk=EIyitYCrzxWlybrqoGqiL2jyvO7Vp9X40n0dQ6HE4oU= Moves the implementation for `pin-init` from an associated function to the trait function of the `Wrapper` trait and extends the implementation to support pin-initializers with error types. This allows to declare functions that are generic over `Wrapper` types. Adds a use for the `Wrapper` trait in `revocable.rs`, to use the new `pin-init` function. This is currently the only usage in the kernel. Reviewed-by: Gerald Wisb=C3=B6ck Reviewed-by: Alice Ryhl Reviewed-by: Benno Lossin Signed-off-by: Christian Schrefl --- rust/kernel/revocable.rs | 2 ++ rust/kernel/types.rs | 25 +++++++++++++------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/rust/kernel/revocable.rs b/rust/kernel/revocable.rs index 1e5a9d25c21b279b01f90b02997492aa4880d84f..4db68ea2207ebafcc09d082fdc1= e281f31846a38 100644 --- a/rust/kernel/revocable.rs +++ b/rust/kernel/revocable.rs @@ -5,6 +5,8 @@ //! The [`Revocable`] type wraps other types and allows access to them to = be revoked. The existence //! of a [`RevocableGuard`] ensures that objects remain valid. =20 +use pin_init::Wrapper; + use crate::{bindings, prelude::*, sync::rcu, types::Opaque}; use core::{ marker::PhantomData, diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index 705f420fdfbc4a576de1c4546578f2f04cdf615e..f06e8720e012102e5c41e79fd97= b0607e927d71c 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -9,7 +9,7 @@ ops::{Deref, DerefMut}, ptr::NonNull, }; -use pin_init::{PinInit, Zeroable}; +use pin_init::{PinInit, Wrapper, Zeroable}; =20 /// Used to transfer ownership to and from foreign (non-Rust) languages. /// @@ -332,17 +332,6 @@ pub const fn uninit() -> Self { } } =20 - /// Create an opaque pin-initializer from the given pin-initializer. - pub fn pin_init(slot: impl PinInit) -> impl PinInit { - Self::ffi_init(|ptr: *mut T| { - // SAFETY: - // - `ptr` is a valid pointer to uninitialized memory, - // - `slot` is not accessed on error; the call is infallible, - // - `slot` is pinned in memory. - let _ =3D unsafe { PinInit::::__pinned_init(slot, ptr) }; - }) - } - /// Creates a pin-initializer from the given initializer closure. /// /// The returned initializer calls the given closure with the pointer = to the inner `T` of this @@ -393,6 +382,18 @@ pub const fn raw_get(this: *const Self) -> *mut T { UnsafeCell::raw_get(this.cast::>>()).cas= t::() } } +impl Wrapper for Opaque { + /// Create an opaque pin-initializer from the given pin-initializer. + fn pin_init(slot: impl PinInit) -> impl PinInit { + Self::try_ffi_init(|ptr: *mut T| { + // SAFETY: + // - `ptr` is a valid pointer to uninitialized memory, + // - `slot` is not accessed on error; the call is infallible, + // - `slot` is pinned in memory. + unsafe { PinInit::::__pinned_init(slot, ptr) } + }) + } +} =20 /// Types that are _always_ reference counted. /// --=20 2.49.0 From nobody Sun Feb 8 23:33:13 2026 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9500A221FB6; Sat, 10 May 2025 09:33:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746869593; cv=none; b=aTu+UMUIUWkMu9QTDiTUsG736Tm8smoVNoTkuTh6X/5+EIo9R7s527p2dAKuagxvM57ontXK/t5eLcJClcqU3eoEL50VtzU33FZgD/Kz5ftL1y38HSXX7w02FPZjAGJVeOmQmquGpX5YhIm8tMErL+ToGhfu/I1jE7ESJEK39Mc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746869593; c=relaxed/simple; bh=5KT6o4PwmqhxLMTqeLgps9jLONAfkvBGP8fVPNwouPw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gM277ML5xsK9RxQtTsARrCfRjbP9aC/Ny/ZEVqoye6xoPT/cVbTIIZxmJR7pgmJJ/K9V0GgFxeDFmUX8Eyoydf1NHWW7rW5OaDbKkAbQFYct4HyxAa4XY9YlhmKOwNUbWzGyKkAhXvOq/XNRahT4q/6rGczHdmMlwf5t43aAkK0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=bo1WgPTT; arc=none smtp.client-ip=209.85.128.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bo1WgPTT" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-43cfa7e7f54so17760875e9.1; Sat, 10 May 2025 02:33:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746869590; x=1747474390; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=CJGae8ej3sDPBpz6YOCR1Ed8bJvIS2qRuUE9rFXc47Y=; b=bo1WgPTTgjfkAHja0j3jtJlyDv0Sy6TFrI6VZ7av5KP13zPI0yF8wN28L9vK+iCHUC SeZhZhzddt8qQI8P3tKaYhdmg/4UsdwR+pqWE1M11uPlSFHvm1v9U5BTH56bzlNtansY RDJR/ty3YDYwojFJsDA9ReaSHi7XwsjUXYn25jzeo+EGFOU/IKfWft6Ft0ElbasnEe3u M9EkLkk+vKt+pH1RodsSy5+MYDmGSfTRNqRWUWxATAjj4pITwDOclpxyfTbmgTEK9dZb kMErUP3bS41AHyupPCB8M1O2wzWhUKPD4IqeQJIpCoPES12WJIPKxeHa8CxB5n+xbIZo TNGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746869590; x=1747474390; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CJGae8ej3sDPBpz6YOCR1Ed8bJvIS2qRuUE9rFXc47Y=; b=s82dkmaPym/GadLXL2rwG1G160hjnDgHrOrWYmB5zvMircGw0ZKCPbx1ScZYMQuMc2 DX+ETRUrq9fCnXHXiUtoVxdjHore4huKgaNe7lG2nZaUVft3lcUUonhrJ5fhtyFVsqaw /6xDiwZJXu0dzoLkERJ2f4DsQ1OXDNlWO5OQsZ6Sh51La3yBricZzKJgiLEJ/HwqUNQc JSkkR7hKgRjjs3Fj2L1tLlh8bgz6p/ax+GJg2U2CYYuUmJwAnujGA3n1I+qTvMvZkhXi JLe547yrlEXrnHUMUo0oXegP6Tf2+tFfOTHJLOvkQ0omKv/6S8dGwl2PTKb3zho5BDry Acow== X-Forwarded-Encrypted: i=1; AJvYcCXFytgBhGUlmB41YDdzz96jVAboqwLyHTiE4oYCIo2YEqdhbjArL0QaeN4L8XseKRZEjx0r5QF1TzwyP4W7/g==@vger.kernel.org X-Gm-Message-State: AOJu0YyHwo7ZXlHGBPGqeEl92LipdEjtlN6iTwHaELY+zJjGK9no2ZVZ O2f/uASXvCKWw8O1yuJszgHOd3gFiv1jkAchIVjM0/hQtMNYIKdb X-Gm-Gg: ASbGncuBRfz916EZHqqF1Eqy3h+FdaMRa5iLsBW9J9Yr2CqIoCHWNSV74uN7YL+2kei 1I4bdbcDNE7K3vmyqPAbQ3EMwDLyfAi/GQB2HIphfYw8eO8A+mndK/s8motmuo92hIKhpw0TCRc QvQ/GIt0HG6+qcB1fAh4rAjfkS0sqdToojtq1vXo8mFE5QA8wMqYUyIh+krcXG9yAo1ySySexeD WS2XQcyzUMcKjfIEWfOH4Rj3rNK68kU7SerEnJE1Vb60GeaKlDRFJPQndOQ36dfpPLvc28zhfhl 0IQTltKsTc7dnBqARzgi6PGzlrKvOOxSPday6J8= X-Google-Smtp-Source: AGHT+IEg1/H0El+/s/3aWcVhdWbxHVw1Udl2ugtERSi/35TGMzTQrvSKRwgi4Tre6zdrnfZXi4TQfw== X-Received: by 2002:a05:600c:1808:b0:43b:bb72:1dce with SMTP id 5b1f17b1804b1-442d02ca7c1mr59656315e9.5.1746869589503; Sat, 10 May 2025 02:33:09 -0700 (PDT) Received: from [10.0.1.56] ([2001:871:22a:99c5::1ad1]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-3a1f57ddde0sm5981485f8f.14.2025.05.10.02.33.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 10 May 2025 02:33:08 -0700 (PDT) From: Christian Schrefl Date: Sat, 10 May 2025 11:32:28 +0200 Subject: [PATCH v3 3/3] rust: use `UnsafePinned` in the implementation of `Opaque` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250510-rust_unsafe_pinned-v3-3-57ce151123f9@gmail.com> References: <20250510-rust_unsafe_pinned-v3-0-57ce151123f9@gmail.com> In-Reply-To: <20250510-rust_unsafe_pinned-v3-0-57ce151123f9@gmail.com> To: Sky , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , =?utf-8?q?Gerald_Wisb=C3=B6ck?= , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt Cc: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, llvm@lists.linux.dev, Christian Schrefl , Benno Lossin X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1746869583; l=3832; i=chrisi.schrefl@gmail.com; s=20250119; h=from:subject:message-id; bh=5KT6o4PwmqhxLMTqeLgps9jLONAfkvBGP8fVPNwouPw=; b=O03eBIbL5UUfDLmO9G++7mRpLilPiCWENfC0kOwkiOjTKRhiusfaGwbDVpzcN4yCA+XK63cSI 6waJnMQBqL6CNpcpcyvssiNEEshP/3aq9BK08G2EIxEd2wy72t89ycA X-Developer-Key: i=chrisi.schrefl@gmail.com; a=ed25519; pk=EIyitYCrzxWlybrqoGqiL2jyvO7Vp9X40n0dQ6HE4oU= Make the semantics of the `Opaque` implementation clearer and prepare for the switch to the upstream rust `UnsafePinned` type in the future. `Opaque` still uses `UnsafeCell` even though the kernel implementation of `UnsafePinned` already includes it, since the current upstream version does not. Reviewed-by: Gerald Wisb=C3=B6ck Reviewed-by: Alice Ryhl Reviewed-by: Benno Lossin Signed-off-by: Christian Schrefl --- rust/kernel/types.rs | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index f06e8720e012102e5c41e79fd97b0607e927d71c..e32905c42453132fbea49d37a64= 57547d42465ce 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -4,12 +4,12 @@ =20 use core::{ cell::UnsafeCell, - marker::{PhantomData, PhantomPinned}, + marker::PhantomData, mem::{ManuallyDrop, MaybeUninit}, ops::{Deref, DerefMut}, ptr::NonNull, }; -use pin_init::{PinInit, Wrapper, Zeroable}; +use pin_init::{cast_pin_init, PinInit, Wrapper, Zeroable}; =20 /// Used to transfer ownership to and from foreign (non-Rust) languages. /// @@ -308,8 +308,10 @@ fn drop(&mut self) { /// ``` #[repr(transparent)] pub struct Opaque { - value: UnsafeCell>, - _pin: PhantomPinned, + // The kernel implementation of `UnsafePinned` uses `UnsafeCell` inter= nally, but the + // upstream rust `UnsafePinned` will not. So to make sure this is comp= atible with + // the upstream version use `UnsafeCell` here. + value: UnsafePinned>>, } =20 // SAFETY: `Opaque` allows the inner value to be any bit pattern, inclu= ding all zeros. @@ -319,16 +321,14 @@ impl Opaque { /// Creates a new opaque value. pub const fn new(value: T) -> Self { Self { - value: UnsafeCell::new(MaybeUninit::new(value)), - _pin: PhantomPinned, + value: UnsafePinned::new(UnsafeCell::new(MaybeUninit::new(valu= e))), } } =20 /// Creates an uninitialised value. pub const fn uninit() -> Self { Self { - value: UnsafeCell::new(MaybeUninit::uninit()), - _pin: PhantomPinned, + value: UnsafePinned::new(UnsafeCell::new(MaybeUninit::uninit()= )), } } =20 @@ -371,7 +371,7 @@ pub fn try_ffi_init( =20 /// Returns a raw pointer to the opaque data. pub const fn get(&self) -> *mut T { - UnsafeCell::get(&self.value).cast::() + UnsafeCell::raw_get(self.value.get()).cast::() } =20 /// Gets the value behind `this`. @@ -384,14 +384,12 @@ pub const fn raw_get(this: *const Self) -> *mut T { } impl Wrapper for Opaque { /// Create an opaque pin-initializer from the given pin-initializer. - fn pin_init(slot: impl PinInit) -> impl PinInit { - Self::try_ffi_init(|ptr: *mut T| { - // SAFETY: - // - `ptr` is a valid pointer to uninitialized memory, - // - `slot` is not accessed on error; the call is infallible, - // - `slot` is pinned in memory. - unsafe { PinInit::::__pinned_init(slot, ptr) } - }) + fn pin_init(value_init: impl PinInit) -> impl PinInit { + let value_init =3D + UnsafePinned::pin_init(UnsafeCell::pin_init(MaybeUninit::pin_i= nit(value_init))); + // SAFETY: `Opaque` is a `repr(transparent)` wrapper around + // `UnsafePinned>>` so the memory represe= ntation is compatible. + unsafe { cast_pin_init(value_init) } } } =20 --=20 2.49.0