From nobody Tue Dec 16 22:14:04 2025 Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) (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 C6243148850; Fri, 30 May 2025 20:46:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748638014; cv=none; b=uedwz9AtZZQASWn49wFdGZ4gvblXXQSseOGClDSQUc4skGXiz8/Q8HYZZa26HPeQWOSTU6Wl6Z79X4FhXXQV7j6Umy7O1qxUjW5j9VtB9eWco6WTmPQjGYWVe0k4ygygLMt/nSLwJNr/boRy6gHfWNEq74Uk5RtW1XYXtoNEn80= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748638014; c=relaxed/simple; bh=SFRlmYh+6ofBFqIE2RKYxAEB1HsZDn6u6OmpOZY6Ihw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MMg8NPjA5XAsEAwlhoWeloqvdOeBz61hTV9floHPsLfwOIaPsj1F6vm56sfC2yZET9XGgxcSwYJftIXJVpMgfE84l0PrvMF5MS7gB3TRzj/Hoy/AaPlE6VU97qXW44mNzJlaFqGkN7u93SFHH0bQd4Dh/F8unn/EXYTJwJ6Zw9g= 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=EnhT+zWe; arc=none smtp.client-ip=209.85.128.47 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="EnhT+zWe" Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-450cf0120cdso19186105e9.2; Fri, 30 May 2025 13:46:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1748638011; x=1749242811; 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=vXKOxgUXd99UndQ/sdm1iF0yL3wtNosoi9ftAa8VQYM=; b=EnhT+zWe8C7R2IOB/W20pva1YgOFdPdpGU1MhIEuWiTh6UUckjsDo8pmk8sC/Yc4BF AkLeB4ZaID8tTNxbctf8dBFu4vHK/531okvdfBaz7+OBOkZpBJXPaX/ZpqoLMLohamBT HzxvV4+0Zop3GxkKzINPwfBs22ptpssFbv/XiTEfq7vidqnFSlWBaJ8XmLvfDPo1Zdvd JgSMvP9EncnXfL0GsTz6COaFXpzQFPU7Ymkdj7VnZzI7mGk+IXnCtpi5rDq/xE9JAi0f bs0JGQsJhi/+dAiDx7GLXl1yEnW6v1Hry69Dvey4lw4ZwYx+7QgKJDkyH9r8Hy0taW63 UULA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748638011; x=1749242811; 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=vXKOxgUXd99UndQ/sdm1iF0yL3wtNosoi9ftAa8VQYM=; b=qBEaSoWpxLFDDDwAwHxNgFAyf46GABSI1ucqDe/efaHnjO9vqbQ9MEpScge30P/Akm tsDAce2HbhNP20uacIrkuPPlSVZu2lPfkXerNTiGBM6qc5d0I4XEAPnMsfTxgLmJhmNt +3dIWH8mMjip9iv3t8p+tLApwVd+kja052Am7Qh1Amm8QlTvpues0UXptOs4h474Tvfs qydvH/EHyXWT6GT+NuBra9+GjLnxQOdjyCDzKE+Q6usCn8si4sGHNP/1m1xT9auNwqx6 Tjn4dSwRxsSpDX0oH9FRNY/a2oYgNoPSIaYaENCx7wHcgubqiWtkTdYxw/RJCrxL7jzp 67Rg== X-Forwarded-Encrypted: i=1; AJvYcCU1fNoktrTR1xR0ernNZvaU2TfhyGBNz/1ClkIE/CgDw9sIFk33o77kr6DbmVRlJezu4+yjKJA0KdZmYBBCOLc=@vger.kernel.org, AJvYcCWCDIKHZKtDUR575TMNOWJJv4WDOqxQkUWQl6Ke+mZeRv20oDA0/aSfduv/pFEn/IMyCFkHCH0I/0zDedo=@vger.kernel.org X-Gm-Message-State: AOJu0Yw5YHa0oDMkjH6IqckJTbw2B4V+ZXGGwOh4I2SPifbc5eZt7rHt l21Th2bGlSToqy8Irf51Cic4CYhmyNBWNWIgwO4dc2n9Ybjb+PaSMTMCUO3mwA== X-Gm-Gg: ASbGncuVYAqMmMUdDgAsqwnI12i2PYf82C/MQGtMv0Ise974klAW5jZU7Hc6j5Gnum2 k2IBsNQS3l9t6oIDwCkyeyPPTIDE7IxPJbLBkMpOZ4K66mf6Glar+tjctfNv8hYF94HLlaz2t87 1SGy+a61KtZLUbeFo58P8a0UwdpECRP+yjVg8sSa4uK+QCSApHyH4dzNYHyLHqJEOdBqdnCxgi4 ZVPIkTXmgAmALIc56Ah9nMq//o9xvB994bJVf721H26zC4t+s66HTHuWfLwJiIZTGUUgkg+FR9P y7E3C1Rrq9O7beEIAyz/WrJ/lz2h623vMf0/9AFd X-Google-Smtp-Source: AGHT+IFi33nyLxjzry9z9CTrFkcpY6FmCNpbJwpsfa5mTciUHelZ8LThn0HAvz3SF98JAu7c2eLYVQ== X-Received: by 2002:a05:600c:614a:b0:450:cea0:1781 with SMTP id 5b1f17b1804b1-450d64f57e7mr48318945e9.16.1748638010779; Fri, 30 May 2025 13:46:50 -0700 (PDT) Received: from [10.0.1.162] ([2001:871:22a:cd68::171c]) by smtp.googlemail.com with ESMTPSA id 5b1f17b1804b1-450d7fa21e4sm28045405e9.11.2025.05.30.13.46.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 May 2025 13:46:50 -0700 (PDT) From: Christian Schrefl Date: Fri, 30 May 2025 22:46:27 +0200 Subject: [PATCH v4 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: <20250530-b4-rust_miscdevice_registrationdata-v4-1-d313aafd7e59@gmail.com> References: <20250530-b4-rust_miscdevice_registrationdata-v4-0-d313aafd7e59@gmail.com> In-Reply-To: <20250530-b4-rust_miscdevice_registrationdata-v4-0-d313aafd7e59@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=1748638009; l=3233; i=chrisi.schrefl@gmail.com; s=20250119; h=from:subject:message-id; bh=SFRlmYh+6ofBFqIE2RKYxAEB1HsZDn6u6OmpOZY6Ihw=; b=7HkNtcPUX0a77Ck8dF9GuCPyQMNpXOibz/MY2IphO2XnWzqHT3kOQU/sn+iooeU9baNQoXQJZ Zy15puE48fQCdRx2GvOnuIp9xcfFko5Z06QA0RkFLwAkovy+Z07u4BF 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: 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 86562e738eac85480a048041e979335b81c5e3c9..7ab70d5f76099c3442dce5b02c6= b226fc74c851e 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. /// @@ -345,17 +345,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 @@ -406,6 +395,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, + // - `slot` is pinned in memory. + unsafe { PinInit::::__pinned_init(slot, ptr) } + }) + } +} =20 /// Types that are _always_ reference counted. /// --=20 2.49.0 From nobody Tue Dec 16 22:14:04 2025 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (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 E47B02116F5; Fri, 30 May 2025 20:46:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748638016; cv=none; b=VHumA0hNrlT/pS6QnGwamEmIyNZN2oqoSeHiZRgE2GwPXfOQ04w9+Tx9mCt7WXcfebfLER7rLrHQ0OA7O+o4DJ/F5ETf3/z+wSP0dDrsvPL5sVqoWL9qtlksA6iqT0osCHeKS5niaNJmA9cMjFEZ6SC3KGTdJm9ZiZgbj6XhQf8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748638016; c=relaxed/simple; bh=nGLnGDJCcqKkua2F7z/rEsxXVnf+YzZJSN1wQu4SzmY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RDsP29Aw+2LqDAficvsklAsTW0kA58xgM6lmk73hwJ5ht1gP1MOJA9l7UOLjpR7YI2KGGtlC/izpI3iTp2K0vRvZkUc/29cLelaGdD6iQe9khwWd9ktfFujJ5gjCXQbaHQFRS07D2w8dhilHdyJZhF9td9/lG7FosYSFOJHPrhc= 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=CO+cBK+i; arc=none smtp.client-ip=209.85.128.50 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="CO+cBK+i" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-43cf257158fso18196105e9.2; Fri, 30 May 2025 13:46:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1748638012; x=1749242812; 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=Tp1evWHjYS1kM2spIBLb9Guyc1fvgCNsWTii1qBWPN4=; b=CO+cBK+ilUxwT7eRSWCN44vKX9O8cCfzn+d3Sho04MTQyEzinE1ScyYokgqGVR1RG9 yHVayJMZMMeuZAIQ6zE1H1SoPAq79DD+gxKOYJOoFuc1Kqm92JdXR39NpoL1oCta6y7i J81di08NIv5MPmvKeOhMJbegAbdMW8hLx5SHpx1ru/jXxtzxykee9O7aG/y7Wjzbyq98 LNM9tGJzY1q25Mw9hjhuoy1jWvbsF9jX6yhZQdGGHi0lcA87ung2lSGA+5HGfX6NL2uD uGM/NCKlfylbeiXiW+ADKINpDGBvTcW2TQoegZ9V0+AzPv7JfcDCg8505+MRJt9KuE8A aPkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748638012; x=1749242812; 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=Tp1evWHjYS1kM2spIBLb9Guyc1fvgCNsWTii1qBWPN4=; b=pHODX1MuLoJdioCPyoVhTES4bbwgJBi7X/d+zce38dYASocFDmObCPnJzvFhiYYI5s FZ5A4SsG5crSs4VA9hmAHc100AGrm3Kd6Spt0fpZVktbnE1SMLtmy/QU2DdlyEt499sV +pjSPqer01M9SdqiigmBwGITF4gVZds/Z0xUQodmWbEt00hSfcrcJPgr0z6YCeTbMs6x GjWm8SH0hE1LAClYAppcxkguh38ZW0DiI8o8tqJtP195jVujNy1wmrq9iQlRyLB4UojM WliGLS70LNdQdjVkcw7IF/mqB8+G8FCeu+rmKmy1dBTOE/oz+S3cc2XWplIU0stLMyWv ZKDA== X-Forwarded-Encrypted: i=1; AJvYcCX2FTDtLjQ238TeokZoXPy2UBu1UFVlSb+LUpqB4RBpfGdMx96iGOuYR8tmSbh+ACzOycGZ9IKl0Pa5qkw=@vger.kernel.org, AJvYcCX5aErwTal5aBhjKleqjWyc3tiBexI0HfrZWz2DWtQjdV/CWO5NM3FfxTkH4GeLBUPg3+i5NiyTC1gN42nZAiA=@vger.kernel.org X-Gm-Message-State: AOJu0YwxCDKCnMY2zEwahVHVJ7s3ppjmO7qEZ/SJwn7wcToXg0m8gWaj IWwBtkBSxrr5XaFhx25BOW2Msg7zlctB7gMTUsrkMvJT3p/aPOpGOx0L X-Gm-Gg: ASbGncvuOZE8OQJawGIhisxhEPZr3JXYBZhkl6JLinEKkJC6R2KXqwkOvqZa2ek9gfm 0bSa1vsQPYXi36hvmlyDsK8tJmFg2RkPuglMEln6NoCEJqclwbUJDRaD9K4nIza3bemHUBPntU9 5ZmoMBPOjiNyP8NoL987iA7shbB1sbQQkNwukyH72CfRNmJ5Kwp6lhWvNwAbeJvw1J6Khe42UdM 3mH2xsgDdHQsWmF0NjOJoQuia8tLqr4d+LpKZ0Ev6UfNc5gyt0Tw6A2Vyn26+gN7PTvvlFn4mce z5EDFvEBmq95/dNMoal2z5nzPi7/EZ0KmtOhhB+m X-Google-Smtp-Source: AGHT+IGnh9Y7zNX5kdQRJG+d5y1Obtrkr/1jZ3SeTbS8/JDPNf85HPVepv/1pC9Z4huf5Zl4TGBTIQ== X-Received: by 2002:a05:600c:45d0:b0:43b:ca39:6c7d with SMTP id 5b1f17b1804b1-450d882b1e0mr40008845e9.3.1748638011722; Fri, 30 May 2025 13:46:51 -0700 (PDT) Received: from [10.0.1.162] ([2001:871:22a:cd68::171c]) by smtp.googlemail.com with ESMTPSA id 5b1f17b1804b1-450d7fa21e4sm28045405e9.11.2025.05.30.13.46.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 May 2025 13:46:51 -0700 (PDT) From: Christian Schrefl Date: Fri, 30 May 2025 22:46:28 +0200 Subject: [PATCH v4 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: <20250530-b4-rust_miscdevice_registrationdata-v4-2-d313aafd7e59@gmail.com> References: <20250530-b4-rust_miscdevice_registrationdata-v4-0-d313aafd7e59@gmail.com> In-Reply-To: <20250530-b4-rust_miscdevice_registrationdata-v4-0-d313aafd7e59@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=1748638009; l=10571; i=chrisi.schrefl@gmail.com; s=20250119; h=from:subject:message-id; bh=nGLnGDJCcqKkua2F7z/rEsxXVnf+YzZJSN1wQu4SzmY=; b=EH1IsxZqOY0bdsjyD+6CjYmZBG0IYAUB26PBQ4A4SGKvXeX9cKjxlPS6ZfsGl4Np0GzCwU5Fi ZL6MlZ0xNjYClG0BEqmV+34Ym3i56pw/Ju6Qi1JKu9r5p8kUf1beE9r 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 Signed-off-by: Christian Schrefl --- rust/kernel/miscdevice.rs | 79 ++++++++++++++++++++++++++++++------= ---- samples/rust/rust_misc_device.rs | 4 +- 2 files changed, 62 insertions(+), 21 deletions(-) diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs index b4c5f74de23d6f4fbcdebfe408d6954884609e8f..ad9fc0b2383860cb976c57a398f= 372280c19513c 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}, @@ -20,6 +20,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)] @@ -45,32 +46,46 @@ pub const fn into_raw(self) -> bindings:= :miscdevice { /// # Invariants /// /// `inner` is a registered misc device. -#[repr(transparent)] +#[repr(C)] #[pin_data(PinnedDrop)] -pub struct MiscDeviceRegistration { +pub struct MiscDeviceRegistration { #[pin] inner: Opaque, + #[pin] + data: Opaque, _t: PhantomData, } =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::RegistrationData` is also `Sen= d`. +unsafe impl Send for MiscDeviceRegistration where T::Reg= istrationData: Send {} + +// SAFETY: +// - All `&self` methods on this type are written to ensure that it is saf= e to call them in +// parallel. +// - `MiscDevice::RegistrationData` is always `Sync`. +unsafe impl Sync for MiscDeviceRegistration {} =20 impl MiscDeviceRegistration { /// Register a misc device. - pub fn register(opts: MiscDeviceOptions) -> impl PinInit { + pub fn register( + opts: MiscDeviceOptions, + data: impl PinInit, + ) -> impl PinInit { 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) }) @@ -93,13 +108,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::RegistrationData { + // 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` is valid for dropping and nothing uses it a= nymore. + unsafe { core::ptr::drop_in_place(self.data.get()) }; } } =20 @@ -109,6 +135,13 @@ pub trait MiscDevice: Sized { /// What kind of pointer should `Self` be wrapped in. type Ptr: ForeignOwnable + Send + Sync; =20 + /// The additional data carried by the [`MiscDeviceRegistration`] for = this [`MiscDevice`]. + /// If no additional data is required than the unit type `()` should b= e used. + /// + /// This data can be accessed in [`MiscDevice::open()`] using + /// [`MiscDeviceRegistration::data()`]. + type RegistrationData: Sync; + /// Called when the misc device is opened. /// /// The returned pointer will be stored as the private data for the fi= le. @@ -178,18 +211,24 @@ 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. + 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..67a6172fbbf72dd42a1b655f5f5= a782101432707 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 RegistrationData =3D (); + fn open(_file: &File, misc: &MiscDeviceRegistration) -> Result>> { let dev =3D ARef::from(misc.device()); =20 --=20 2.49.0 From nobody Tue Dec 16 22:14:04 2025 Received: from mail-wr1-f46.google.com (mail-wr1-f46.google.com [209.85.221.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 799AF2185A6; Fri, 30 May 2025 20:46:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748638016; cv=none; b=e+KY5xbwqFowlWMfKdsSNntpNaaSMmlgJ+62X2QH1wWLrGdXyNcVsLYsqZcVqzG45raLwAgrNOiHhnQEdsQKtYB9KxlY1yzMOzQvpy+GP2DmkJgWtrDnCRuixHlcmLjGgxMRHH2Jo7XDtaBXNP1CmpmThzS9D++D6hYlV+/Jj/k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748638016; c=relaxed/simple; bh=Tl9KVLjAYo8nLG7kxM/4N+/E474ZkjS1L1eq4887tp0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ie6OrECrWXuDDH6L7C7BqNnFMHR9W+7WlZvgzcD9CryKrdRtrP8HhzhGegsMW5QEPg8x0fBF9b1TgJKC0ByjQyYm1aXFbwuNId/ylUA+TBoxojdmIcgCCgsx0DaIcrpjOTWMsGDQcd3MEB9ABbIGZ8pc5gljvqhyVeeSO1IlGoo= 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=SajlyGUO; arc=none smtp.client-ip=209.85.221.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="SajlyGUO" Received: by mail-wr1-f46.google.com with SMTP id ffacd0b85a97d-3a4ef2c2ef3so1839905f8f.2; Fri, 30 May 2025 13:46:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1748638013; x=1749242813; 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=r3qDm3mLZcRdoxx+80MjSPgoFL99DEoKU4L7ojs6jpw=; b=SajlyGUOoZN6g4NnZHQ7Eni4XTBwDWb9C9SaHAIm9u71jiyE54loPZl197aIBYRrlj URVB8Kru3ihz3HYnwzTI7VDv6UBD344zc692hp1iyOiJtK3JxqWDlm18wWRU/Anui9CA k/K3JZcACmgkFzkXLxPMGvUx2t/d5HSfgTlT96xQjntFlh5xWThljLtPmjJlQ5bTVgE9 WMSnFgSVtT+9bbU2p4lJKBXrdvLuDxbW4emDz9arcKzxnWL5QN6LNxvtEwo+juFsYINE sBy5vUtMvNRvol0jUMfpODFgCUSnenrH9xaqavLjhGtBjPHf5iGJAhHWkPxZv1VfhOpU RqFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748638013; x=1749242813; 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=r3qDm3mLZcRdoxx+80MjSPgoFL99DEoKU4L7ojs6jpw=; b=mKYQoDlAifK8RZk/Lw+mkskZEl76x4fTgJUw2cG2a+ED7IvgnL67MrGFi5xDSPHyjH 5PMSqLOEtPMOZ4JtqmS6LycMh1hX/2sjkW9cWfpS2OCAFK5Uo7bO0UTJuYi0iqnTigk0 xQZYKBnvE2/Zmny9rok13O+Vi3icVwyQQWjzyaDbXWnSq9Tw9YVy7TfhJOEatFVQsFVR xY2etbIy5OSc685WSiNAVnU8qPDGfGJYXM1ystSWa/t2oVaju+hI4kUtevfysJ2AZDVM GvruEDqgF881T0XaMFVc7zNEezemsSL/4fPbdDDRgiw2QqAK+ZgrDh7Cm6KPh7RM43q4 405g== X-Forwarded-Encrypted: i=1; AJvYcCVe8ks0Gka4UHJ/VaSAw7E/oEdjk79Q745XLXcZqw8DyKkdF+Mx0IlFKJCesOFoeRNTlDLnIJmjoGRZshmqCgk=@vger.kernel.org, AJvYcCXXrgjvx+V00QGQwMTuBAUzUG/djJDE5vkaqTAs8IGfvasrdFhVX6npTzcSgiRX94W5WLx7G+hAYfxZljo=@vger.kernel.org X-Gm-Message-State: AOJu0YzBCLVfKmZakXH9EFVDWubkrs+bVe2oFnVc804wWYVYQVRxaZmG hW22X6r0DW1rdsKAHrdGkZAvijYuiN8krXcP/yWNTf3UxjB8cTB2WXBp X-Gm-Gg: ASbGncsnl8Eif9GhU636MO/5++bDs1lzIc1IeIzGoh2iAGqTZWBSeqc6k5wFrHEsYnD 5biTPEmVGyDn3av5q9IbAxKErpx3Tk80kLMdKRQMIsP7LeuJHOy22hLaX4HqZ8k5IF5G7Oz0Qx3 QqbYFaU+qrwjZLIt+3cpzC1nSugRF9ZRTk9sf+040loUiUwyx3enZJWDuZ34xUNnXtk+l+7tf1v wXDHM2UaxQKsh0v1U107k20NK9baTHu9WPAN7bUGs5vIcrOidX76sV3ss0Daq1LOcZs9o6A1ybd 9LK3NlAQfmOA3NXE+bnzUauJP2wJEcpPRSO291sn X-Google-Smtp-Source: AGHT+IG2U7sxwRFJgIe+wXnLV5jDUaFc12c2xgUl6sDvdj2Uc3RTKkIChBO0snB+hq8AiC8DumV1uA== X-Received: by 2002:a5d:5f84:0:b0:3a4:e706:52f5 with SMTP id ffacd0b85a97d-3a4f7a4b4e2mr4055593f8f.13.1748638012631; Fri, 30 May 2025 13:46:52 -0700 (PDT) Received: from [10.0.1.162] ([2001:871:22a:cd68::171c]) by smtp.googlemail.com with ESMTPSA id 5b1f17b1804b1-450d7fa21e4sm28045405e9.11.2025.05.30.13.46.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 May 2025 13:46:52 -0700 (PDT) From: Christian Schrefl Date: Fri, 30 May 2025 22:46:29 +0200 Subject: [PATCH v4 3/3] rust: miscdevice: adjust the rust_misc_device sample to use RegistrationData. 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: <20250530-b4-rust_miscdevice_registrationdata-v4-3-d313aafd7e59@gmail.com> References: <20250530-b4-rust_miscdevice_registrationdata-v4-0-d313aafd7e59@gmail.com> In-Reply-To: <20250530-b4-rust_miscdevice_registrationdata-v4-0-d313aafd7e59@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=1748638009; l=8048; i=chrisi.schrefl@gmail.com; s=20250119; h=from:subject:message-id; bh=Tl9KVLjAYo8nLG7kxM/4N+/E474ZkjS1L1eq4887tp0=; b=NQY75oA+Cqbyk6jh52HUGfjBuBmiXt2Cs4Heq8BWGIpSE/uxLWmKPQ+zBMkQk/0bOf7QFAIYR 2ZgEtrbnvqdDZ7CxWjRzmpmrgf8u3CWRrUjxw3xoVP6u3+OsHXFyYwe 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 RegistrationData of MiscDeviceRegistration. This is mostly to demonstrate the capability to share data in this way. Signed-off-by: Christian Schrefl Reviewed-by: Benno Lossin --- samples/rust/rust_misc_device.rs | 120 +++++++++++++++++++++++++++++++++++= ---- 1 file changed, 110 insertions(+), 10 deletions(-) diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_devi= ce.rs index 67a6172fbbf72dd42a1b655f5f5a782101432707..3c96cf8fe747427106f2e436c3d= ba33008c7fd53 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); @@ -94,7 +152,6 @@ //! return 0; //! } //! ``` - use core::pin::Pin; =20 use kernel::{ @@ -105,7 +162,7 @@ miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration}, new_mutex, prelude::*, - sync::Mutex, + sync::{Arc, Mutex}, types::ARef, uaccess::{UserSlice, UserSliceReader, UserSliceWriter}, }; @@ -113,6 +170,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, @@ -130,14 +189,17 @@ struct RustMiscDeviceModule { =20 impl kernel::InPlaceModule for RustMiscDeviceModule { fn init(_module: &'static ThisModule) -> impl PinInit { - pr_info!("Initialising Rust Misc Device Sample\n"); + pr_info!("Initializing Rust Misc Device Sample\n"); =20 let options =3D MiscDeviceOptions { name: c_str!("rust-misc-device"), }; =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 +210,9 @@ struct Inner { =20 #[pin_data(PinnedDrop)] struct RustMiscDevice { + shared: Arc>, #[pin] - inner: Mutex, + unique: Mutex, dev: ARef, } =20 @@ -157,7 +220,7 @@ struct RustMiscDevice { impl MiscDevice for RustMiscDevice { type Ptr =3D Pin>; =20 - type RegistrationData =3D (); + type RegistrationData =3D Arc>; =20 fn open(_file: &File, misc: &MiscDeviceRegistration) -> Result>> { let dev =3D ARef::from(misc.device()); @@ -167,7 +230,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); @@ -193,7 +263,6 @@ fn ioctl(me: Pin<&RustMiscDevice>, _file: &File, cmd: u= 32, arg: usize) -> Result Ok(0) } } - #[pinned_drop] impl PinnedDrop for RustMiscDevice { fn drop(self: Pin<&mut Self>) { @@ -204,7 +273,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 +286,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