From nobody Thu Oct 2 09:16:49 2025 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (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 903BE1CDFD5 for ; Thu, 18 Sep 2025 15:02:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758207745; cv=none; b=iCeTWzTXTPJyOTRJuncLOyPlx7oWy+A5NohziP+gPevtEkzVnW+je88mFzmxgFTz6RARRYy8qcIs2TafjcHxYBEfqQi5sIdDfOOlMarkQPm6/ZJYq6L32PqLiAGy/RTYaEvSkuX+fdCuK1X+2duuRMpvxu1OtCoAt43ZJEe8yv4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758207745; c=relaxed/simple; bh=vJ54JE6+riZlcAldU+0faKQxu82OqxHqyvNXkYI5oGI=; h=Date:Mime-Version:Message-ID:Subject:From:To:Cc:Content-Type; b=IqWDWOHS6gkdwmww64Z+KBEBt/EPVepSWn5kgiLV2EnQlhIvXHafqCb+xK999X3iNQywySfdc1bX0dJj+5rEngp89feXsOXEWPxQuuhRA3WsSRWXlp6y9nN8ewTOUhW3NxFhZrKcksAck2La/zIb8fYqpLhtLHLnTigtjrsbKdA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=x9O0XxUF; arc=none smtp.client-ip=209.85.128.73 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--aliceryhl.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="x9O0XxUF" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-45b467f5173so9410285e9.3 for ; Thu, 18 Sep 2025 08:02:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1758207742; x=1758812542; darn=vger.kernel.org; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date:message-id:reply-to; bh=l7zJnB3yDJu54j7XDPcUHBWHQ2xjhdYOpr3OUldWhZI=; b=x9O0XxUFO7N4ZtNhcCOB7pynd1FZ5QJDaTtXr/WiVlQTD45f0sWeZjhqtrWVjMrc40 ZYp0MdtR54boZEwb6ECU0f9OKqFAzQZ1xBIWXUO6V8EtEd9ac1YWkBCZh13FF2ImyvIt XhDoJo4yxBUwJZOD71VDNcwa8T9MB/O8wXvqPIWrw76tuR+6G/hFnf0KHv8hyAXR/gaF /HiYUR+gF9Rbmf5zgbw4Si8R3bzpwQ9w7kZOm4xj9hy1hsOclSL2kYAivyQSa/HfQh6n ICgE2N9yIcP7q9WjqnYkaZF9Jbulsc3eun/yZQyJmYS6mNO1rY4+VkIQAtkKh0ZjWbxZ T7dg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758207742; x=1758812542; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=l7zJnB3yDJu54j7XDPcUHBWHQ2xjhdYOpr3OUldWhZI=; b=iJIEJMzOjgxgFKYtW25RkLFegXIQMlMTSR7FkaEnGWUFLC3O3Y2+QjLHeyeY2SfKF8 4jDwWhj06LQZVDXBNm3waD5aytca0G+jaerEMFjjXOkHGiJsQ2l79yWeiLgmQu+C1yYl QXASI20+NO0GTIrJh0X5GR6F8lvVC6JA69ju00xmuJ0OyAt4ZjePhX4J27XrEFA2ae3f /FmDlI9umJ/9M96iRG9aB1g3tlJ6sHsuu4OnHtAks5DrmGjxjKGmGYgb94Ezub0bRTNb uqpUULf6K4gH8cRyfwS2yt1qbEfXu1NYipY5yCYp03+zpWxMAJU2z9z2azKQbWNdEIep z+ew== X-Forwarded-Encrypted: i=1; AJvYcCUh/9SRWob3Nvuc+OFhrS4iLyTGp2Z+fYg28/BRVKD/skjzWgalmCK7qyMft0UvIQgpTb+8BvUP2RKGnt0=@vger.kernel.org X-Gm-Message-State: AOJu0YybyjWLdEbusR2UBWwAR9wm05SQ0Y2nOGdeQz5mgPvnTgjXbRoi DLfBpmBdPRTJm7qHnzED8wnmT6Gl3njIf1Pk8eya1C6pMiXGgy5bFx+QjLx0VMV7MZS0idB0HIR q6E9NY9yLB4CXOMkt2A== X-Google-Smtp-Source: AGHT+IGPi4MZRXFcoOWPdUNlDZJMVbEdW8oLBAH+1jAR+Diom6ppak8B/S5RDukjmv+fduoTwCEAHE4877UjRK8= X-Received: from wmbay25.prod.google.com ([2002:a05:600c:1e19:b0:464:f7d9:6b0]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4e93:b0:45f:2d21:cb36 with SMTP id 5b1f17b1804b1-462074c576amr51491305e9.35.1758207742039; Thu, 18 Sep 2025 08:02:22 -0700 (PDT) Date: Thu, 18 Sep 2025 15:02:11 +0000 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 X-B4-Tracking: v=1; b=H4sIAPIezGgC/x3MQQqEMAxA0atI1gbaqKBeRVw4NdVsWmmKDoh3t 7h8i/9vUE7CCmN1Q+JTVGIosHUFbl/CxihrMZChzgy2xytJZozeK2d0MWhG86PGupZ64gVKeCT 28v+m0/w8L+9hGf9kAAAA X-Change-Id: 20250918-write-offset-const-0b231c4282ea X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=7310; i=aliceryhl@google.com; h=from:subject:message-id; bh=vJ54JE6+riZlcAldU+0faKQxu82OqxHqyvNXkYI5oGI=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBozB748rOfzrnjjSiHKGsX0n/x0Z3PtJbpWHfqq gTHB11OZYyJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCaMwe+AAKCRAEWL7uWMY5 Rl4RD/4t8Nbnz6TBtCmQoNUw/ZfJv6wR1kk4pmCvIL62u/kkC7XWhfJGvi1fvuVUZNAsyCukNOb S0+2aa463z8u2qomYAZNc8ronaonyjtPh8NNcdI3G0b73niWeexkLA7J619ZUlfMxHddicnVACb 387tj0pEiWOqKBTAm4dxcr/+IyglGnhIgMkSsJdgzjpOODll2GE5zwJJnuQTzw+HxtNM5sxIPPa DIUAG71t3yxrqpQBxUBIkD4f8Z+QgNAy+eBzjWMRQXz+nrLve/UcrY9Tbmg8v1qMutTTsrLLVCM ghZhVL/Gy0QXTPzEOQBZ2FFHh4Y6LkoRWOn6X90gwyEfoFLn7P00LIxKU9RXwW4tRN9HwSWLqAE /r4ftVa79WR5/TiYyB4eMmiYcsCmxbqv3GEwdnIihYn/ioNDllGczIlZ5MzbsRaOB6c4z1E8X1Y V+V/fZ9VITnZggfsta5SeDYXrsN5/krxJ/EkD2717cEvfHgLxI45/7ruAiL/+WJ7WvXjGBwytIf QtvHPOljIsnugLwZHCGwpAbQQCZXLHKOxsV/dutoOFxODJ8NITd4vurbhyMu21T43/h0HyamWQE qCdE4RhoFXxy4z06spZHRF2O6KU8EnLuiQLMetP37LiyVQ+P3wd45B1WGHm6iOREbrDSN0pCWvO OENwPwQjM3fbOLA== X-Mailer: b4 0.14.2 Message-ID: <20250918-write-offset-const-v1-1-eb51120d4117@google.com> Subject: [PATCH] rust: io: use const generics for read/write offsets From: Alice Ryhl To: Joel Fernandes Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Miguel Ojeda , Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Benno Lossin , Andreas Hindborg , Trevor Gross , Bjorn Helgaas , "=?utf-8?q?Krzysztof_Wilczy=C5=84ski?=" , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-pci@vger.kernel.org, Alice Ryhl Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Using build_assert! to assert that offsets are in bounds is really fragile and likely to result in spurious and hard-to-debug build failures. Therefore, build_assert! should be avoided for this case. Thus, update the code to perform the check in const evaluation instead. Signed-off-by: Alice Ryhl --- drivers/gpu/drm/tyr/regs.rs | 4 ++-- rust/kernel/devres.rs | 4 ++-- rust/kernel/io.rs | 18 ++++++++++-------- rust/kernel/io/mem.rs | 6 +++--- samples/rust/rust_driver_pci.rs | 10 +++++----- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/tyr/regs.rs b/drivers/gpu/drm/tyr/regs.rs index f46933aaa2214ee0ac58b1ea2a6aa99506a35b70..e3c306e48e86d1d6047cab7944e= 0fe000901d48b 100644 --- a/drivers/gpu/drm/tyr/regs.rs +++ b/drivers/gpu/drm/tyr/regs.rs @@ -25,13 +25,13 @@ impl Register { #[inline] pub(crate) fn read(&self, dev: &Device, iomem: &Devres) = -> Result { - let value =3D (*iomem).access(dev)?.read32(OFFSET); + let value =3D (*iomem).access(dev)?.read32::(); Ok(value) } =20 #[inline] pub(crate) fn write(&self, dev: &Device, iomem: &Devres,= value: u32) -> Result { - (*iomem).access(dev)?.write32(value, OFFSET); + (*iomem).access(dev)?.write32::(value); Ok(()) } } diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs index da18091143a67fcfbb247e7cb4f59f5a4932cac5..3e66e10c05fa078e42162c7a367= 161fbf735a07f 100644 --- a/rust/kernel/devres.rs +++ b/rust/kernel/devres.rs @@ -96,7 +96,7 @@ struct Inner { /// let devres =3D KBox::pin_init(Devres::new(dev, iomem), GFP_KERNEL)?; /// /// let res =3D devres.try_access().ok_or(ENXIO)?; -/// res.write8(0x42, 0x0); +/// res.write8::<0x0>(0x42); /// # Ok(()) /// # } /// ``` @@ -232,7 +232,7 @@ pub fn device(&self) -> &Device { /// /// // might_sleep() /// - /// bar.write32(0x42, 0x0); + /// bar.write32::<0x0>(0x42); /// /// Ok(()) /// } diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs index 03b467722b8651ebecd660ac0e2d849cf88dc915..563ff8488100d9e07a7f4bffeb0= 85db7bd7e9d6a 100644 --- a/rust/kernel/io.rs +++ b/rust/kernel/io.rs @@ -103,7 +103,7 @@ pub fn maxsize(&self) -> usize { ///# fn no_run() -> Result<(), Error> { /// // SAFETY: Invalid usage for example purposes. /// let iomem =3D unsafe { IoMem::<{ core::mem::size_of::() }>::new(0= xBAAAAAAD)? }; -/// iomem.write32(0x42, 0x0); +/// iomem.write32::<0x0>(0x42); /// assert!(iomem.try_write32(0x42, 0x0).is_ok()); /// assert!(iomem.try_write32(0x42, 0x4).is_err()); /// # Ok(()) @@ -120,8 +120,8 @@ macro_rules! define_read { /// time, the build will fail. $(#[$attr])* #[inline] - pub fn $name(&self, offset: usize) -> $type_name { - let addr =3D self.io_addr_assert::<$type_name>(offset); + pub fn $name(&self) -> $type_name { + let addr =3D self.io_addr_assert::<$type_name, OFF>(); =20 // SAFETY: By the type invariant `addr` is a valid address for= MMIO operations. unsafe { bindings::$c_fn(addr as *const c_void) } @@ -149,8 +149,8 @@ macro_rules! define_write { /// time, the build will fail. $(#[$attr])* #[inline] - pub fn $name(&self, value: $type_name, offset: usize) { - let addr =3D self.io_addr_assert::<$type_name>(offset); + pub fn $name(&self, value: $type_name) { + let addr =3D self.io_addr_assert::<$type_name, OFF>(); =20 // SAFETY: By the type invariant `addr` is a valid address for= MMIO operations. unsafe { bindings::$c_fn(value, addr as *mut c_void) } @@ -217,10 +217,12 @@ fn io_addr(&self, offset: usize) -> Result { } =20 #[inline] - fn io_addr_assert(&self, offset: usize) -> usize { - build_assert!(Self::offset_valid::(offset, SIZE)); + fn io_addr_assert(&self) -> usize { + const { + build_assert!(Self::offset_valid::(OFF, SIZE)); + } =20 - self.addr() + offset + self.addr() + OFF } =20 define_read!(read8, try_read8, readb -> u8); diff --git a/rust/kernel/io/mem.rs b/rust/kernel/io/mem.rs index 6f99510bfc3a63dd72c1d47dc661dcd48fa7f54e..b73557f5f57c955ac251a46c9bd= d6df0687411e2 100644 --- a/rust/kernel/io/mem.rs +++ b/rust/kernel/io/mem.rs @@ -54,7 +54,7 @@ pub(crate) unsafe fn new(device: &'a Device, resou= rce: &'a Resource) -> S /// pdev: &platform::Device, /// info: Option<&Self::IdInfo>, /// ) -> Result>> { - /// let offset =3D 0; // Some offset. + /// const OFFSET: usize =3D 0; // Some offset. /// /// // If the size is known at compile time, use [`Self::iomap_s= ized`]. /// // @@ -66,9 +66,9 @@ pub(crate) unsafe fn new(device: &'a Device, resou= rce: &'a Resource) -> S /// let io =3D iomem.access(pdev.as_ref())?; /// /// // Read and write a 32-bit value at `offset`. - /// let data =3D io.read32_relaxed(offset); + /// let data =3D io.read32_relaxed::(); /// - /// io.write32_relaxed(data, offset); + /// io.write32_relaxed::(data); /// /// # Ok(KBox::new(SampleDriver, GFP_KERNEL)?.into()) /// } diff --git a/samples/rust/rust_driver_pci.rs b/samples/rust/rust_driver_pci= .rs index 606946ff4d7fd98e206ee6420a620d1c44eb0377..6f0388853e2b36e0800df5125a5= dd8b20a6d5912 100644 --- a/samples/rust/rust_driver_pci.rs +++ b/samples/rust/rust_driver_pci.rs @@ -46,17 +46,17 @@ struct SampleDriver { impl SampleDriver { fn testdev(index: &TestIndex, bar: &Bar0) -> Result { // Select the test. - bar.write8(index.0, Regs::TEST); + bar.write8::<{ Regs::TEST }>(index.0); =20 - let offset =3D u32::from_le(bar.read32(Regs::OFFSET)) as usize; - let data =3D bar.read8(Regs::DATA); + let offset =3D u32::from_le(bar.read32::<{ Regs::OFFSET }>()) as u= size; + let data =3D bar.read8::<{ Regs::DATA }>(); =20 // Write `data` to `offset` to increase `count` by one. // // Note that we need `try_write8`, since `offset` can't be checked= at compile-time. bar.try_write8(data, offset)?; =20 - Ok(bar.read32(Regs::COUNT)) + Ok(bar.read32::<{ Regs::COUNT }>()) } } =20 @@ -98,7 +98,7 @@ fn probe(pdev: &pci::Device, info: &Self::IdInfo) -= > Result fn unbind(pdev: &pci::Device, this: Pin<&Self>) { if let Ok(bar) =3D this.bar.access(pdev.as_ref()) { // Reset pci-testdev by writing a new test index. - bar.write8(this.index.0, Regs::TEST); + bar.write8::<{ Regs::TEST }>(this.index.0); } } } --- base-commit: cf4fd52e323604ccfa8390917593e1fb965653ee change-id: 20250918-write-offset-const-0b231c4282ea Best regards, --=20 Alice Ryhl