]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
hwmon: (ltc2992) Fix u32 overflow in power read path
authorSanman Pradhan <psanman@juniper.net>
Thu, 16 Apr 2026 21:59:40 +0000 (21:59 +0000)
committerGuenter Roeck <linux@roeck-us.net>
Thu, 30 Apr 2026 17:23:59 +0000 (10:23 -0700)
ltc2992_get_power() computes the divisor for mul_u64_u32_div() as
r_sense_uohm * 1000. This multiplication overflows u32 when
r_sense_uohm exceeds about 4.29 ohms (4294967 micro-ohms), producing
a truncated divisor and an incorrect power reading.

Cancel the factor of 1000 from both the numerator
(VADC_UV_LSB * IADC_NANOV_LSB = 312500000) and the divisor
(r_sense_uohm * 1000), giving (VADC_UV_LSB / 1000) * IADC_NANOV_LSB
= 312500 as the numerator and plain r_sense_uohm as the divisor.
The cancellation is exact because LTC2992_VADC_UV_LSB (25000) is
divisible by 1000.

This is the read-path counterpart of the write-path fix applied in
the preceding patch.

Fixes: b0bd407e94b03 ("hwmon: (ltc2992) Add support")
Cc: stable@vger.kernel.org
Signed-off-by: Sanman Pradhan <psanman@juniper.net>
Link: https://lore.kernel.org/r/20260416215904.101969-3-sanman.pradhan@hpe.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/ltc2992.c

index 1069736196763de52929e882701e6dcb82b860c5..2617c4538af91dde8544afc08006b8962930545e 100644 (file)
@@ -637,8 +637,10 @@ static int ltc2992_get_power(struct ltc2992_state *st, u32 reg, u32 channel, lon
        if (reg_val < 0)
                return reg_val;
 
-       *val = mul_u64_u32_div(reg_val, LTC2992_VADC_UV_LSB * LTC2992_IADC_NANOV_LSB,
-                              st->r_sense_uohm[channel] * 1000);
+       *val = mul_u64_u32_div(reg_val,
+                              LTC2992_VADC_UV_LSB / 1000 *
+                              LTC2992_IADC_NANOV_LSB,
+                              st->r_sense_uohm[channel]);
 
        return 0;
 }