From nobody Sat Oct 11 08:29:19 2025 Received: from mail-ed1-f52.google.com (mail-ed1-f52.google.com [209.85.208.52]) (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 08682265286; Tue, 10 Jun 2025 20:28:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749587284; cv=none; b=psDOIsHawT7DkRJ4zdFYrkfRa4EGiB7xJq7bdLj6HKj7LAKJQShXk0/8baX7SUU1xMf8wCgcm0LNmG/hSLZrxkqwJ7Y/esID7bxtzJaIjw2tXlF+MuhfcIkzX/+i/WE2hi8NZi1NV7WNSKsO/LLIa+523fCeoaSaU+lSKKqMVCE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749587284; c=relaxed/simple; bh=LonEQDkG2vH+/s77vOSwjTPnV9muhPIPy/+YR2PeInA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MtF7rPYVulXj6rcRu5CL/XZa+zZr0n94Orcu7eQkTYpksUtKYNN1O+q95Dscd4z2akrd0ITwwupmXSnP2MT8GCN4+Dkicc2guT/sj724bWoIHt8y46BGj5YVnLb5erS81Cq2wkIaqmQcXH6tn2HNYt7aLA/juR12IUB2/ST6xCs= 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=jaavmk4d; arc=none smtp.client-ip=209.85.208.52 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="jaavmk4d" Received: by mail-ed1-f52.google.com with SMTP id 4fb4d7f45d1cf-60727e46168so10154357a12.0; Tue, 10 Jun 2025 13:28:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1749587281; x=1750192081; 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=5QkJi5Kb0CSf/rX0SHuPAU2RuViLKIg14a3y6FbAPpQ=; b=jaavmk4dsLwo4ar6sf0rTTitPnqykqvw3DHaksWGTpllDDM4BcuZoxhc3phBi1tYZN 38DMFn2NpEoh4hOFSE3NUxNfH7Qoa2/EGcaiVLfF9iV2qwrCZnqtVw3yqM5gblDHPwly aeXEDflD/ahC/PsVPAM86nwt9TneUGt5VR3XeWyDEyT+Z8GRk+OrIoq6boC07T5i139r kD7etJLppY3yAARY/1LUbgy77p3P1upmMgxzABRtsGk0EDyNTvNOQnfdvbSt0lDmtDYc Zqw8I5ZA0QvlKzBaCtsqgJBuDKpRmDiTDi5Gyn11p7f2eWATmJkURPUMBkWsEfTTyQrZ fy2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749587281; x=1750192081; 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=5QkJi5Kb0CSf/rX0SHuPAU2RuViLKIg14a3y6FbAPpQ=; b=SYDpgyyF+3ya+32sF635dBrE28eUvLfcLptlnTyPL/6HlcIaXjucycoFtd1MsRkjMY YFF1qAi1ttoKeODmUQnc1yEAiXXT/KXKgth3oZKDHNed5ahtVHWaK7IGVfB4lkzqT9B2 c6gvovKniKC50fLYwzLBjasOygr/dYpMtXutKSilQe9Km9E/B+uJikriSD0QyFhAMhjY 9NwU6N+v9AGH55HvvNIVFO8D67ULWRYAZBNslLWD77084NjM9o4GqmsYe8oRJjJDZnHu G7XWXN0RC1PYT/uEXk4x/CzTWOqcoKOzsn0YjrZymjXt//mhLZSBoHFgcUNYQLRcbFTO IvvA== X-Forwarded-Encrypted: i=1; AJvYcCUcUmVyhOHRYpr4emPPsKQz0KL1fBTN9HKza+l7UMnRLlrKl7JnLKT/gIF0Ox5Bq58tBFz4444IjlpjRnQ=@vger.kernel.org, AJvYcCVkjaLtMA2l9OecT6uYemAQM+uNtLWKlBHIhxs/VJaxoQ9gnGF2vADwdNbfuqbxTQUhLggRxWBUPFjIKKpAi4g=@vger.kernel.org X-Gm-Message-State: AOJu0YzbHV1a0L8TyxN2WMy+sgLMXcaGH0QOepoV5Pid/1uLFg32/h4v 3p46b7dSs8v8y9ZzRFftkjXw/NE8V/q/UgOeGa1eUjFY0XntebAX0MBM X-Gm-Gg: ASbGnctRBmzy+P7pV7J4B38jamCu7ZOG8ybfGm6HbW5gBynrlbr7y3s9hm0c2NB6Id8 FNGkKXdf8kwh/hsnN5OCLTPNreVmcaI7TIg7kNReTQ7kYdoWlAuV0Hh4QVp4sYizhTxIwB52lL+ 3Pq9LhPTVSFHewfkGwtZGdqBIez6kfkAIjrIRD/vwS17v5EdAEObWuV95hLuCc6PWgAmIn1Xk95 Dv0M0Q+fJ7vKZQRtBQzOZjgidd54QScBu9lBdq7CtD3qiDzryxWSB/pzOzfDLlqPFZZlCe9TFtt 9IGPJjyYShEr2uDaKmHwhkbRJ23i7bCJg+RwJrpWeecgwx1nl3D3Kfko6jbwGPMpPXE777w= X-Google-Smtp-Source: AGHT+IH6LLm3evehYJR4G83oE8ls7DYPaeOM7N31fBeNBbMGUQgGEnS5QzHJndMSTEmydt5HyfIPjA== X-Received: by 2002:a05:6402:84e:b0:607:d235:87b1 with SMTP id 4fb4d7f45d1cf-6084e9ee39dmr42953a12.32.1749587281202; Tue, 10 Jun 2025 13:28:01 -0700 (PDT) Received: from [10.5.1.156] ([193.170.134.247]) by smtp.googlemail.com with ESMTPSA id 4fb4d7f45d1cf-607783e67efsm6552678a12.78.2025.06.10.13.28.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Jun 2025 13:28:00 -0700 (PDT) From: Christian Schrefl Date: Tue, 10 Jun 2025 22:27:55 +0200 Subject: [PATCH v6 1/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: <20250610-b4-rust_miscdevice_registrationdata-v6-1-b03f5dfce998@gmail.com> References: <20250610-b4-rust_miscdevice_registrationdata-v6-0-b03f5dfce998@gmail.com> In-Reply-To: <20250610-b4-rust_miscdevice_registrationdata-v6-0-b03f5dfce998@gmail.com> To: Miguel Ojeda , Danilo Krummrich , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Andreas Hindborg , Alice Ryhl , Trevor Gross , Arnd Bergmann , Greg Kroah-Hartman , Lee Jones , Daniel Almeida , Benno Lossin , Benno Lossin Cc: =?utf-8?q?Gerald_Wisb=C3=B6ck?= , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Christian Schrefl X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1749587279; l=3445; i=chrisi.schrefl@gmail.com; s=20250119; h=from:subject:message-id; bh=LonEQDkG2vH+/s77vOSwjTPnV9muhPIPy/+YR2PeInA=; b=Kg+Aa/ssFoSotWR2iV0qnoWWo6Gtv1LxbtYwcxwR8aOQSiK4pzMloyIsym0Freg5pqERMDyYk wCfS1yVfpQJBqngS5EJW5HyNfcKzwm5PbQu6xGJjZE+m10fblsA//FS 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. 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: Danilo Krummrich Reviewed-by: Gerald Wisb=C3=B6ck Reviewed-by: Alice Ryhl Reviewed-by: Benno Lossin Signed-off-by: Christian Schrefl Acked-by: Miguel Ojeda --- This patch is also required for my `UnsafePinned`series. I'm not sure how this should be handeld (in case both series make it in this cycle). --- rust/kernel/revocable.rs | 2 ++ rust/kernel/types.rs | 26 ++++++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/rust/kernel/revocable.rs b/rust/kernel/revocable.rs index db4aa46bb1216d18868dcbdcb0b7033a757306b1..3d41374a911482385faa93170cd= 31a703bb0d42d 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 22985b6f69820d6df8ff3aae0bf815fad36a9d92..3958a5f44d567bbf2ff4e3e891b= 27c065909431a 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. /// @@ -353,17 +353,6 @@ pub const fn zeroed() -> 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 @@ -415,6 +404,19 @@ pub const fn raw_get(this: *const Self) -> *mut T { } } =20 +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, + // - `slot` is pinned in memory. + unsafe { PinInit::::__pinned_init(slot, ptr) } + }) + } +} + /// Types that are _always_ reference counted. /// /// It allows such types to define their own custom ref increment and decr= ement functions. --=20 2.49.0 From nobody Sat Oct 11 08:29:19 2025 Received: from mail-ed1-f46.google.com (mail-ed1-f46.google.com [209.85.208.46]) (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 66824265CA0; Tue, 10 Jun 2025 20:28:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749587286; cv=none; b=E5dlDaEAkBMpk4ljDczP7Cj3utZO0p0w+xX89Pe5KyCNxC/MPwrkv4/z7KMe026EPTqTtCGfFXwixfir11/We9hpsuQToi6IczEPiyOr85lXMzV7INwpFH9cu+ytHKQFgzRRUvMPUfD0KLqsMjvjVClhLU6umOuq++2livBGg5I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749587286; c=relaxed/simple; bh=K4RhgZE/wYQmP+QbXOufjRK7BPcv3S+aCV2ZQpi/RyI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DfSzxU7zWsBJEIDPMMzNdLSXfO87kAcgb/DmP15ZY9/BofQam9CoCugtUytmV9j2Fd5cavi4EES3eiS100kt2LOqNI+0cwgcqTSF17QL3MoKbXAkSrXqUw1kz9tS1E59BmbcVKv6/5NlGORZZKwToJOPlcQzKwxrC2bFUzeZGek= 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=Z7TY/HhP; arc=none smtp.client-ip=209.85.208.46 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="Z7TY/HhP" Received: by mail-ed1-f46.google.com with SMTP id 4fb4d7f45d1cf-6077dea37easo7286661a12.3; Tue, 10 Jun 2025 13:28:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1749587283; x=1750192083; 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=ByIM0SqwrqaZQqOesQau4CN4JmNVKP7t3Qu2vIl6D+M=; b=Z7TY/HhPUBlqv1UYwuuQujjy9hsy6suREh0VinWXpOyNZaYwL+xK2coIEioJjNPHjo 1IbaI3uMQP5brIIYfPzS5qLiEs0CdqwvGMKTxJD73E4OJQOGBVopRd3WbmpnE0U7z9um deNNuvm4yzdWITPmcX7Gupo7b5BJZQZ+yrllVZEMbDdEGjLqxQtsKwEuKayE3MMW3hpp z9B2qmOz4UHPdZ8WwXCGrx1apB9/tt6ZQOtVSPn1hePb27Ze/yiNhkNBLiE1e7v68QEF eDys7VV3l4eiX+IltJTNQNjtLV0hCxrc3qFDRNC1Cf5PhgCbtQ2ybrKrQ0+vWoSrqyJy +gvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749587283; x=1750192083; 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=ByIM0SqwrqaZQqOesQau4CN4JmNVKP7t3Qu2vIl6D+M=; b=GO9FL2VoGxdwu1jUtK76slntL9jaOb9cnxJ+LRpcVFlX62/oyFLqY/K/sDcA297ugd oNB7F/Zw2pYmuwJNw3WH4S0shmOX1fXekBxCfx/46LAXC6yGl9ilLgLRHeNNc3+2wq08 mDtEfKAi/QZkJY3/xZYBG05H1Pd6w7Fkz+4hjGqrhlYEzxBCJFo8hAFumeqFBeTjmDTv TeRtCInE/x5tnmedqTQrYohjUW4l4CMEaBzO1XMxTvD8kxZnP52aGhIxqALEMsvQXQmk l4pDWhNUTzq9clPc+GfVy/7l+rwSjVUyAn02pDErJqjc2lbJdrxQDy4Rvy+21rgZ/Qxj rAeQ== X-Forwarded-Encrypted: i=1; AJvYcCUzEHgQQuz7wO3AfVtCuQPLcQ0lsLwuOdfYTBAcjKLT2kpUYwJRSPoomw6l3q24KngnlUIy4EllFT1mAYE=@vger.kernel.org, AJvYcCXWuXYDT/pKtz5r7JZ3/e47fPBgpnyEchvF1AzXYbTjvGEaNzuQR9Mrnz1pC1Uv01MOE6vbYqht52Uts/jYB6I=@vger.kernel.org X-Gm-Message-State: AOJu0YxhYh0ei/QMzief5SM5ZD6CFQH0Ljq/vll9u4Xb0GVMmaejqG/L BsrJEVs4bCzdCBa+PNS3X66yKle/BOYDVak1biT5lmxWGH4amGSTxu35 X-Gm-Gg: ASbGncvX2OAtyqMnpViha3Zk/yipKCvZ7kS3KKTvgLJB8+1DJi1Zoi+AfDg/5wjpeDh nvVYwXhgJuOwkOtSbAumAcDPVuUxcT233fcBZgdFp6DqnzYqP97ukxlhmZ/MnLmQTrS/blqVRjr BGm27QjAOHoBH2mvdusZkT0EgDnJrVc/getV/VN9Ia9dEjtWe+Jftq0IISVJ6i/1l+D5VPfnUda e8EYziGaYLDSZC2+/oLkCFErepKHs6fit8DAjbaUHJ2LPboOgyzgg96/VPTyhkQAJOanFSHU3bR lOHmD0f6/6fMPMVIm8q06+NFfVGbBOlQfYjxF8OwU8OOt6PlDreKUJ/3fJymn6Id0421wEE= X-Google-Smtp-Source: AGHT+IGr77VP/Ma9Z1hcbN/HIgnqWYmRyulvY+7lK2QE/njA2IDND7OEc/5wwflwbu3he4cH/ycIuw== X-Received: by 2002:a05:6402:524c:b0:602:e46:638 with SMTP id 4fb4d7f45d1cf-60846cf0c7emr449756a12.26.1749587282265; Tue, 10 Jun 2025 13:28:02 -0700 (PDT) Received: from [10.5.1.156] ([193.170.134.247]) by smtp.googlemail.com with ESMTPSA id 4fb4d7f45d1cf-607783e67efsm6552678a12.78.2025.06.10.13.28.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Jun 2025 13:28:02 -0700 (PDT) From: Christian Schrefl Date: Tue, 10 Jun 2025 22:27:56 +0200 Subject: [PATCH v6 2/3] rust: miscdevice: add additional data to `MiscDeviceRegistration` 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: <20250610-b4-rust_miscdevice_registrationdata-v6-2-b03f5dfce998@gmail.com> References: <20250610-b4-rust_miscdevice_registrationdata-v6-0-b03f5dfce998@gmail.com> In-Reply-To: <20250610-b4-rust_miscdevice_registrationdata-v6-0-b03f5dfce998@gmail.com> To: Miguel Ojeda , Danilo Krummrich , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Andreas Hindborg , Alice Ryhl , Trevor Gross , Arnd Bergmann , Greg Kroah-Hartman , Lee Jones , Daniel Almeida , Benno Lossin , Benno Lossin Cc: =?utf-8?q?Gerald_Wisb=C3=B6ck?= , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Christian Schrefl X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1749587279; l=12398; i=chrisi.schrefl@gmail.com; s=20250119; h=from:subject:message-id; bh=K4RhgZE/wYQmP+QbXOufjRK7BPcv3S+aCV2ZQpi/RyI=; b=VvGfVxZJKhKHRjSP9TQtrKEirJgNsguVLWOtcQPxFV3ypHVQjzyd7875kJwU8b/YSwyTH4ewA BrBuced3blCB1oYrz0coPQuqFHa6Q7yEcC9wlXTATYthrb+9+JDXU7Q X-Developer-Key: i=chrisi.schrefl@gmail.com; a=ed25519; pk=EIyitYCrzxWlybrqoGqiL2jyvO7Vp9X40n0dQ6HE4oU= When using the Rust miscdevice bindings, you generally embed the `MiscDeviceRegistration` within another struct: struct MyDriverData { data: SomeOtherData, misc: MiscDeviceRegistration } In the `fops->open` callback of the miscdevice, you are given a reference to the registration, which allows you to access its fields. For example, as of commit 284ae0be4dca ("rust: miscdevice: Provide accessor to pull out miscdevice::this_device") you can access the internal `struct device`. However, there is still no way to access the `data` field in the above example, because you only have a reference to the registration. Using `container_of` is also not possible to do safely. For example, if the destructor of `MyDriverData` runs, then the destructor of `data` would run before the miscdevice is deregistered, so using `container_of` to access `data` from `fops->open` could result in a UAF. A similar problem can happen on initialization if `misc` is not the last field to be initialized. To provide a safe way to access user-defined data stored next to the `struct miscdevice`, make `MiscDeviceRegistration` into a container that can store a user-provided piece of data. This way, `fops->open` can access that data via the registration, since the data is stored inside the registration. The container enforces that the additional user data is initialized before the miscdevice is registered, and that the miscdevice is deregistered before the user data is destroyed. This ensures that access to the userdata is safe. For the same reasons as in commit 88441d5c6d17 ("rust: miscdevice: access the `struct miscdevice` from fops->open()"), you cannot access the user data in any other fops callback than open. This is because a miscdevice can be deregistered while there are still open files. A situation where this user data might be required is when a platform driver acquires a resource in `probe` and wants to use this resource in the `fops` implementation of a `MiscDevice`. This solution is similar to the approach used by the initial downstream Rust-for-Linux/Rust branch [0]. Link: https://github.com/Rust-for-Linux/linux/blob/rust/rust/kernel/miscdev= .rs#L108 [0] Suggested-by: Alice Ryhl Reviewed-by: Alice Ryhl Signed-off-by: Christian Schrefl --- rust/kernel/miscdevice.rs | 104 +++++++++++++++++++++++++++++------= ---- samples/rust/rust_misc_device.rs | 4 +- 2 files changed, 82 insertions(+), 26 deletions(-) diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs index 939278bc7b03489a647b697012e09223871c90cd..8daf3724b75068c998cb361eac3= 8f43a39884b0c 100644 --- a/rust/kernel/miscdevice.rs +++ b/rust/kernel/miscdevice.rs @@ -9,7 +9,7 @@ //! Reference: =20 use crate::{ - bindings, + bindings, container_of, device::Device, error::{to_result, Error, Result, VTABLE_DEFAULT_ERROR}, ffi::{c_int, c_long, c_uint, c_ulong}, @@ -21,6 +21,7 @@ types::{ForeignOwnable, Opaque}, }; use core::{marker::PhantomData, mem::MaybeUninit, pin::Pin}; +use pin_init::Wrapper; =20 /// Options for creating a misc device. #[derive(Copy, Clone)] @@ -31,7 +32,10 @@ pub struct MiscDeviceOptions { =20 impl MiscDeviceOptions { /// Create a raw `struct miscdev` ready for registration. - pub const fn into_raw(self) -> bindings::miscdevice { + pub const fn into_raw(self) -> bindings::miscdevice + where + T::Data: Sync, + { // SAFETY: All zeros is valid for this C type. let mut result: bindings::miscdevice =3D unsafe { MaybeUninit::zer= oed().assume_init() }; result.minor =3D bindings::MISC_DYNAMIC_MINOR as _; @@ -45,38 +49,55 @@ pub const fn into_raw(self) -> bindings:= :miscdevice { /// /// # Invariants /// -/// `inner` is a registered misc device. -#[repr(transparent)] +/// - `inner` is a registered misc device. +/// - `data` contains a valid `T::Data` for the whole lifetime of [`MiscDe= viceRegistration`] +/// - `data` must be valid until `misc_deregister` (called when dropped) h= as returned. +/// - no mutable references to `data` may be created. #[pin_data(PinnedDrop)] -pub struct MiscDeviceRegistration { +pub struct MiscDeviceRegistration { #[pin] inner: Opaque, - _t: PhantomData, + #[pin] + data: Opaque, } =20 -// SAFETY: It is allowed to call `misc_deregister` on a different thread f= rom where you called -// `misc_register`. -unsafe impl Send for MiscDeviceRegistration {} -// SAFETY: All `&self` methods on this type are written to ensure that it = is safe to call them in -// parallel. -unsafe impl Sync for MiscDeviceRegistration {} +// SAFETY: +// - It is allowed to call `misc_deregister` on a different thread from wh= ere you called +// `misc_register`. +// - Only implements `Send` if `MiscDevice::Data` is also `Send`. +unsafe impl Send for MiscDeviceRegistration where T::Dat= a: Send {} + +// SAFETY: +// - All `&self` methods on this type are written to ensure that it is saf= e to call them in +// parallel. +// - Only implements `Sync` if `MiscDevice::Data` is also `Sync`. +unsafe impl Sync for MiscDeviceRegistration where T::Dat= a: Sync {} =20 impl MiscDeviceRegistration { /// Register a misc device. - pub fn register(opts: MiscDeviceOptions) -> impl PinInit { + pub fn register( + opts: MiscDeviceOptions, + data: impl PinInit, + ) -> impl PinInit + where + T::Data: Sync, + { try_pin_init!(Self { + data <- Opaque::pin_init(data), inner <- Opaque::try_ffi_init(move |slot: *mut bindings::miscd= evice| { // SAFETY: The initializer can write to the provided `slot= `. unsafe { slot.write(opts.into_raw::()) }; =20 - // SAFETY: We just wrote the misc device options to the sl= ot. The miscdevice will - // get unregistered before `slot` is deallocated because t= he memory is pinned and - // the destructor of this type deallocates the memory. + // SAFETY: + // * We just wrote the misc device options to the slot. Th= e miscdevice will + // get unregistered before `slot` is deallocated because= the memory is pinned and + // the destructor of this type deallocates the memory. + // * `data` is Initialized before `misc_register` so no ra= ce with `fops->open()` + // is possible. // INVARIANT: If this returns `Ok(())`, then the `slot` wi= ll contain a registered // misc device. to_result(unsafe { bindings::misc_register(slot) }) }), - _t: PhantomData, }) } =20 @@ -94,13 +115,24 @@ pub fn device(&self) -> &Device { // before the underlying `struct miscdevice` is destroyed. unsafe { Device::as_ref((*self.as_raw()).this_device) } } + + /// Access the additional data stored in this registration. + pub fn data(&self) -> &T::Data { + // SAFETY: + // * No mutable reference to the value contained by `self.data` ca= n ever be created. + // * The value contained by `self.data` is valid for the entire li= fetime of `&self`. + unsafe { &*self.data.get() } + } } =20 #[pinned_drop] -impl PinnedDrop for MiscDeviceRegistration { +impl PinnedDrop for MiscDeviceRegistration { fn drop(self: Pin<&mut Self>) { // SAFETY: We know that the device is registered by the type invar= iants. unsafe { bindings::misc_deregister(self.inner.get()) }; + + // SAFETY: `self.data` contains a valid `Data` and does not need t= o be valid anymore. + unsafe { core::ptr::drop_in_place(self.data.get()) }; } } =20 @@ -110,6 +142,13 @@ pub trait MiscDevice: Sized { /// What kind of pointer should `Self` be wrapped in. type Ptr: ForeignOwnable + Send + Sync; =20 + /// Additional data carried by the [`MiscDeviceRegistration`] for this= [`MiscDevice`]. + /// If no additional data is required than the unit type `()` should b= e used. + /// + /// This can be accessed in [`MiscDevice::open()`] using + /// [`MiscDeviceRegistration::data()`]. + type Data; + /// Called when the misc device is opened. /// /// The returned pointer will be stored as the private data for the fi= le. @@ -180,7 +219,10 @@ fn show_fdinfo( /// A vtable for the file operations of a Rust miscdevice. struct MiscdeviceVTable(PhantomData); =20 -impl MiscdeviceVTable { +impl MiscdeviceVTable +where + T::Data: Sync, +{ /// # Safety /// /// `file` and `inode` must be the file and inode for a file that is u= ndergoing initialization. @@ -195,18 +237,30 @@ impl MiscdeviceVTable { // SAFETY: The open call of a file can access the private data. let misc_ptr =3D unsafe { (*raw_file).private_data }; =20 - // SAFETY: This is a miscdevice, so `misc_open()` set the private = data to a pointer to the - // associated `struct miscdevice` before calling into this method.= Furthermore, - // `misc_open()` ensures that the miscdevice can't be unregistered= and freed during this - // call to `fops_open`. - let misc =3D unsafe { &*misc_ptr.cast::>= () }; + // This is a miscdevice, so `misc_open()` sets the private data to= a pointer to the + // associated `struct miscdevice` before calling into this method. + let misc_ptr =3D misc_ptr.cast::>(); + + // SAFETY: + // * `misc_open()` ensures that the `struct miscdevice` can't be u= nregistered and freed + // during this call to `fops_open`. + // * The `misc_ptr` always points to the `inner` field of a `MiscD= eviceRegistration`. + // * The `MiscDeviceRegistration` is valid until the `struct mi= scdevice` was + // unregistered. + // * `MiscDeviceRegistration` is `Send` since `MiscDeviceRegist= ration::register` has a + // `T::Data: Sync` bound, `MiscDeviceRegistration` is Send i= f `T::Data: Sync` and is + // the only way to create a `MiscDeviceRegistration`. This means= that a reference to it + // can be shared between contexts. + // TODO: add `assert_sync` for `MiscDeviceRegistration` and + // `MiscDeviceRegistration::Data`. + let registration =3D unsafe { &*container_of!(misc_ptr, MiscDevice= Registration, inner) }; =20 // SAFETY: // * This underlying file is valid for (much longer than) the dura= tion of `T::open`. // * There is no active fdget_pos region on the file on this threa= d. let file =3D unsafe { File::from_raw_file(raw_file) }; =20 - let ptr =3D match T::open(file, misc) { + let ptr =3D match T::open(file, registration) { Ok(ptr) =3D> ptr, Err(err) =3D> return err.to_errno(), }; diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_devi= ce.rs index c881fd6dbd08cf4308fe1bd37d11d28374c1f034..c0b912920d6c4b60e747d9d2989= 00ad64df67339 100644 --- a/samples/rust/rust_misc_device.rs +++ b/samples/rust/rust_misc_device.rs @@ -137,7 +137,7 @@ fn init(_module: &'static ThisModule) -> impl PinInit { }; =20 try_pin_init!(Self { - _miscdev <- MiscDeviceRegistration::register(options), + _miscdev <- MiscDeviceRegistration::register(options, ()), }) } } @@ -157,6 +157,8 @@ struct RustMiscDevice { impl MiscDevice for RustMiscDevice { type Ptr =3D Pin>; =20 + type Data =3D (); + fn open(_file: &File, misc: &MiscDeviceRegistration) -> Result>> { let dev =3D ARef::from(misc.device()); =20 --=20 2.49.0 From nobody Sat Oct 11 08:29:19 2025 Received: from mail-ed1-f41.google.com (mail-ed1-f41.google.com [209.85.208.41]) (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 3FE4A265CDD; Tue, 10 Jun 2025 20:28:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749587287; cv=none; b=Nx7DLBL0Z4r9HTiZrGoY7EwkPSHWHvlQSNoCplwF6daHydc7Hg6nk4NmcvSKA+Lsa/ikhxMjr6BgQ0HG4WoEr4iXzxHYql4/I8Yh0VkWuCvQ5tdOOk943tLOHza73lSxrqgJz2/TOA09/cnwHhrwNTzt420R+7V/+D/myD1J8R0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749587287; c=relaxed/simple; bh=DZa3JdiBu214uY9Tt/JtVOPrAsMdXuGUNMm9XNgGI3o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=F8M0V2p+JampRa1AKUoyi6cEfRkgZtRqxyqRCouaIoPxwo3n3Iiyr1f6lYsnDKXG1Wrot3a3p2ybT2n1GwGCDGz+tX5iO2br89N7VgSlomaqfoLVM0jHJKZ94Fd+48mXlhTBGcB21jA95HDI4u2gf4GXtrLGlDyuo3uFG0uDhhE= 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=VhrxmKhJ; arc=none smtp.client-ip=209.85.208.41 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="VhrxmKhJ" Received: by mail-ed1-f41.google.com with SMTP id 4fb4d7f45d1cf-60768f080d8so8906396a12.1; Tue, 10 Jun 2025 13:28:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1749587283; x=1750192083; 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=07TVQMLxCVF1Rat4olwfbCqsRTrqGNZ3C/Ht2jMQZbM=; b=VhrxmKhJZNfvEMpm0D8tArrDSAAKrISZVtfBOBnd81n2jgAdZs3aK4TsLgr/2cyVWT RdG1dwgdqEhhKZwtX4yC2t2FV93O67FrcGYgyq7SX/Zl27IY9mBqiMS22RG25mDw4ZfA Qokmz3TIj1j6sGk0E4zBpGYsmM80SHXhJJWqm2zBMRYJY5q5Q2xs6MN6jQlTicymem9z d/6eULtGk+HhtjzdiBF9Uf3qnYI7ES0RC39tBpaiWsrHGRrRMriiQycMYUF1RDNhdOKm eZ6Vv1ddZQhd3svX0SBrfzr4+Y3dbOoevEyIYrtzBSKH5uC2v3j6HrKB5PFsB9F6xnp+ hGDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749587283; x=1750192083; 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=07TVQMLxCVF1Rat4olwfbCqsRTrqGNZ3C/Ht2jMQZbM=; b=RRDqeCNUdLSSd5eb9gnQ754BzUaOJhzfuKU0ou2ykR7wMN0l/wlzPsKNSE88jzVX1h cpddql4cE6+7VTTCJZXVQJf14mObHUuFdoXaeH7QsxGBhZJ9cf7Gkx6IH5t9Z8+ql5Dd R7p7RoRqoDRBf9ANXrJ+RTsnf1CWz1N6JXdP1QRMz2AFzQB7S5rKJn0Jouz3nDsoxbqJ 9RKHJBkVq7h0HQhbiADGttoPPracrHyKcvpTB/tfYz+EaS4cagPlMxGyYC5AFG5qk1UL Z7+4tnCKDbLseyz+5s4ktgRyopoyZdDpJuDNDSHliysNg1BTdlusmDSeLEAjksAhfPPJ GaFw== X-Forwarded-Encrypted: i=1; AJvYcCVqwG/+MS6sikAw37KxYpy35J7IPOORBICeA6ltwy7WN+qDmb0VasEOEopNtUgW6BZ9k7HzTfuD6O/3Grg=@vger.kernel.org, AJvYcCWDFyC05g5yUAHxTutZeYJTTKyPsq0EQc2NPTSENAuYltYYzEecuFSl3ZVQGcQWdc+VeSxKOyzrwkagorbx3zM=@vger.kernel.org X-Gm-Message-State: AOJu0YwLzBF/uy9Tjzwd1SCsjOa9ETHHByD1VutsyiABne4HBP18DfD1 zj5ZowWk671n3x4K1pIdKLcJ8wdgR6ect4AVE78qDHdtNZe6FKIWv9Mr X-Gm-Gg: ASbGncsFRU9Pug6RMViMNQaLfSDlWQkXA42jNs0qeBXFGPxGhXIiflm4b7YhOyhuJd7 YyN463E/8O0PUsIEzbGbnvALpwUZ3pzD7YgfW5Dphglkq6/pfg+xXPSudvvKd4OlVZU5zY5pkOb dNlrCSukfl13/BLGCd3bnj4ZWhCFc53fgJeyaq5q3a/siv0Gm6yIfuw2x+aywnS0zqG2NLEsBOk MR8caD6RfP9IhRPT0GFQgzwqiLN1EZBu1gScy0qTy1eFwKONOolAGkPFol2FfPGlOpaFUfOy0IY Ce21hsCUrmFmRsVUOP27OZduP2Wq2YmZ9v6/EFlXy9pYo7N6+/h2GTlx5G5jTkmn3axal4eG47Y r3cBraw== X-Google-Smtp-Source: AGHT+IGhwvRLfbD0HAJSRYwXR8Wo6WZ7hGaok0JWNDYeP+QKQZJlufJTAHymLpt5w85UGxdZsfaBeA== X-Received: by 2002:a05:6402:1ecb:b0:606:9996:80b7 with SMTP id 4fb4d7f45d1cf-6084e9e6551mr54309a12.26.1749587283385; Tue, 10 Jun 2025 13:28:03 -0700 (PDT) Received: from [10.5.1.156] ([193.170.134.247]) by smtp.googlemail.com with ESMTPSA id 4fb4d7f45d1cf-607783e67efsm6552678a12.78.2025.06.10.13.28.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Jun 2025 13:28:03 -0700 (PDT) From: Christian Schrefl Date: Tue, 10 Jun 2025 22:27:57 +0200 Subject: [PATCH v6 3/3] rust: miscdevice: adjust the `rust_misc_device` sample to use `Data`. 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: <20250610-b4-rust_miscdevice_registrationdata-v6-3-b03f5dfce998@gmail.com> References: <20250610-b4-rust_miscdevice_registrationdata-v6-0-b03f5dfce998@gmail.com> In-Reply-To: <20250610-b4-rust_miscdevice_registrationdata-v6-0-b03f5dfce998@gmail.com> To: Miguel Ojeda , Danilo Krummrich , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Andreas Hindborg , Alice Ryhl , Trevor Gross , Arnd Bergmann , Greg Kroah-Hartman , Lee Jones , Daniel Almeida , Benno Lossin , Benno Lossin Cc: =?utf-8?q?Gerald_Wisb=C3=B6ck?= , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Christian Schrefl X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1749587279; l=7426; i=chrisi.schrefl@gmail.com; s=20250119; h=from:subject:message-id; bh=DZa3JdiBu214uY9Tt/JtVOPrAsMdXuGUNMm9XNgGI3o=; b=AE3ISk1f9xz205e0anDjngvwZxEakdyonhZ2lXr2+j5rTOXRqynDgdCvx7qnVO26X2UjngYna FDisQNN/zGxBMwXaGH8lFp+F7vAwA5rrLbOMxEsbMWN04XZhpvdEkmY X-Developer-Key: i=chrisi.schrefl@gmail.com; a=ed25519; pk=EIyitYCrzxWlybrqoGqiL2jyvO7Vp9X40n0dQ6HE4oU= Add a second mutex to the `RustMiscDevice``, which is shared between all instances of the device using an `Arc` and the `Data` of `MiscDeviceRegistration`. This is mostly to demonstrate the capability to share data in this way. Reviewed-by: Alice Ryhl Signed-off-by: Christian Schrefl --- samples/rust/rust_misc_device.rs | 116 +++++++++++++++++++++++++++++++++++= +--- 1 file changed, 109 insertions(+), 7 deletions(-) diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_devi= ce.rs index c0b912920d6c4b60e747d9d298900ad64df67339..7519ff6a79985e8bdbb7f4c79d8= a6ebf160ef8cc 100644 --- a/samples/rust/rust_misc_device.rs +++ b/samples/rust/rust_misc_device.rs @@ -18,6 +18,8 @@ //! #define RUST_MISC_DEV_HELLO _IO('|', 0x80) //! #define RUST_MISC_DEV_GET_VALUE _IOR('|', 0x81, int) //! #define RUST_MISC_DEV_SET_VALUE _IOW('|', 0x82, int) +//! #define RUST_MISC_DEV_GET_SHARED_VALUE _IOR('|', 0x83, int) +//! #define RUST_MISC_DEV_SET_SHARED_VALUE _IOW('|', 0x84, int) //! //! int main() { //! int value, new_value; @@ -86,6 +88,62 @@ //! return -1; //! } //! +//! value++; +//! +//! // Set shared value to something different +//! printf("Submitting new shared value (%d)\n", value); +//! ret =3D ioctl(fd, RUST_MISC_DEV_SET_SHARED_VALUE, &value); +//! if (ret < 0) { +//! perror("ioctl: Failed to submit new value"); +//! close(fd); +//! return errno; +//! } +//! +//! // Close the device file +//! printf("Closing /dev/rust-misc-device\n"); +//! close(fd); +//! +//! // Open the device file again +//! printf("Opening /dev/rust-misc-device again for reading\n"); +//! fd =3D open("/dev/rust-misc-device", O_RDWR); +//! if (fd < 0) { +//! perror("open"); +//! return errno; +//! } +//! +//! // Ensure new value was applied +//! printf("Fetching new value\n"); +//! ret =3D ioctl(fd, RUST_MISC_DEV_GET_SHARED_VALUE, &new_value); +//! if (ret < 0) { +//! perror("ioctl: Failed to fetch the new value"); +//! close(fd); +//! return errno; +//! } +//! +//! if (value !=3D new_value) { +//! printf("Failed: Committed and retrieved values are different (%d -= %d)\n", +//! value, new_value); +//! close(fd); +//! return -1; +//! } +//! +//! value =3D 0; +//! // Ensure non-shared value is still 0 +//! printf("Fetching new value\n"); +//! ret =3D ioctl(fd, RUST_MISC_DEV_GET_VALUE, &new_value); +//! if (ret < 0) { +//! perror("ioctl: Failed to fetch the new value"); +//! close(fd); +//! return errno; +//! } +//! +//! if (value !=3D new_value) { +//! printf("Failed: Committed and retrieved values are different (%d -= %d)\n", +//! value, new_value); +//! close(fd); +//! return -1; +//! } +//! //! // Close the device file //! printf("Closing /dev/rust-misc-device\n"); //! close(fd); @@ -105,7 +163,7 @@ miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration}, new_mutex, prelude::*, - sync::Mutex, + sync::{Arc, Mutex}, types::ARef, uaccess::{UserSlice, UserSliceReader, UserSliceWriter}, }; @@ -113,6 +171,8 @@ const RUST_MISC_DEV_HELLO: u32 =3D _IO('|' as u32, 0x80); const RUST_MISC_DEV_GET_VALUE: u32 =3D _IOR::('|' as u32, 0x81); const RUST_MISC_DEV_SET_VALUE: u32 =3D _IOW::('|' as u32, 0x82); +const RUST_MISC_DEV_GET_SHARED_VALUE: u32 =3D _IOR::('|' as u32, 0x83= ); +const RUST_MISC_DEV_SET_SHARED_VALUE: u32 =3D _IOW::('|' as u32, 0x84= ); =20 module! { type: RustMiscDeviceModule, @@ -137,7 +197,10 @@ fn init(_module: &'static ThisModule) -> impl PinInit<= Self, Error> { }; =20 try_pin_init!(Self { - _miscdev <- MiscDeviceRegistration::register(options, ()), + _miscdev <- MiscDeviceRegistration::register( + options, + Arc::pin_init(new_mutex!(Inner { value: 0_i32 }), GFP_KERN= EL)? + ), }) } } @@ -148,8 +211,9 @@ struct Inner { =20 #[pin_data(PinnedDrop)] struct RustMiscDevice { + shared: Arc>, #[pin] - inner: Mutex, + unique: Mutex, dev: ARef, } =20 @@ -157,7 +221,7 @@ struct RustMiscDevice { impl MiscDevice for RustMiscDevice { type Ptr =3D Pin>; =20 - type Data =3D (); + type Data =3D Arc>; =20 fn open(_file: &File, misc: &MiscDeviceRegistration) -> Result>> { let dev =3D ARef::from(misc.device()); @@ -167,7 +231,8 @@ fn open(_file: &File, misc: &MiscDeviceRegistration) -> Result, _file: &File, cmd: = u32, arg: usize) -> Result match cmd { RUST_MISC_DEV_GET_VALUE =3D> me.get_value(UserSlice::new(arg, = size).writer())?, RUST_MISC_DEV_SET_VALUE =3D> me.set_value(UserSlice::new(arg, = size).reader())?, + RUST_MISC_DEV_GET_SHARED_VALUE =3D> { + me.get_shared_value(UserSlice::new(arg, size).writer())? + } + RUST_MISC_DEV_SET_SHARED_VALUE =3D> { + me.set_shared_value(UserSlice::new(arg, size).reader())? + } RUST_MISC_DEV_HELLO =3D> me.hello()?, _ =3D> { dev_err!(me.dev, "-> IOCTL not recognised: {}\n", cmd); @@ -204,7 +275,7 @@ fn drop(self: Pin<&mut Self>) { impl RustMiscDevice { fn set_value(&self, mut reader: UserSliceReader) -> Result { let new_value =3D reader.read::()?; - let mut guard =3D self.inner.lock(); + let mut guard =3D self.unique.lock(); =20 dev_info!( self.dev, @@ -217,7 +288,38 @@ fn set_value(&self, mut reader: UserSliceReader) -> Re= sult { } =20 fn get_value(&self, mut writer: UserSliceWriter) -> Result { - let guard =3D self.inner.lock(); + let guard =3D self.unique.lock(); + let value =3D guard.value; + + // Free-up the lock and use our locally cached instance from here + drop(guard); + + dev_info!( + self.dev, + "-> Copying data to userspace (value: {})\n", + &value + ); + + writer.write::(&value)?; + Ok(0) + } + + fn set_shared_value(&self, mut reader: UserSliceReader) -> Result { + let new_value =3D reader.read::()?; + let mut guard =3D self.shared.lock(); + + dev_info!( + self.dev, + "-> Copying data from userspace (value: {})\n", + new_value + ); + + guard.value =3D new_value; + Ok(0) + } + + fn get_shared_value(&self, mut writer: UserSliceWriter) -> Result { + let guard =3D self.shared.lock(); let value =3D guard.value; =20 // Free-up the lock and use our locally cached instance from here --=20 2.49.0