mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v4 0/3] rust: time: fix Delta arithmetic and add math helpers
@ 2026-10-23 13:04 chenhan
  2026-10-23 13:04 ` [PATCH v4 1/3] rust: time: rename the rem_nanos() divisor chenhan
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: chenhan @ 2026-10-23 13:04 UTC (permalink / raw)
  To: rust-for-linux
  Cc: a.hindborg, boqun, fujita.tomonori, frederic, lyude, tglx,
	anna-maria, jstultz, sboyd, ojeda, gary, bjorn3_gh, lossin,
	aliceryhl, tmgross, dakr, daniel.almeida, tamird, acourbot, work,
	miguel.ojeda.sandonis, tomo, georgeandrout13, linux-kernel

This series fixes the architecture-dependent handling of invalid Delta
division and remainder inputs, then moves the integer operations into a
math module with Delta as its initial user.

V4 addresses Tomonori's follow-up review [1]:
- Add the math64.h link to the module documentation.
- Replace rem_s64() with div_s64_rem(i64, i32) -> (i64, i32), returning
  both quotient and remainder. Document the semantics and the i32 cast.
- Update Delta::rem_nanos() to use the remainder. Keep div64_s64() for
  full-width divisors and retain unconditional invalid-input checks.
- Extend local validation to call both public helpers directly and check
  both tuple elements, including i64::MIN / i32::MIN = (4294967296, 0).

Patches 1 and 2 have unchanged code. Patch 1 carries Tomonori's
Reviewed-by; patch 2 is otherwise unchanged from v3. Patch 3 does not
carry its v3 Reviewed-by because the public interface has changed.
A range-diff against v3 [2] follows below.

Patches 1 and 2 form the stable candidate pair: the parameter rename is
a prerequisite for the behavior fix. Patch 3 is separate and is not
intended for stable. The caller recheck found no additional production
users for the helpers; each still has one caller in Delta. No PWM or
unsigned arithmetic changes are included.

The base remains timekeeping-next at
2ea0119f72dba597aa8a98cbdb72c564bfc5cb38, unchanged on October 23.
On rust-next at 7be4bc52fd9e0e55dc9a2e0232b89427d2c4b614,
patches 1 and 2 apply unchanged. Patch 3 needs only the lib.rs module
registration placed between maple_tree and the newly added mem module;
the remaining changes apply unchanged. That integration was checked
for application only; the runtime tests use the declared base.

Validation on x86-64 and ARMv7 QEMU passed with Rust overflow checks
both enabled and disabled. A standalone built-in test module passes
operands through black_box, calls Delta and the public math helpers,
and compares results with literal expected values. Each configuration
runs 100 valid calls (124 scalar comparisons) and eight separate boots
for zero-divisor and MIN/-1 panics. All 36 boots passed, covering
400 valid calls, 496 scalar comparisons and 32 expected panics. The
test module is local validation scaffolding, outside this series.

Both architectures also passed rustdoc generation, including the C
header link. The fix-only validation from v3 remains applicable because
the base and both prefix trees are identical; it was not rerun for v4
and is not included in the counts above.

[1] https://lore.kernel.org/rust-for-linux/20261021.183700.735437784476089878.tomo@flapping.org/
[2] https://lore.kernel.org/rust-for-linux/20261017111134.22546-1-chenhan0017.work@gmail.com/

chenhan (3):
  rust: time: rename the rem_nanos() divisor
  rust: time: make Delta division and remainder fail consistently
  rust: math: add signed division and remainder helpers

 rust/kernel/lib.rs  |  1 +
 rust/kernel/math.rs | 71 +++++++++++++++++++++++++++++++++++++++++++++
 rust/kernel/time.rs | 47 ++++++++++--------------------
 3 files changed, 88 insertions(+), 31 deletions(-)
 create mode 100644 rust/kernel/math.rs

Range-diff against v3:
1:  67c2d61e47da ! 1:  ed93030078ac rust: time: rename the rem_nanos() divisor
    @@ Commit message
         for documenting and checking the invalid divisors in the next patch.
     
         Cc: stable@vger.kernel.org # prerequisite for the Delta division/remainder fix
    +    Reviewed-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
         Assisted-by: LLM
         Signed-off-by: chenhan <chenhan0017.work@gmail.com>
     
2:  25000522fc46 = 2:  ff344561eebb rust: time: make Delta division and remainder fail consistently
3:  69a07812a676 ! 3:  63d7f5dd76f7 rust: math: add signed division and remainder helpers
    @@ Commit message
         do not depend on time units. Move them into a math module to provide a
         common home for arithmetic helpers, with Delta as the initial user.
     
    -    Expose div64_s64() and rem_s64() so driver crates can use these operations
    -    without constructing time values. The division helper takes two i64
    -    operands; the remainder helper takes an i64 dividend and an i32 divisor
    -    and returns an i64. Both keep Rust's signed operator semantics, including
    -    the unconditional panic checks, and use the existing C helpers on 32-bit.
    +    Expose div64_s64() for an i64 dividend and divisor, and div_s64_rem()
    +    for an i64 dividend and an i32 divisor. The latter returns an i64 quotient
    +    and an i32 remainder, matching the results of the C helper without
    +    exposing its output pointer. Delta's rem_nanos() uses the remainder and
    +    converts it to i64. Both helpers retain Rust's signed operator semantics
    +    and unconditional panic checks, using the existing C helpers on 32-bit.
     
    -    Keep the Delta API and its panic documentation unchanged. This is separate
    -    from the preceding behavior fix so that introducing the math module is
    -    not required for a backport.
    +    Keep the Delta API and its panic conditions unchanged. Document the
    +    quotient and remainder semantics and link to the corresponding C header.
    +    This is separate from the preceding behavior fix so that introducing
    +    the math module is not required for a backport.
     
         Assisted-by: LLM
         Signed-off-by: chenhan <chenhan0017.work@gmail.com>
    @@ rust/kernel/math.rs (new)
     +// SPDX-License-Identifier: GPL-2.0
     +
     +//! Integer arithmetic helpers.
    ++//!
    ++//! C header: [`include/linux/math64.h`](srctree/include/linux/math64.h).
     +
     +/// Divides an [`i64`] dividend by an [`i64`] divisor, rounding towards zero.
     +///
    @@ rust/kernel/math.rs (new)
     +    }
     +}
     +
    -+/// Returns the remainder of an [`i64`] dividend divided by an [`i32`] divisor.
    ++/// Divides an [`i64`] dividend by an [`i32`] divisor, returning `(quotient, remainder)`.
     +///
    -+/// A non-zero remainder has the sign of `dividend`.
    ++/// The quotient is rounded towards zero. A non-zero remainder has the sign of `dividend`.
     +///
     +/// # Panics
     +///
     +/// Panics if `divisor` is zero, or if `dividend` is [`i64::MIN`] and `divisor` is `-1`.
     +#[inline]
    -+pub fn rem_s64(dividend: i64, divisor: i32) -> i64 {
    ++pub fn div_s64_rem(dividend: i64, divisor: i32) -> (i64, i32) {
     +    if divisor == 0 {
    -+        panic!("attempt to calculate the remainder with a divisor of zero");
    ++        panic!("attempt to divide by zero");
     +    }
     +
     +    if dividend == i64::MIN && divisor == -1 {
    -+        panic!("attempt to calculate the remainder with overflow");
    ++        panic!("attempt to divide with overflow");
     +    }
     +
     +    #[cfg(CONFIG_64BIT)]
     +    {
    -+        dividend % i64::from(divisor)
    ++        let divisor = i64::from(divisor);
    ++        let quotient = dividend / divisor;
    ++        let remainder = dividend % divisor;
    ++
    ++        // CAST: |remainder| < |divisor| <= 2^31, so the remainder fits in i32.
    ++        (quotient, remainder as i32)
     +    }
     +
     +    #[cfg(not(CONFIG_64BIT))]
     +    {
    -+        let mut rem = 0;
    ++        let mut remainder = 0;
     +
     +        // SAFETY: The checks above exclude a zero divisor and `i64::MIN / -1`.
    -+        // `&mut rem` provides a valid, aligned, writable pointer for this call.
    -+        unsafe { bindings::div_s64_rem(dividend, divisor, &mut rem) };
    ++        // `&mut remainder` provides a valid, aligned, writable pointer for this call.
    ++        let quotient = unsafe { bindings::div_s64_rem(dividend, divisor, &mut remainder) };
     +
    -+        i64::from(rem)
    ++        (quotient, remainder)
     +    }
     +}
     
    @@ rust/kernel/time.rs: pub fn to_jiffies_timeout(self) -> Delta<Jiffy> {
     -            Self {
     -                value: i64::from(rem),
     -            }
    ++        let (_, remainder) = math::div_s64_rem(self.as_nanos(), divisor);
     +        Self {
    -+            value: math::rem_s64(self.as_nanos(), divisor),
    ++            value: i64::from(remainder),
              }
          }
      }

base-commit: 2ea0119f72dba597aa8a98cbdb72c564bfc5cb38
-- 
2.34.1


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

* [PATCH v4 1/3] rust: time: rename the rem_nanos() divisor
  2026-10-23 13:04 [PATCH v4 0/3] rust: time: fix Delta arithmetic and add math helpers chenhan
@ 2026-10-23 13:04 ` chenhan
  2026-10-23 13:04 ` [PATCH v4 2/3] rust: time: make Delta division and remainder fail consistently chenhan
  2026-10-23 13:04 ` [PATCH v4 3/3] rust: math: add signed division and remainder helpers chenhan
  2 siblings, 0 replies; 4+ messages in thread
