From nobody Fri Oct 3 06:33:22 2025 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (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 82F3829BD92 for ; Thu, 4 Sep 2025 21:14:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757020453; cv=none; b=NAfowhj5hhG5z6zILT1YfulFNTVOvd9KW0NXYZKg8ITElP/kOp958bGocuoKtQDrwPJBbSgDLMFNfnssVpmzCUE30izH+KQLJwq07vJ5hxrAWcDwxoi8uTx79yTEE6PclBMkPmHD25kyzFfJP6Ov9nHPNOoSnjmK8jIcYf2zwfA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757020453; c=relaxed/simple; bh=IX+FmUJAsAt3bbv6WP+sppw+TzVK8DRPJvw00HnhzEY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=LSN5de816wm3Th/sx2vc8eT3XDYBnjSnHxCcIqA7HHcGMN1QjC0PVmPuyu0kkj6GN7PN/lhEmApGJ2k8r6xmdTxtSrLK3g+BKJLDbXr2wPQCQgfrE9gMjTyTjQY5xn9oUqZcynQOHJDIltxI6zNSxH7AbVw8KgSt4UTINX5XToE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--mmaurer.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=zoV5pZBM; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--mmaurer.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="zoV5pZBM" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-3234811cab3so1699766a91.3 for ; Thu, 04 Sep 2025 14:14:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1757020451; x=1757625251; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=arN2pmQBVtYOvUg5waEtOueGktesFqbTHbSY6edCK8Y=; b=zoV5pZBMjfEmoWMvwse4R8qkrAJrkPvbbmhaIxm845Ljhfed9OzicE8/JKDVdlqm9A y0eFhqMpwGr8AzBDwGgvTvEr015ZxlLv4edOZa4ze6ue8d/EsxYehOSjP9YncSfdecux ssimJOs979aStSmF0nUvwz3jhwPgbrr/a5Lrzjsv6JshHEZPFnft+H7XqEEJ1A51yfWR AfQgmH0GVg18mczS3a8TURLFGES/+TOHGpXMvPl5qHV/Huz9Q0r9+eKS0qP7KiYHHvfL s3F26BGSMLDLyxm7Kxn3HrCFJCRiKflBVxp+td3aKX1tfjCB6LbnvfuluNimNPbKYy0d tEow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757020451; x=1757625251; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=arN2pmQBVtYOvUg5waEtOueGktesFqbTHbSY6edCK8Y=; b=th3nSNFecX9WIZQHIfKFNHXIPRlujq1AQexm8R197FyOOJxFHe1deFYlaSLAeWbQ7w 5fxGZ11V/MjBCLdKhIlGqZdcqfMxkPbf9DDzisEPq8fXiwFNRDKuug6avHugSIP8ZhwJ RnrWBWNAm/q92wlrNnw3zb4PT5wx41vret9C5XdwmHtso3oZ2/ktyyWqIrgJ7sDGi4E3 ghUMjtK4zuSDvciJaBDOko/3SKMbkiQWeC3bK+6p05LXnqL5Z1zgUAT8503F1hAir64v 3QrZmw59h2KQdbMFa6a+g53QQ+qkvgUOQN4+s1KNgo+2ilBwvz1HYHUW3SJV5zf798jk N+gw== X-Gm-Message-State: AOJu0YyWQfGqI0JVZiw87Xtdhxly23SOzHBaotBPcu3aXoX16sxYQnxg Sf7VwO1IeOaLxoeoL2nnqkO2j5V0CXO+G67uIe301RxpRcAdHJ1Zx3s/5+ti1TIC2VL0bIC+FLz KJ9KbZbm6gQ== X-Google-Smtp-Source: AGHT+IGAgAM+cMeURLjfyTSd3DY3sRO4QhH61uz52v0RlipIbIDIiNT3/8p2I/kKs4JfuGm3wPmrDUpj6CNx X-Received: from pjbsl12.prod.google.com ([2002:a17:90b:2e0c:b0:32b:61c4:e48b]) (user=mmaurer job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:1b0d:b0:32b:bc2c:f9fd with SMTP id 98e67ed59e1d1-32bbc2cfd32mr1255448a91.24.1757020450800; Thu, 04 Sep 2025 14:14:10 -0700 (PDT) Date: Thu, 04 Sep 2025 21:13:56 +0000 In-Reply-To: <20250904-debugfs-rust-v11-0-7d12a165685a@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250904-debugfs-rust-v11-0-7d12a165685a@google.com> X-Developer-Key: i=mmaurer@google.com; a=ed25519; pk=2Ezhl7+fEjTOMVFpplDeak2AdQ8cjJieLRVJdNzrW+E= X-Developer-Signature: v=1; a=ed25519-sha256; t=1757020440; l=7445; i=mmaurer@google.com; s=20250429; h=from:subject:message-id; bh=IX+FmUJAsAt3bbv6WP+sppw+TzVK8DRPJvw00HnhzEY=; b=WIjuHal8JPzrlTATTMgG7QCC701Z6YtD5hkSb1UaUNhCrvBGdxIBURre06/pLD+tg6sy0M+OT p082DNgLNfLC2S0n0yJ6Gf/6LQ2C7vCpyJAysUK+AM6n08SlbAij80Y X-Mailer: b4 0.14.2 Message-ID: <20250904-debugfs-rust-v11-5-7d12a165685a@google.com> Subject: [PATCH v11 5/7] samples: rust: Add debugfs sample driver From: Matthew Maurer To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Greg Kroah-Hartman , "Rafael J. Wysocki" , Sami Tolvanen , Timur Tabi , Benno Lossin , Dirk Beheme Cc: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, Matthew Maurer Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Adds a new sample driver that demonstrates the debugfs APIs. The driver creates a directory in debugfs and populates it with a few files: - A read-only file that displays a fwnode property. - A read-write file that exposes an atomic counter. - A read-write file that exposes a custom struct. This sample serves as a basic example of how to use the `debugfs::Dir` and `debugfs::File` APIs to create and manage debugfs entries. Signed-off-by: Matthew Maurer --- MAINTAINERS | 1 + samples/rust/Kconfig | 11 ++++ samples/rust/Makefile | 1 + samples/rust/rust_debugfs.rs | 151 +++++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 164 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8f2dbf71ca3f8f97e4d7619375279ed11d1261b2..5b6db584a33dd7ee39de3fdd008= 5d2bd7b7bef0e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7481,6 +7481,7 @@ F: rust/kernel/devres.rs F: rust/kernel/driver.rs F: rust/kernel/faux.rs F: rust/kernel/platform.rs +F: samples/rust/rust_debugfs.rs F: samples/rust/rust_driver_platform.rs F: samples/rust/rust_driver_faux.rs =20 diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig index 7f7371a004ee0a8f67dca99c836596709a70c4fa..01101db41ae31b08a86d048cdd2= 7da8ef9bb23a2 100644 --- a/samples/rust/Kconfig +++ b/samples/rust/Kconfig @@ -62,6 +62,17 @@ config SAMPLE_RUST_DMA =20 If unsure, say N. =20 +config SAMPLE_RUST_DEBUGFS + tristate "DebugFS Test Module" + depends on DEBUG_FS + help + This option builds the Rust DebugFS Test module sample. + + To compile this as a module, choose M here: + the module will be called rust_debugfs. + + If unsure, say N. + config SAMPLE_RUST_DRIVER_PCI tristate "PCI Driver" depends on PCI diff --git a/samples/rust/Makefile b/samples/rust/Makefile index bd2faad63b4f3befe7d1ed5139fe25c7a8b6d7f6..61276222a99f8cc6d7f84c26d05= 33b30815ebadd 100644 --- a/samples/rust/Makefile +++ b/samples/rust/Makefile @@ -4,6 +4,7 @@ ccflags-y +=3D -I$(src) # needed for trace events obj-$(CONFIG_SAMPLE_RUST_MINIMAL) +=3D rust_minimal.o obj-$(CONFIG_SAMPLE_RUST_MISC_DEVICE) +=3D rust_misc_device.o obj-$(CONFIG_SAMPLE_RUST_PRINT) +=3D rust_print.o +obj-$(CONFIG_SAMPLE_RUST_DEBUGFS) +=3D rust_debugfs.o obj-$(CONFIG_SAMPLE_RUST_DMA) +=3D rust_dma.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_PCI) +=3D rust_driver_pci.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) +=3D rust_driver_platform.o diff --git a/samples/rust/rust_debugfs.rs b/samples/rust/rust_debugfs.rs new file mode 100644 index 0000000000000000000000000000000000000000..8d394f06b37e69ea1c30a3b0d84= 44c80562cc5ab --- /dev/null +++ b/samples/rust/rust_debugfs.rs @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (C) 2025 Google LLC. + +//! Sample DebugFS exporting platform driver +//! +//! To successfully probe this driver with ACPI, use an ssdt that looks li= ke +//! +//! ```dsl +//! DefinitionBlock ("", "SSDT", 2, "TEST", "VIRTACPI", 0x00000001) +//! { +//! Scope (\_SB) +//! { +//! Device (T432) +//! { +//! Name (_HID, "LNUXDEBF") // ACPI hardware ID to match +//! Name (_UID, 1) +//! Name (_STA, 0x0F) // Device present, enabled +//! Name (_DSD, Package () { // Sample attribute +//! ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), +//! Package() { +//! Package(2) {"compatible", "sample-debugfs"} +//! } +//! }) +//! Name (_CRS, ResourceTemplate () +//! { +//! Memory32Fixed (ReadWrite, 0xFED00000, 0x1000) +//! }) +//! } +//! } +//! } +//! ``` + +use core::str::FromStr; +use core::sync::atomic::AtomicUsize; +use core::sync::atomic::Ordering; +use kernel::c_str; +use kernel::debugfs::{Dir, File}; +use kernel::new_mutex; +use kernel::prelude::*; +use kernel::sync::Mutex; + +use kernel::{acpi, device::Core, of, platform, str::CString, types::ARef}; + +kernel::module_platform_driver! { + type: RustDebugFs, + name: "rust_debugfs", + authors: ["Matthew Maurer"], + description: "Rust DebugFS usage sample", + license: "GPL", +} + +#[pin_data] +struct RustDebugFs { + pdev: ARef, + // As we only hold these for drop effect (to remove the directory/file= s) we have a leading + // underscore to indicate to the compiler that we don't expect to use = this field directly. + _debugfs: Dir, + #[pin] + _compatible: File, + #[pin] + counter: File, + #[pin] + inner: File>, +} + +#[derive(Debug)] +struct Inner { + x: u32, + y: u32, +} + +impl FromStr for Inner { + type Err =3D Error; + fn from_str(s: &str) -> Result { + let mut parts =3D s.split_whitespace(); + let x =3D parts + .next() + .ok_or(EINVAL)? + .parse::() + .map_err(|_| EINVAL)?; + let y =3D parts + .next() + .ok_or(EINVAL)? + .parse::() + .map_err(|_| EINVAL)?; + if parts.next().is_some() { + return Err(EINVAL); + } + Ok(Inner { x, y }) + } +} + +kernel::acpi_device_table!( + ACPI_TABLE, + MODULE_ACPI_TABLE, + ::IdInfo, + [(acpi::DeviceId::new(c_str!("LNUXDEBF")), ())] +); + +impl platform::Driver for RustDebugFs { + type IdInfo =3D (); + const OF_ID_TABLE: Option> =3D None; + const ACPI_ID_TABLE: Option> =3D Some(&ACP= I_TABLE); + + fn probe( + pdev: &platform::Device, + _info: Option<&Self::IdInfo>, + ) -> Result>> { + let result =3D KBox::try_pin_init(RustDebugFs::new(pdev), GFP_KERN= EL)?; + // We can still mutate fields through the files which are atomic o= r mutexed: + result.counter.store(91, Ordering::Relaxed); + { + let mut guard =3D result.inner.lock(); + guard.x =3D guard.y; + guard.y =3D 42; + } + Ok(result) + } +} + +impl RustDebugFs { + fn build_counter(dir: &Dir) -> impl PinInit> + '_ { + dir.read_write_file(c_str!("counter"), AtomicUsize::new(0)) + } + + fn build_inner(dir: &Dir) -> impl PinInit>> + '_ { + dir.read_write_file(c_str!("pair"), new_mutex!(Inner { x: 3, y: 10= })) + } + + fn new(pdev: &platform::Device) -> impl PinInit + '= _ { + let debugfs =3D Dir::new(c_str!("sample_debugfs")); + let dev =3D pdev.as_ref(); + + try_pin_init! { + Self { + _compatible <- debugfs.read_only_file( + c_str!("compatible"), + dev.fwnode() + .ok_or(ENOENT)? + .property_read::(c_str!("compatible")) + .required_by(dev)?, + ), + counter <- Self::build_counter(&debugfs), + inner <- Self::build_inner(&debugfs), + _debugfs: debugfs, + pdev: pdev.into(), + } + } + } +} --=20 2.51.0.355.g5224444f11-goog