public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] rust_binder: replace is_aligned helper with is_multiple_of
@ 2026-03-02 19:35 KaiserGranatapfel via B4 Relay
  2026-03-02 20:02 ` Gary Guo
  2026-03-02 22:27 ` Greg Kroah-Hartman
  0 siblings, 2 replies; 3+ messages in thread
From: KaiserGranatapfel via B4 Relay @ 2026-03-02 19:35 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
	Christian Brauner, Carlos Llamas, Alice Ryhl, Miguel Ojeda,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Trevor Gross, Danilo Krummrich
  Cc: linux-kernel, rust-for-linux,
	Christopher Erleigh (KaiserGranatapfel)

From: KaiserGranatapfel <christopher.erleigh@gmail.com>

Remove the local `is_aligned` helper from the binder thread module and
replace all call sites with `usize::is_multiple_of`, which is the
idiomatic Rust API for checking divisibility.

Since `is_multiple_of` was only stabilized in Rust 1.87.0 and the
kernel MSRV is currently 1.78.0, introduce a `UsizeExt` extension
trait in `rust/kernel/usize_ext.rs` as a polyfill. The trait is
conditionally compiled behind `CONFIG_RUSTC_HAS_USIZE_IS_MULTIPLE_OF`
(set when rustc >= 1.87.0) and re-exported via the kernel prelude,
following the same pattern used for `AsFlattened` / `slice_flatten`.

The `offset % type_size == 0` expression in `rust/kernel/io.rs` is
intentionally left unchanged as it lives inside a `const fn` where
trait method calls are not permitted.

Link: https://github.com/Rust-for-Linux/linux/issues/1220
Signed-off-by: Christopher Erleigh (KaiserGranatapfel) <christopher.erleigh@gmail.com>
---
The recently landed patch "rust_binder: add additional alignment checks"
introduced a local `is_aligned` helper as a workaround for
`usize::is_multiple_of` not being available prior to Rust 1.87.0.

This patch replaces that helper with a `UsizeExt` extension trait that
provides `is_multiple_of` as a polyfill, following the same pattern used
for `AsFlattened` / `slice_flatten`. The trait is gated behind
`CONFIG_RUSTC_HAS_USIZE_IS_MULTIPLE_OF` and will become a no-op once
the kernel MSRV reaches 1.87.0.

Note: the From: header uses my GitHub username "KaiserGranatapfel", as
this is tied to my Git and GitHub identity. My real name is Christopher
Erleigh, as reflected in the Signed-off-by trailer.
---
 drivers/android/binder/thread.rs | 14 +++++---------
 init/Kconfig                     |  3 +++
 rust/kernel/lib.rs               |  1 +
 rust/kernel/prelude.rs           |  3 +++
 rust/kernel/usize_ext.rs         | 30 ++++++++++++++++++++++++++++++
 5 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs
index 0b62d24b2..25d499d05 100644
--- a/drivers/android/binder/thread.rs
+++ b/drivers/android/binder/thread.rs
@@ -36,10 +36,6 @@
 
 use core::mem::size_of;
 