From: chenhan @ 2026-10-23 13:04 UTC (permalink / raw)
  To: rust-for-linux
  Cc: a.hindborg, boqun, fujita.tomonori, frederic, lyude, tglx,
	anna-maria, jstultz, sboyd, ojeda, gary, bjorn3_gh, lossin,
	aliceryhl, tmgross, dakr, daniel.almeida, tamird, acourbot, work,
	miguel.ojeda.sandonis, tomo, georgeandrout13, linux-kernel,
	stable

The argument to rem_nanos() is the divisor, while self holds the
dividend. Rename the argument and correct the documentation. Drop the
architecture-specific implementation explanation from the public API
documentation; the argument type already states the divisor's width.

This does not change the function's type or behavior. It is a preparation
for documenting and checking the invalid divisors in the next patch.

Cc: stable@vger.kernel.org # prerequisite for the Delta division/remainder fix
Reviewed-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
Assisted-by: LLM
Signed-off-by: chenhan <chenhan0017.work@gmail.com>
---
Changes since v3:
- Carry FUJITA Tomonori's Reviewed-by; code unchanged.

 rust/kernel/time.rs | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs
index 5ae377e70dd8..16b44e82d2ac 100644
--- a/rust/kernel/time.rs
+++ b/rust/kernel/time.rs
@@ -614,16 +614,13 @@ pub fn to_jiffies_timeout(self) -> Delta<Jiffy> {
         Delta::<Jiffy>::from_jiffies(jiffies)
     }
 
