From patchwork Thu Dec 8 19:29:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 9467029 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 131476071E for ; Thu, 8 Dec 2016 19:29:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F356F285E8 for ; Thu, 8 Dec 2016 19:29:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E7522285FF; Thu, 8 Dec 2016 19:29:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 80431285E8 for ; Thu, 8 Dec 2016 19:29:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752057AbcLHT3c (ORCPT ); Thu, 8 Dec 2016 14:29:32 -0500 Received: from bh-25.webhostbox.net ([208.91.199.152]:52377 "EHLO bh-25.webhostbox.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751302AbcLHT3b (ORCPT ); Thu, 8 Dec 2016 14:29:31 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=roeck-us.net; s=default; h=Message-Id:Date:Subject:Cc:To:From; bh=AcIlFxiCJJrHFxemadfygDhJtmgyQF8E1iDYEgj3YnI=; b=yI+egMR2THJE5LzmWCwveq0Han bH8cs2A3DqvnIRx+JnjKmQbY6Uz6jzDw+GbY2IGPe+8m+KiWgx5/HiwYwb+z3mTzhuL/nXza/vexT gs2zYn4W/xoTnZb28SW20rXtHWYIQ6qVRTOmbePXML+NxwxDu2tmJhzr/km9d99p14JuBjJ5IVWF4 0L2ZJspfOA2mclLTjeMIk03NeSynDKH4KytfZFheOwiwqXB4c94tpr48geo6+46rOFQKxTkJyI8b4 u9lPuWgDLQpih2L7B+m6pXeRmjN4T501NgTBbVX7QmWlflozz2x842hpk2WuQ/DS31/bWryOnBK74 OuLaHYGQ==; Received: from 108-223-40-66.lightspeed.sntcca.sbcglobal.net ([108.223.40.66]:35440 helo=localhost) by bh-25.webhostbox.net with esmtpa (Exim 4.86_1) (envelope-from ) id 1cF4Nl-001SQs-89; Thu, 08 Dec 2016 19:29:29 +0000 From: Guenter Roeck To: Hardware Monitoring Cc: Jean Delvare , Guenter Roeck Subject: [PATCH v2] hwmon: (adm1026) Fix overflows seen when writing into limit attributes Date: Thu, 8 Dec 2016 11:29:29 -0800 Message-Id: <1481225369-13461-1-git-send-email-linux@roeck-us.net> X-Mailer: git-send-email 2.5.0 X-Authenticated_sender: guenter@roeck-us.net X-OutGoing-Spam-Status: No, score=-1.0 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - bh-25.webhostbox.net X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - roeck-us.net X-Get-Message-Sender-Via: bh-25.webhostbox.net: authenticated_id: guenter@roeck-us.net X-Authenticated-Sender: bh-25.webhostbox.net: guenter@roeck-us.net X-Source: X-Source-Args: X-Source-Dir: Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Fix overflows seen when writing large values into voltage limit, temperature limit, temperature offset, and DAC attributes. Overflows are seen due to unbound multiplications and additions. While at it, change the low temperature limit to -128 degrees C, since this is the minimum temperature accepted by the chip. Signed-off-by: Guenter Roeck Reviewed-by: Jean Delvare --- v2: Provide reason for changing lower temperature range. drivers/hwmon/adm1026.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index e67b9a50ac7c..b2a5d9e5c590 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -197,8 +197,9 @@ static int adm1026_scaling[] = { /* .001 Volts */ }; #define NEG12_OFFSET 16000 #define SCALE(val, from, to) (((val)*(to) + ((from)/2))/(from)) -#define INS_TO_REG(n, val) (clamp_val(SCALE(val, adm1026_scaling[n], 192),\ - 0, 255)) +#define INS_TO_REG(n, val) \ + SCALE(clamp_val(val, 0, 255 * adm1026_scaling[n] / 192), \ + adm1026_scaling[n], 192) #define INS_FROM_REG(n, val) (SCALE(val, 192, adm1026_scaling[n])) /* @@ -215,11 +216,11 @@ static int adm1026_scaling[] = { /* .001 Volts */ #define DIV_TO_REG(val) ((val) >= 8 ? 3 : (val) >= 4 ? 2 : (val) >= 2 ? 1 : 0) /* Temperature is reported in 1 degC increments */ -#define TEMP_TO_REG(val) (clamp_val(((val) + ((val) < 0 ? -500 : 500)) \ - / 1000, -127, 127)) +#define TEMP_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), \ + 1000) #define TEMP_FROM_REG(val) ((val) * 1000) -#define OFFSET_TO_REG(val) (clamp_val(((val) + ((val) < 0 ? -500 : 500)) \ - / 1000, -127, 127)) +#define OFFSET_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), \ + 1000) #define OFFSET_FROM_REG(val) ((val) * 1000) #define PWM_TO_REG(val) (clamp_val(val, 0, 255)) @@ -233,7 +234,8 @@ static int adm1026_scaling[] = { /* .001 Volts */ * indicates that the DAC could be used to drive the fans, but in our * example board (Arima HDAMA) it isn't connected to the fans at all. */ -#define DAC_TO_REG(val) (clamp_val(((((val) * 255) + 500) / 2500), 0, 255)) +#define DAC_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val(val, 0, 2500) * 255, \ + 2500) #define DAC_FROM_REG(val) (((val) * 2500) / 255) /* @@ -593,7 +595,10 @@ static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, return err; mutex_lock(&data->update_lock); - data->in_min[16] = INS_TO_REG(16, val + NEG12_OFFSET); + data->in_min[16] = INS_TO_REG(16, + clamp_val(val, INT_MIN, + INT_MAX - NEG12_OFFSET) + + NEG12_OFFSET); adm1026_write_value(client, ADM1026_REG_IN_MIN[16], data->in_min[16]); mutex_unlock(&data->update_lock); return count; @@ -618,7 +623,10 @@ static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr, return err; mutex_lock(&data->update_lock); - data->in_max[16] = INS_TO_REG(16, val+NEG12_OFFSET); + data->in_max[16] = INS_TO_REG(16, + clamp_val(val, INT_MIN, + INT_MAX - NEG12_OFFSET) + + NEG12_OFFSET); adm1026_write_value(client, ADM1026_REG_IN_MAX[16], data->in_max[16]); mutex_unlock(&data->update_lock); return count;