Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4584099pxj; Wed, 12 May 2021 08:41:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwEagJ3dB6GnFS2EpzkHs3H5PjSidLeo+SqKTUy/WJdFEVtaFIMmX/YosUe2783CrJK06y1 X-Received: by 2002:a05:6830:16d8:: with SMTP id l24mr15533919otr.106.1620834062007; Wed, 12 May 2021 08:41:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620834062; cv=none; d=google.com; s=arc-20160816; b=kzBlY1ytHr3L3OVB6s9jDgtVGbwpeygXgJErgFC6F3Fib+gwnyTZfgIWsfUlhZjscZ 6Ax5jsG3QWOYmSD1g8RLau9XroAiTdvHrxP1bDcWwDDFCsnWDguM5qkr6cxRYpPF7qgO aVCQwrysSw4J9FqW98NQn0oEYIXKipUw3zhMBlKNZBSvI9sHJT39FwLTUTeM6kS53fRD lhaERU6Blr393e+cOzpLRh53APfN/DL5B4PzhiBfyVKp9yo2jeUD23dZdS+UZHz98MzM JaURfqcxC8VBpewn/Ks7VVPhvP9rXB5ww+Vrt1x8bEhRFL945ApJApLPxFURcUk+/1er b+Vg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=v4cjtexa1VLhwnUxLjT/1aYhCKNNhRapUKeVrbwdKaI=; b=v/NwmXYX3BFfIyBWZzd7VGyafpAmTqfgxBFSjrgbsYGTt8Jx2rSgdZ55FVKK8tKwb6 zV3OpGpGE0YHYPKvN/w8OPwo0Fjigir9+t9UaKrblg84xDnk6lyUx1Jn/N3kphorc8vJ rVohh/iqmy6yyHqI/eL+L2pNxugWphClssE+N/qlFCiYnFcy7djIrkRSYofUl+R3LCJl Nta99IpUzN4sPRjD5v1NP0PNxIWfn+nePCKDMdRnrKlN1dh3Bqt+4jPlQyT/WUXIzKo3 KjsK3/bTu+g7gAZukW1t/UjYOitsinSI6LmlKDsqgVc5foZUmDGRYNlMpDc667YhcHMW CoDg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=zLCEl5CJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id v23si233749oth.205.2021.05.12.08.40.48; Wed, 12 May 2021 08:41:01 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=zLCEl5CJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234846AbhELPep (ORCPT + 99 others); Wed, 12 May 2021 11:34:45 -0400 Received: from mail.kernel.org ([198.145.29.99]:49672 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234120AbhELPQI (ORCPT ); Wed, 12 May 2021 11:16:08 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 3D2CF61944; Wed, 12 May 2021 15:05:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1620831932; bh=OuD2WSFFv92UEKzjI7sGUIVNydcBLPvo3HbYabBXPcY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=zLCEl5CJMcnGsJwmYcCE10WgAFq2OWP3FTOZPTwqaQpckCbEVVCnb1sow9L+Jmy+g y40Dvz7M9kPPZDxdksb1eBMzciyTm5hsdJFkOXN8+1vU/w4WGr10Vsks/Ko7MraFRd AlBE8KGfqj7poh+fQK1ViyTXL8zPDUEqWlRMs1X4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Hans de Goede Subject: [PATCH 5.10 039/530] misc: lis3lv02d: Fix false-positive WARN on various HP models Date: Wed, 12 May 2021 16:42:29 +0200 Message-Id: <20210512144821.031421444@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210512144819.664462530@linuxfoundation.org> References: <20210512144819.664462530@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Hans de Goede commit 3641762c1c9c7cfd84a7061a0a73054f09b412e3 upstream. Before this commit lis3lv02d_get_pwron_wait() had a WARN_ONCE() to catch a potential divide by 0. WARN macros should only be used to catch internal kernel bugs and that is not the case here. We have been receiving a lot of bug reports about kernel backtraces caused by this WARN. The div value being checked comes from the lis3->odrs[] array. Which is sized to be a power-of-2 matching the number of bits in lis3->odr_mask. The only lis3 model where this array is not entirely filled with non zero values. IOW the only model where we can hit the div == 0 check is the 3dc ("8 bits 3DC sensor") model: int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000}; Note the 0 value at index 0, according to the datasheet an odr index of 0 means "Power-down mode". HP typically uses a lis3 accelerometer for HDD fall protection. What I believe is happening here is that on newer HP devices, which only contain a SDD, the BIOS is leaving the lis3 device powered-down since it is not used for HDD fall protection. Note that the lis3_3dc_rates array initializer only specifies 10 values, which matches the datasheet. So it also contains 6 zero values at the end. Replace the WARN with a normal check, which treats an odr index of 0 as power-down and uses a normal dev_err() to report the error in case odr index point past the initialized part of the array. Fixes: 1510dd5954be ("lis3lv02d: avoid divide by zero due to unchecked") Cc: stable@vger.kernel.org Signed-off-by: Hans de Goede BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=785814 BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1817027 BugLink: https://bugs.centos.org/view.php?id=10720 Link: https://lore.kernel.org/r/20210217102501.31758-1-hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/misc/lis3lv02d/lis3lv02d.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) --- a/drivers/misc/lis3lv02d/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c @@ -208,7 +208,7 @@ static int lis3_3dc_rates[16] = {0, 1, 1 static int lis3_3dlh_rates[4] = {50, 100, 400, 1000}; /* ODR is Output Data Rate */ -static int lis3lv02d_get_odr(struct lis3lv02d *lis3) +static int lis3lv02d_get_odr_index(struct lis3lv02d *lis3) { u8 ctrl; int shift; @@ -216,15 +216,23 @@ static int lis3lv02d_get_odr(struct lis3 lis3->read(lis3, CTRL_REG1, &ctrl); ctrl &= lis3->odr_mask; shift = ffs(lis3->odr_mask) - 1; - return lis3->odrs[(ctrl >> shift)]; + return (ctrl >> shift); } static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3) { - int div = lis3lv02d_get_odr(lis3); + int odr_idx = lis3lv02d_get_odr_index(lis3); + int div = lis3->odrs[odr_idx]; - if (WARN_ONCE(div == 0, "device returned spurious data")) + if (div == 0) { + if (odr_idx == 0) { + /* Power-down mode, not sampling no need to sleep */ + return 0; + } + + dev_err(&lis3->pdev->dev, "Error unknown odrs-index: %d\n", odr_idx); return -ENXIO; + } /* LIS3 power on delay is quite long */ msleep(lis3->pwron_delay / div); @@ -816,9 +824,12 @@ static ssize_t lis3lv02d_rate_show(struc struct device_attribute *attr, char *buf) { struct lis3lv02d *lis3 = dev_get_drvdata(dev); + int odr_idx; lis3lv02d_sysfs_poweron(lis3); - return sprintf(buf, "%d\n", lis3lv02d_get_odr(lis3)); + + odr_idx = lis3lv02d_get_odr_index(lis3); + return sprintf(buf, "%d\n", lis3->odrs[odr_idx]); } static ssize_t lis3lv02d_rate_set(struct device *dev,