-    /// Return `self % dividend` where `dividend` is in nanoseconds.
-    ///
-    /// The kernel doesn't have any emulation for `s64 % s64` on 32 bit platforms, so this is
-    /// limited to 32 bit dividends.
+    /// Return `self % divisor` where `divisor` is in nanoseconds.
     #[inline]
-    pub fn rem_nanos(self, dividend: i32) -> Self {
+    pub fn rem_nanos(self, divisor: i32) -> Self {
         #[cfg(CONFIG_64BIT)]
         {
             Self {
-                value: self.as_nanos() % i64::from(dividend),
+                value: self.as_nanos() % i64::from(divisor),
             }
         }
 
@@ -632,7 +629,7 @@ pub fn rem_nanos(self, dividend: i32) -> Self {
             let mut rem = 0;
 
             // SAFETY: `rem` is in the stack, so we can always provide a valid pointer to it.
-            unsafe { bindings::div_s64_rem(self.as_nanos(), dividend, &mut rem) };
+            unsafe { bindings::div_s64_rem(self.as_nanos(), divisor, &mut rem) };
 
             Self {
                 value: i64::from(rem),
-- 
2.34.1


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

* [PATCH v4 2/3] rust: time: make Delta division and remainder fail consistently
  2026-10-23 13:04 [PATCH v4 0/3] rust: time: fix Delta arithmetic and add math helpers chenhan
  2026-10-23 13:04 ` [PATCH v4 1/3] rust: time: rename the rem_nanos() divisor chenhan
@ 2026-10-23 13:04 ` chenhan
  2026-10-23 13:04 ` [PATCH v4 3/3] rust: math: add signed division and remainder helpers chenhan
  2 siblings, 0 replies; 4+ messages in thread
From: chenhan @ 2026-10-23 13:04 UTC (permalink / raw)
  To: rust-for-linux
  Cc: a.hindborg, boqun, fujita.tomonori, frederic, lyude, tglx,
	anna-maria, jstultz, sboyd, ojeda, gary, bjorn3_gh, lossin,
	aliceryhl, tmgross, dakr, daniel.almeida, tamird, acourbot, work,
	miguel.ojeda.sandonis, tomo, georgeandrout13, linux-kernel,
	stable

Delta's division and rem_nanos() use Rust operators on 64-bit and C
helpers on 32-bit. The report shows that rem_nanos(0) can return 10 for
a 10 ns dividend on ARMv7, while the same call panics on x86-64. The
i64::MIN / -1 case also differs, and neither API documents these inputs.

Check for zero divisors and i64::MIN with -1 before the architecture-
specific code, and document the panic conditions on each method. This
matches Rust's signed division and remainder operators, including when
overflow checks are disabled. Valid-input results and API signatures
are unchanged; invalid inputs now panic on 32-bit too.

No in-tree calls to either API were found at the base commit. The checks
stay in the existing methods so the fix does not depend on introducing
a math module.

Fixes: 4521438fb076 ("rust: time: Implement basic arithmetic operations for Delta")
Reported-by: Georgios Androutsopoulos <georgeandrout13@gmail.com>
Closes: https://github.com/Rust-for-Linux/linux/issues/1254
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: chenhan <chenhan0017.work@gmail.com>
---
Changes since v3: none.

 rust/kernel/time.rs | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs
index 16b44e82d2ac..4415e91a5227 100644
--- a/rust/kernel/time.rs
+++ b/rust/kernel/time.rs
@@ -412,8 +412,20 @@ fn mul_assign(&mut self, rhs: i64) {
 impl ops::Div for Delta {
     type Output = i64;
 
+    /// # Panics
+    ///
+    /// Panics if `rhs` is zero, or if `self` represents [`i64::MIN`] nanoseconds
+    /// and `rhs` represents `-1` nanosecond.
     #[inline]
     fn div(self, rhs: Self) -> Self::Output {
+        if rhs.value == 0 {
+            panic!("attempt to divide by zero");
+        }
+
+        if self.value == i64::MIN && rhs.value == -1 {
+            panic!("attempt to divide with overflow");
+        }
+
         #[cfg(CONFIG_64BIT)]
         {
             self.value / rhs.value
@@ -421,7 +433,7 @@ fn div(self, rhs: Self) -> Self::Output {
 
         #[cfg(not(CONFIG_64BIT))]
         {
-            // SAFETY: This function is always safe to call regardless of the input values
+            // SAFETY: The checks above exclude a zero divisor and `i64::MIN / -1`.
             unsafe { bindings::div64_s64(self.value, rhs.value) }
         }
     }
@@ -615,8 +627,21 @@ pub fn to_jiffies_timeout(self) -> Delta<Jiffy> {
     }
 
     /// Return `self % divisor` where `divisor` is in nanoseconds.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `divisor` is zero, or if `self` represents [`i64::MIN`]
+    /// nanoseconds and `divisor` is `-1`.
     #[inline]
     pub fn rem_nanos(self, divisor: i32) -> Self {
+        if divisor == 0 {
+            panic!("attempt to calculate the remainder with a divisor of zero");
+        }
+
+        if self.value == i64::MIN && divisor == -1 {
+            panic!("attempt to calculate the remainder with overflow");
+        }
+
         #[cfg(CONFIG_64BIT)]
         {
             Self {
@@ -628,7 +653,8 @@ pub fn rem_nanos(self, divisor: i32) -> Self {
         {
             let mut rem = 0;
 
-            // SAFETY: `rem` is in the stack, so we can always provide a valid pointer to it.
+            // SAFETY: The checks above exclude a zero divisor and `i64::MIN / -1`.
+            // `&mut rem` provides a valid, aligned, writable pointer for this call.
             unsafe { bindings::div_s64_rem(self.as_nanos(), divisor, &mut rem) };
 
             Self {
-- 
2.34.1


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

* [PATCH v4 3/3] rust: math: add signed division and remainder helpers
  2026-10-23 13:04 [PATCH v4 0/3] rust: time: fix Delta arithmetic and add math helpers chenhan
  2026-10-23 13:04 ` [PATCH v4 1/3] rust: time: rename the rem_nanos() divisor chenhan
  2026-10-23 13:04 ` [PATCH v4 2/3] rust: time: make Delta division and remainder fail consistently chenhan
@ 2026-10-23 13:04 ` chenhan
  2 siblings, 0 replies; 4+ messages in thread
From: chenhan @ 2026-10-23 13:04 UTC (permalink / raw)
  To: rust-for-linux
  Cc: a.hindborg, boqun, fujita.tomonori, frederic, lyude, tglx,
	anna-maria, jstultz, sboyd, ojeda, gary, bjorn3_gh, lossin,
	aliceryhl, tmgross, dakr, daniel.almeida, tamird, acourbot, work,
	miguel.ojeda.sandonis, tomo, georgeandrout13, linux-kernel

Delta's division and remainder implementations operate on integers and
do not depend on time units. Move them into a math module to provide a
common home for arithmetic helpers, with Delta as the initial user.

Expose div64_s64() for an i64 dividend and divisor, and div_s64_rem()
for an i64 dividend and an i32 divisor. The latter returns an i64 quotient
and an i32 remainder, matching the results of the C helper without
exposing its output pointer. Delta's rem_nanos() uses the remainder and
converts it to i64. Both helpers retain Rust's signed operator semantics
and unconditional panic checks, using the existing C helpers on 32-bit.

Keep the Delta API and its panic conditions unchanged. Document the
quotient and remainder semantics and link to the corresponding C header.
This is separate from the preceding behavior fix so that introducing
the math module is not required for a backport.

Assisted-by: LLM
Signed-off-by: chenhan <chenhan0017.work@gmail.com>
---
Changes since v3:
- Link the module documentation to include/linux/math64.h.
- Replace rem_s64() with div_s64_rem(), returning (i64, i32).
- Document quotient/remainder semantics and explain the i32 cast.
- Adapt Delta and directly test both public helpers.

FUJITA provided a Reviewed-by for v3. It is not carried here because
this revision changes the public API to return both results; a fresh
review of that change is requested.

 rust/kernel/lib.rs  |  1 +
 rust/kernel/math.rs | 71 +++++++++++++++++++++++++++++++++++++++++++++
 rust/kernel/time.rs | 50 ++++---------------------------
 3 files changed, 78 insertions(+), 44 deletions(-)
 create mode 100644 rust/kernel/math.rs

diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 4d5c96ddc49c..60c2af705b47 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -98,6 +98,7 @@
 pub mod kunit;
 pub mod list;
 pub mod maple_tree;
+pub mod math;
 pub mod miscdevice;
 pub mod mm;
 pub mod module;
diff --git a/rust/kernel/math.rs b/rust/kernel/math.rs
new file mode 100644
index 000000000000..aeb61d5427a7
--- /dev/null
+++ b/rust/kernel/math.rs
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Integer arithmetic helpers.
+//!
+//! C header: [`include/linux/math64.h`](srctree/include/linux/math64.h).
+
+/// Divides an [`i64`] dividend by an [`i64`] divisor, rounding towards zero.
+///
+/// # Panics
+///
+/// Panics if `divisor` is zero, or if `dividend` is [`i64::MIN`] and `divisor` is `-1`.
+#[inline]
+pub fn div64_s64(dividend: i64, divisor: i64) -> i64 {
+    if divisor == 0 {
+        panic!("attempt to divide by zero");
+    }
+
+    if dividend == i64::MIN && divisor == -1 {
+        panic!("attempt to divide with overflow");
+    }
+
+    #[cfg(CONFIG_64BIT)]
+    {
+        dividend / divisor
+    }
+
+    #[cfg(not(CONFIG_64BIT))]
+    {
+        // SAFETY: The checks above exclude a zero divisor and `i64::MIN / -1`.
+        unsafe { bindings::div64_s64(dividend, divisor) }
+    }
+}
+
+/// Divides an [`i64`] dividend by an [`i32`] divisor, returning `(quotient, remainder)`.
+///
+/// The quotient is rounded towards zero. A non-zero remainder has the sign of `dividend`.
+///
+/// # Panics
+///
+/// Panics if `divisor` is zero, or if `dividend` is [`i64::MIN`] and `divisor` is `-1`.
+#[inline]
+pub fn div_s64_rem(dividend: i64, divisor: i32) -> (i64, i32) {
+    if divisor == 0 {
+        panic!("attempt to divide by zero");
+    }
+
+    if dividend == i64::MIN && divisor == -1 {
+        panic!("attempt to divide with overflow");
+    }
+
+    #[cfg(CONFIG_64BIT)]
+    {
+        let divisor = i64::from(divisor);
+        let quotient = dividend / divisor;
+        let remainder = dividend % divisor;
+
+        // CAST: |remainder| < |divisor| <= 2^31, so the remainder fits in i32.
+        (quotient, remainder as i32)
+    }
+
+    #[cfg(not(CONFIG_64BIT))]
+    {
+        let mut remainder = 0;
+
+        // SAFETY: The checks above exclude a zero divisor and `i64::MIN / -1`.
+        // `&mut remainder` provides a valid, aligned, writable pointer for this call.
+        let quotient = unsafe { bindings::div_s64_rem(dividend, divisor, &mut remainder) };
+
+        (quotient, remainder)
+    }
+}
diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs
index 4415e91a5227..f38e2fbd2670 100644
--- a/rust/kernel/time.rs
+++ b/rust/kernel/time.rs
@@ -27,6 +27,8 @@
 use core::marker::PhantomData;
 use core::ops;
 
+use crate::math;
+
 pub mod delay;
 pub mod hrtimer;
 
@@ -418,24 +420,7 @@ impl ops::Div for Delta {
     /// and `rhs` represents `-1` nanosecond.
     #[inline]
     fn div(self, rhs: Self) -> Self::Output {
-        if rhs.value == 0 {
-            panic!("attempt to divide by zero");
-        }
-
-        if self.value == i64::MIN && rhs.value == -1 {
-            panic!("attempt to divide with overflow");
-        }
-
-        #[cfg(CONFIG_64BIT)]
-        {
-            self.value / rhs.value
-        }
-
-        #[cfg(not(CONFIG_64BIT))]
-        {
-            // SAFETY: The checks above exclude a zero divisor and `i64::MIN / -1`.
-            unsafe { bindings::div64_s64(self.value, rhs.value) }
-        }
+        math::div64_s64(self.value, rhs.value)
     }
 }
 
@@ -634,32 +619,9 @@ pub fn to_jiffies_timeout(self) -> Delta<Jiffy> {
     /// nanoseconds and `divisor` is `-1`.
     #[inline]
     pub fn rem_nanos(self, divisor: i32) -> Self {
-        if divisor == 0 {
-            panic!("attempt to calculate the remainder with a divisor of zero");
-        }
-
-        if self.value == i64::MIN && divisor == -1 {
-            panic!("attempt to calculate the remainder with overflow");
-        }
-
-        #[cfg(CONFIG_64BIT)]
-        {
-            Self {
-                value: self.as_nanos() % i64::from(divisor),
-            }
-        }
-
-        #[cfg(not(CONFIG_64BIT))]
-        {
-            let mut rem = 0;
-
-            // SAFETY: The checks above exclude a zero divisor and `i64::MIN / -1`.
-            // `&mut rem` provides a valid, aligned, writable pointer for this call.
-            unsafe { bindings::div_s64_rem(self.as_nanos(), divisor, &mut rem) };
-
-            Self {
-                value: i64::from(rem),
-            }
+        let (_, remainder) = math::div_s64_rem(self.as_nanos(), divisor);
+        Self {
+            value: i64::from(remainder),
         }
     }
 }
-- 
2.34.1


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

end of thread, other threads:[~2026-10-23 13:05 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-23 13:04 [PATCH v4 0/3] rust: time: fix Delta arithmetic and add math helpers chenhan
2026-10-23 13:04 ` [PATCH v4 1/3] rust: time: rename the rem_nanos() divisor chenhan
2026-10-23 13:04 ` [PATCH v4 2/3] rust: time: make Delta division and remainder fail consistently chenhan
2026-10-23 13:04 ` [PATCH v4 3/3] rust: math: add signed division and remainder helpers chenhan

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

all inboxes | Powered by JetHome®