pmbus: core: Use 64-bit ints for returned sensor values
PATCH 1/1 pmbus: core: Use 64-bit ints for returned sensor values
It's possible to overflow sensor values, especially for power sensors reporting micro Watts. Use 64-bit values to prevent overflow.
Signed-off-by Eddie James <[email protected]>
--- drivers/hwmon/pmbus/pmbus_core.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-)
drivers/hwmon/pmbus/pmbus_core.c +17 -16
@@ -629,12 +629,12 @@ static struct pmbus_data *pmbus_update_device(struct device *dev)* Convert linear sensor values to milli- or micro-units * depending on sensor type. */ -static long pmbus_reg2data_linear (struct pmbus_data *data, -struct pmbus_sensor *sensor) +static s64 pmbus_reg2data_linear (struct pmbus_data *data, +struct pmbus_sensor *sensor) {s16 exponent;s32 mantissa; -long val; +s64 val;if (sensor->class ==PSC_VOLTAGE_OUT ) {/* LINEAR16 */ exponent = data->exponent[sensor->page];
@@ -648,11 +648,11 @@ static long pmbus_reg2data_linear(struct pmbus_data *data,/* scale result to milli-units for all sensors except fans */ if (sensor->class !=PSC_FAN ) - val = val *1000L ; + val = val *1000LL ;/* scale result to micro-units for power sensors */ if (sensor->class ==PSC_POWER ) - val = val *1000L ; + val = val *1000LL ;if (exponent >=0 ) val <<= exponent;
@@ -666,10 +666,10 @@ static long pmbus_reg2data_linear(struct pmbus_data *data,* Convert direct sensor values to milli- or micro-units * depending on sensor type. */ -static long pmbus_reg2data_direct (struct pmbus_data *data, -struct pmbus_sensor *sensor) +static s64 pmbus_reg2data_direct (struct pmbus_data *data, +struct pmbus_sensor *sensor) { -long val = (s16 ) sensor->data; +s64 val = sensor->data;long m, b,R ; m = data->info->m[sensor->class];
@@ -694,23 +694,24 @@ static long pmbus_reg2data_direct(struct pmbus_data *data, }while (R >0 ) { - val *=10 ; + val *=10LL ;R --; }while (R <0 ) { - val =DIV_ROUND_CLOSEST (val,10 ); + val =DIV_ROUND_CLOSEST_ULL (val,10 );R ++; } -return (val - b) / m; + val -= b; +return do_div (val, m); }/* * Convert VID sensor values to milli- or micro-units * depending on sensor type. */ -static long pmbus_reg2data_vid (struct pmbus_data *data, -struct pmbus_sensor *sensor) +static s64 pmbus_reg2data_vid (struct pmbus_data *data, +struct pmbus_sensor *sensor) {long val = sensor->data;long rv =0 ;
@@ -728,9 +729,9 @@ static long pmbus_reg2data_vid(struct pmbus_data *data,return rv; } -static long pmbus_reg2data (struct pmbus_data *data,struct pmbus_sensor *sensor) +static s64 pmbus_reg2data (struct pmbus_data *data,struct pmbus_sensor *sensor) { -long val; +s64 val;if (!sensor->convert)return sensor->data;
@@ -968,7 +969,7 @@ static ssize_t pmbus_show_sensor(struct device *dev,if (sensor->data <0 )return sensor->data; -return snprintf (buf,PAGE_SIZE ,"%ld\n" ,pmbus_reg2data (data, sensor)); +return snprintf (buf,PAGE_SIZE ,"%lld\n" ,pmbus_reg2data (data, sensor)); } static ssize_t pmbus_set_sensor(struct device *dev,
Signature · 1 line
1.8.3.1
Quoted 2 lines · Eddie James
It's possible to overflow sensor values, especially for power sensors reporting micro Watts. Use 64-bit values to prevent overflow.
Cancel that. This has been fixed in linux-next with bd467e4eababe4c04272c1e646f066db02734c79
I'll port it to dev-4.13
Thanks,
Eddie
Quoted 105 lines
Signed-off-by Eddie James <[email protected]>--- drivers/hwmon/pmbus/pmbus_core.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-)drivers/hwmon/pmbus/pmbus_core.c +17
-16@@ -629,12 +629,12 @@ static struct pmbus_data *pmbus_update_device(struct device *dev)* Convert linear sensor values to milli- or micro-units * depending on sensor type. */ -static long pmbus_reg2data_linear (struct pmbus_data *data, -struct pmbus_sensor *sensor) +static s64 pmbus_reg2data_linear (struct pmbus_data *data, +struct pmbus_sensor *sensor) {s16 exponent;s32 mantissa; -long val; +s64 val;if (sensor->class ==PSC_VOLTAGE_OUT ) {/* LINEAR16 */ exponent = data->exponent[sensor->page];@@ -648,11 +648,11 @@ static long pmbus_reg2data_linear(struct pmbus_data *data,/* scale result to milli-units for all sensors except fans */ if (sensor->class !=PSC_FAN ) - val = val *1000L ; + val = val *1000LL ;/* scale result to micro-units for power sensors */ if (sensor->class ==PSC_POWER ) - val = val *1000L ; + val = val *1000LL ;if (exponent >=0 ) val <<= exponent;@@ -666,10 +666,10 @@ static long pmbus_reg2data_linear(struct pmbus_data *data,* Convert direct sensor values to milli- or micro-units * depending on sensor type. */ -static long pmbus_reg2data_direct (struct pmbus_data *data, -struct pmbus_sensor *sensor) +static s64 pmbus_reg2data_direct (struct pmbus_data *data, +struct pmbus_sensor *sensor) { -long val = (s16 ) sensor->data; +s64 val = sensor->data;long m, b,R ; m = data->info->m[sensor->class];@@ -694,23 +694,24 @@ static long pmbus_reg2data_direct(struct pmbus_data *data, }while (R >0 ) { - val *=10 ; + val *=10LL ;R --; }while (R <0 ) { - val =DIV_ROUND_CLOSEST (val,10 ); + val =DIV_ROUND_CLOSEST_ULL (val,10 );R ++; } -return (val - b) / m; + val -= b; +return do_div (val, m); }/* * Convert VID sensor values to milli- or micro-units * depending on sensor type. */ -static long pmbus_reg2data_vid (struct pmbus_data *data, -struct pmbus_sensor *sensor) +static s64 pmbus_reg2data_vid (struct pmbus_data *data, +struct pmbus_sensor *sensor) {long val = sensor->data;long rv =0 ;@@ -728,9 +729,9 @@ static long pmbus_reg2data_vid(struct pmbus_data *data,return rv; } -static long pmbus_reg2data (struct pmbus_data *data,struct pmbus_sensor *sensor) +static s64 pmbus_reg2data (struct pmbus_data *data,struct pmbus_sensor *sensor) { -long val; +s64 val;if (!sensor->convert)return sensor->data;@@ -968,7 +969,7 @@ static ssize_t pmbus_show_sensor(struct device *dev,if (sensor->data <0 )return sensor->data; -return snprintf (buf,PAGE_SIZE ,"%ld\n" ,pmbus_reg2data (data, sensor)); +return snprintf (buf,PAGE_SIZE ,"%lld\n" ,pmbus_reg2data (data, sensor)); } static ssize_t pmbus_set_sensor(struct device *dev,
Quoted 10 lines · Eddie James
Quoted 3 lines · Eddie James
It's possible to overflow sensor values, especially for power sensors reporting micro Watts. Use 64-bit values to prevent overflow.
Cancel that. This has been fixed in linux-next with
bd467e4eababe4c04272c1e646f066db02734c79
I have cherry picked this into dev-4.13.
Cheers,
Joel