[PATCH linux dev-4.13] pmbus: core: Use 64-bit ints for returned sensor values

Eddie James eajames at linux.vnet.ibm.com
Sat May 12 06:21:57 AEST 2018



On 05/11/2018 03:16 PM, Eddie James wrote:
> 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

>
> Signed-off-by: Eddie James <eajames at linux.vnet.ibm.com>
> ---
>   drivers/hwmon/pmbus/pmbus_core.c | 33 +++++++++++++++++----------------
>   1 file changed, 17 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
> index d0ffa4b..4957243 100644
> --- a/drivers/hwmon/pmbus/pmbus_core.c
> +++ b/drivers/hwmon/pmbus/pmbus_core.c
> @@ -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,



More information about the openbmc mailing list