-fn is_aligned(value: usize, to: usize) -> bool {
-    value % to == 0
-}
-
 /// Stores the layout of the scatter-gather entries. This is used during the `translate_objects`
 /// call and is discarded when it returns.
 struct ScatterGatherState {
@@ -796,7 +792,7 @@ fn translate_object(
                 let num_fds = usize::try_from(obj.num_fds).map_err(|_| EINVAL)?;
                 let fds_len = num_fds.checked_mul(size_of::<u32>()).ok_or(EINVAL)?;
 
-                if !is_aligned(parent_offset, size_of::<u32>()) {
+                if !parent_offset.is_multiple_of(size_of::<u32>()) {
                     return Err(EINVAL.into());
                 }
 
@@ -814,7 +810,7 @@ fn translate_object(
                     }
                 };
 
-                if !is_aligned(parent_entry.sender_uaddr, size_of::<u32>()) {
+                if !parent_entry.sender_uaddr.is_multiple_of(size_of::<u32>()) {
                     return Err(EINVAL.into());
                 }
 
@@ -975,10 +971,10 @@ pub(crate) fn copy_transaction_data(
             None => 0,
         };
 
-        if !is_aligned(offsets_size, size_of::<u64>()) {
+        if !offsets_size.is_multiple_of(size_of::<u64>()) {
             return Err(EINVAL.into());
         }
-        if !is_aligned(buffers_size, size_of::<u64>()) {
+        if !buffers_size.is_multiple_of(size_of::<u64>()) {
             return Err(EINVAL.into());
         }
 
@@ -1047,7 +1043,7 @@ pub(crate) fn copy_transaction_data(
                     .try_into()
                     .map_err(|_| EINVAL)?;
 
-                if offset < end_of_previous_object || !is_aligned(offset, size_of::<u32>()) {
+                if offset < end_of_previous_object || !offset.is_multiple_of(size_of::<u32>()) {
                     pr_warn!("Got transaction with invalid offset.");
                     return Err(EINVAL.into());
                 }
diff --git a/init/Kconfig b/init/Kconfig
index b55deae92..bd7493480 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -166,6 +166,9 @@ config LD_CAN_USE_KEEP_IN_OVERLAY
 config RUSTC_HAS_SLICE_AS_FLATTENED
 	def_bool RUSTC_VERSION >= 108000
 
+config RUSTC_HAS_USIZE_IS_MULTIPLE_OF
+	def_bool RUSTC_VERSION >= 108700
+
 config RUSTC_HAS_COERCE_POINTEE
 	def_bool RUSTC_VERSION >= 108400
 
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 3da92f18f..59216912a 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -157,6 +157,7 @@
 pub mod uaccess;
 #[cfg(CONFIG_USB = "y")]
 pub mod usb;
+pub mod usize_ext;
 pub mod workqueue;
 pub mod xarray;
 
diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs
index 2877e3f7b..7e778a666 100644
--- a/rust/kernel/prelude.rs
+++ b/rust/kernel/prelude.rs
@@ -53,3 +53,6 @@
 
 #[cfg(not(CONFIG_RUSTC_HAS_SLICE_AS_FLATTENED))]
 pub use super::slice::AsFlattened;
+
+#[cfg(not(CONFIG_RUSTC_HAS_USIZE_IS_MULTIPLE_OF))]
+pub use super::usize_ext::UsizeExt as _;
diff --git a/rust/kernel/usize_ext.rs b/rust/kernel/usize_ext.rs
new file mode 100644
index 000000000..690265bc0
--- /dev/null
+++ b/rust/kernel/usize_ext.rs
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Additional (and temporary) `usize` helpers.
+
+/// Extension trait providing a portable version of [`usize::is_multiple_of`].
+///
+/// `usize::is_multiple_of` was stabilized in Rust 1.87.0. This extension trait
+/// provides the same functionality for kernels built with older toolchains.
+///
+/// This trait can be removed once the MSRV passes 1.87.
+///
+/// [`usize::is_multiple_of`]: https://doc.rust-lang.org/std/primitive.usize.html#method.is_multiple_of
+#[cfg(not(CONFIG_RUSTC_HAS_USIZE_IS_MULTIPLE_OF))]
+pub trait UsizeExt {
+    /// Returns `true` if `self` is a multiple of `rhs`.
+    ///
+    /// This is a portable layer on top of [`usize::is_multiple_of`]; see its documentation for
+    /// details.
+    ///
+    /// [`usize::is_multiple_of`]: https://doc.rust-lang.org/std/primitive.usize.html#method.is_multiple_of
+    fn is_multiple_of(self, rhs: usize) -> bool;
+}
+
+#[cfg(not(CONFIG_RUSTC_HAS_USIZE_IS_MULTIPLE_OF))]
+impl UsizeExt for usize {
+    #[inline]
+    fn is_multiple_of(self, rhs: usize) -> bool {
+        self % rhs == 0
+    }
+}

---
base-commit: 11439c4635edd669ae435eec308f4ab8a0804808
change-id: 20260302-rust-binder-is-multiple-of-2d757cf0a70f

Best regards,
-- 
KaiserGranatapfel <christopher.erleigh@gmail.com>



^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-03-02 22:27 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-02 19:35 [PATCH] rust_binder: replace is_aligned helper with is_multiple_of KaiserGranatapfel via B4 Relay
2026-03-02 20:02 ` Gary Guo
2026-03-02 22:27 ` Greg Kroah-Hartman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox