From patchwork Mon Jun 8 13:40:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sasha Levin X-Patchwork-Id: 49627 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f199.google.com (mail-lb0-f199.google.com [209.85.217.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 16559214B2 for ; Mon, 8 Jun 2015 13:45:20 +0000 (UTC) Received: by lbcue7 with SMTP id ue7sf33722293lbc.3 for ; Mon, 08 Jun 2015 06:45:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=vWIksXPFYAwjvFIEymmP2EroWHmO/RkI78nzcdZVM1I=; b=grRjkf88Fxd6qw1dFyvgOUFXzSVerDlZb8v0h1Ux1x0rJzbZS252su1JxozT3Pg6jZ UEgpEz5DCc8xkGWDvCMhgZzeiQjRIFLd3JqB3rQlxUp/6uRQnL7KlHYH4GbVPchXKcGa tgjzdqj5y1x5eSJixmKspIpTpP/aiumP0UaPI3MIyU9Wd5Qy0/9eCC/IWEndlH+Cd5+X MXZ7Hy1SfnuDHicEGkkYKKyiEvu3kcaCHs84mea2dqrpFH5ea5pwrXss43zqAmdqGtoJ DcNhqmRgkZ7OgRMi2Bba4G/B6/WGVHw3mlwt9vzERhoHQFhY7JVPjSODOJu+gbosxLcn y6Zg== X-Gm-Message-State: ALoCoQmYy8Hjvg7zgiyIAFs9B1PtSjY4J1t1OuJo/yWnZ7qdGPepmL/v7M7Bs2xOMmmHzn2LhPrT X-Received: by 10.194.142.205 with SMTP id ry13mr17202130wjb.2.1433771119066; Mon, 08 Jun 2015 06:45:19 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.116.7 with SMTP id js7ls627892lab.34.gmail; Mon, 08 Jun 2015 06:45:18 -0700 (PDT) X-Received: by 10.112.118.49 with SMTP id kj17mr13109082lbb.62.1433771118924; Mon, 08 Jun 2015 06:45:18 -0700 (PDT) Received: from mail-la0-f52.google.com (mail-la0-f52.google.com. [209.85.215.52]) by mx.google.com with ESMTPS id s2si2748476lal.142.2015.06.08.06.45.18 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 08 Jun 2015 06:45:18 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.52 as permitted sender) client-ip=209.85.215.52; Received: by labpy14 with SMTP id py14so97501504lab.0 for ; Mon, 08 Jun 2015 06:45:18 -0700 (PDT) X-Received: by 10.152.27.1 with SMTP id p1mr16526835lag.112.1433771118815; Mon, 08 Jun 2015 06:45:18 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.108.230 with SMTP id hn6csp1876328lbb; Mon, 8 Jun 2015 06:45:17 -0700 (PDT) X-Received: by 10.68.136.42 with SMTP id px10mr29992944pbb.19.1433771086816; Mon, 08 Jun 2015 06:44:46 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ig4si4189681pbb.82.2015.06.08.06.44.46; Mon, 08 Jun 2015 06:44:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753169AbbFHNok (ORCPT + 2 others); Mon, 8 Jun 2015 09:44:40 -0400 Received: from userp1040.oracle.com ([156.151.31.81]:22860 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753292AbbFHNoI (ORCPT ); Mon, 8 Jun 2015 09:44:08 -0400 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t58Di6tp010213 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 8 Jun 2015 13:44:07 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t58Di6nN004972 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Mon, 8 Jun 2015 13:44:06 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t58Di65V004618; Mon, 8 Jun 2015 13:44:06 GMT Received: from lappy.hsd1.nh.comcast.net (/10.159.178.227) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 08 Jun 2015 06:44:06 -0700 From: Sasha Levin To: stable@vger.kernel.org, stable-commits@vger.kernel.org Cc: sasha.levin@oracle.com Subject: [PATCH 3.18 064/178] ktime: Fix ktime_divns to do signed division Date: Mon, 8 Jun 2015 09:40:55 -0400 Message-Id: <1433770969-2003-65-git-send-email-sasha.levin@oracle.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1433770969-2003-1-git-send-email-sasha.levin@oracle.com> References: <1433770969-2003-1-git-send-email-sasha.levin@oracle.com> X-Source-IP: aserv0021.oracle.com [141.146.126.233] Sender: stable-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: stable@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: patch@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.52 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: John Stultz [ Upstream commit f7bcb70ebae0dcdb5a2d859b09e4465784d99029 ] It was noted that the 32bit implementation of ktime_divns() was doing unsigned division and didn't properly handle negative values. And when a ktime helper was changed to utilize ktime_divns, it caused a regression on some IR blasters. See the following bugzilla for details: https://bugzilla.redhat.com/show_bug.cgi?id=1200353 This patch fixes the problem in ktime_divns by checking and preserving the sign bit, and then reapplying it if appropriate after the division, it also changes the return type to a s64 to make it more obvious this is expected. Nicolas also pointed out that negative dividers would cause infinite loops on 32bit systems, negative dividers is unlikely for users of this function, but out of caution this patch adds checks for negative dividers for both 32-bit (BUG_ON) and 64-bit(WARN_ON) versions to make sure no such use cases creep in. [ tglx: Hand an u64 to do_div() to avoid the compiler warning ] Fixes: 166afb64511e 'ktime: Sanitize ktime_to_us/ms conversion' Reported-and-tested-by: Trevor Cordes Signed-off-by: John Stultz Acked-by: Nicolas Pitre Cc: Ingo Molnar Cc: Josh Boyer Cc: One Thousand Gnomes Cc: Link: http://lkml.kernel.org/r/1431118043-23452-1-git-send-email-john.stultz@linaro.org Signed-off-by: Thomas Gleixner Signed-off-by: Sasha Levin --- include/linux/ktime.h | 27 +++++++++++++++++++++------ kernel/time/hrtimer.c | 14 ++++++++------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/include/linux/ktime.h b/include/linux/ktime.h index 411dd8b..039bbe5 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h @@ -166,19 +166,34 @@ static inline bool ktime_before(const ktime_t cmp1, const ktime_t cmp2) } #if BITS_PER_LONG < 64 -extern u64 __ktime_divns(const ktime_t kt, s64 div); -static inline u64 ktime_divns(const ktime_t kt, s64 div) +extern s64 __ktime_divns(const ktime_t kt, s64 div); +static inline s64 ktime_divns(const ktime_t kt, s64 div) { + /* + * Negative divisors could cause an inf loop, + * so bug out here. + */ + BUG_ON(div < 0); if (__builtin_constant_p(div) && !(div >> 32)) { - u64 ns = kt.tv64; - do_div(ns, div); - return ns; + s64 ns = kt.tv64; + u64 tmp = ns < 0 ? -ns : ns; + + do_div(tmp, div); + return ns < 0 ? -tmp : tmp; } else { return __ktime_divns(kt, div); } } #else /* BITS_PER_LONG < 64 */ -# define ktime_divns(kt, div) (u64)((kt).tv64 / (div)) +static inline s64 ktime_divns(const ktime_t kt, s64 div) +{ + /* + * 32-bit implementation cannot handle negative divisors, + * so catch them on 64bit as well. + */ + WARN_ON(div < 0); + return kt.tv64 / div; +} #endif static inline s64 ktime_to_us(const ktime_t kt) diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 5e4d51c..210b848 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -266,21 +266,23 @@ lock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags) /* * Divide a ktime value by a nanosecond value */ -u64 __ktime_divns(const ktime_t kt, s64 div) +s64 __ktime_divns(const ktime_t kt, s64 div) { - u64 dclc; int sft = 0; + s64 dclc; + u64 tmp; dclc = ktime_to_ns(kt); + tmp = dclc < 0 ? -dclc : dclc; + /* Make sure the divisor is less than 2^32: */ while (div >> 32) { sft++; div >>= 1; } - dclc >>= sft; - do_div(dclc, (unsigned long) div); - - return dclc; + tmp >>= sft; + do_div(tmp, (unsigned long) div); + return dclc < 0 ? -tmp : tmp; } EXPORT_SYMBOL_GPL(__ktime_divns); #endif /* BITS_PER_LONG >= 64 */