From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linuxfoundation.org ([140.211.169.12]:57608 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1032716AbcIVRrU (ORCPT ); Thu, 22 Sep 2016 13:47:20 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Gregor Boirie , Lars-Peter Clausen , Jonathan Cameron Subject: [PATCH 4.7 080/184] iio:core: fix IIO_VAL_FRACTIONAL sign handling Date: Thu, 22 Sep 2016 19:40:14 +0200 Message-Id: <20160922174052.146353233@linuxfoundation.org> In-Reply-To: <20160922174048.653794923@linuxfoundation.org> References: <20160922174048.653794923@linuxfoundation.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: stable-owner@vger.kernel.org List-ID: 4.7-stable review patch. If anyone has any objections, please let me know. ------------------ From: Gregor Boirie commit 171c0091837c81ed5c949fec6966bb5afff2d1cf upstream. 7985e7c100 ("iio: Introduce a new fractional value type") introduced a new IIO_VAL_FRACTIONAL value type meant to represent rational type numbers expressed by a numerator and denominator combination. Formating of IIO_VAL_FRACTIONAL values relies upon do_div() usage. This fails handling negative values properly since parameters are reevaluated as unsigned values. Fix this by using div_s64_rem() instead. Computed integer part will carry properly signed value. Formatted fractional part will always be positive. Fixes: 7985e7c100 ("iio: Introduce a new fractional value type") Signed-off-by: Gregor Boirie Reviewed-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/industrialio-core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -532,9 +532,8 @@ ssize_t iio_format_value(char *buf, unsi return sprintf(buf, "%d.%09u\n", vals[0], vals[1]); case IIO_VAL_FRACTIONAL: tmp = div_s64((s64)vals[0] * 1000000000LL, vals[1]); - vals[1] = do_div(tmp, 1000000000LL); - vals[0] = tmp; - return sprintf(buf, "%d.%09u\n", vals[0], vals[1]); + vals[0] = (int)div_s64_rem(tmp, 1000000000, &vals[1]); + return sprintf(buf, "%d.%09u\n", vals[0], abs(vals[1])); case IIO_VAL_FRACTIONAL_LOG2: tmp = (s64)vals[0] * 1000000000LL >> vals[1]; vals[1] = do_div(tmp, 1000000000LL);