| From 8abec6ec5db2418ccfb5f8961da4d6ef19d7c6cd Mon Sep 17 00:00:00 2001 |
| From: Guenter Roeck <linux@roeck-us.net> |
| Date: Sun, 11 Dec 2016 13:27:42 -0800 |
| Subject: [PATCH] hwmon: (g762) Fix overflows and crash seen when writing limit |
| attributes |
| |
| commit 4fccd4a1e8944033bcd7693ea4e8fb478cd2059a upstream. |
| |
| Fix overflows seen when writing into fan speed limit attributes. |
| Also fix crash due to division by zero, seen when certain very |
| large values (such as 2147483648, or 0x80000000) are written |
| into fan speed limit attributes. |
| |
| Fixes: 594fbe713bf60 ("Add support for GMT G762/G763 PWM fan controllers") |
| Cc: Arnaud Ebalard <arno@natisbad.org> |
| Reviewed-by: Jean Delvare <jdelvare@suse.de> |
| Signed-off-by: Guenter Roeck <linux@roeck-us.net> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/hwmon/g762.c b/drivers/hwmon/g762.c |
| index b96a2a9e4df7..628be9c95ff9 100644 |
| --- a/drivers/hwmon/g762.c |
| +++ b/drivers/hwmon/g762.c |
| @@ -193,14 +193,17 @@ static inline unsigned int rpm_from_cnt(u8 cnt, u32 clk_freq, u16 p, |
| * Convert fan RPM value from sysfs into count value for fan controller |
| * register (FAN_SET_CNT). |
| */ |
| -static inline unsigned char cnt_from_rpm(u32 rpm, u32 clk_freq, u16 p, |
| +static inline unsigned char cnt_from_rpm(unsigned long rpm, u32 clk_freq, u16 p, |
| u8 clk_div, u8 gear_mult) |
| { |
| - if (!rpm) /* to stop the fan, set cnt to 255 */ |
| + unsigned long f1 = clk_freq * 30 * gear_mult; |
| + unsigned long f2 = p * clk_div; |
| + |
| + if (!rpm) /* to stop the fan, set cnt to 255 */ |
| return 0xff; |
| |
| - return clamp_val(((clk_freq * 30 * gear_mult) / (rpm * p * clk_div)), |
| - 0, 255); |
| + rpm = clamp_val(rpm, f1 / (255 * f2), ULONG_MAX / f2); |
| + return DIV_ROUND_CLOSEST(f1, rpm * f2); |
| } |
| |
| /* helper to grab and cache data, at most one time per second */ |
| -- |
| 2.10.1 |
| |