From patchwork Tue Mar 31 08:58:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "gregkh@linuxfoundation.org" X-Patchwork-Id: 228584 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D9604C2D0F4 for ; Tue, 31 Mar 2020 09:20:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B08FE208E0 for ; Tue, 31 Mar 2020 09:20:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1585646422; bh=LmSOA6eA7punsys1NXG8+fu3gkgXH5pP+LxHwgF/0sc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=I7IPWS5nsla8PMoyF3JwIbMH8LE5395XjG5joW6xjsTQ/zwrSZrs2lsq2lIsQv94g UdbixW1lMeCdElA0p+F0oA+XDZ+pGR5+8FI0k0hEugHRcmnXntac2zg75k38KqCAF2 xyRs/mNZNEPoQtFdrGKOXeg7Yk2rRKE8i3Iyw0nA= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730473AbgCaJPC (ORCPT ); Tue, 31 Mar 2020 05:15:02 -0400 Received: from mail.kernel.org ([198.145.29.99]:34962 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731872AbgCaJO6 (ORCPT ); Tue, 31 Mar 2020 05:14:58 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id CEB142137B; Tue, 31 Mar 2020 09:14:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1585646097; bh=LmSOA6eA7punsys1NXG8+fu3gkgXH5pP+LxHwgF/0sc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OYg4mFCKi9BQCmy2ebF7sPbrsL665aaA2HfScneK2zwlS8wl9b+x7OK5N9RTO+lJH 8PX2q4EMBNxJFIBdKD7fcaFcqII+EczjfBjcpWI7zWBuS9aKgQh6wSiKLdUcpcrdo5 sbLW0XfBmpw73UGPMPnugXAjjLJs1VqTUNUV85d0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Brian Masney , Hans Verkuil , Bartosz Golaszewski , Linus Walleij Subject: [PATCH 5.4 083/155] gpiolib: Fix irq_disable() semantics Date: Tue, 31 Mar 2020 10:58:43 +0200 Message-Id: <20200331085427.596028836@linuxfoundation.org> X-Mailer: git-send-email 2.26.0 In-Reply-To: <20200331085418.274292403@linuxfoundation.org> References: <20200331085418.274292403@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Linus Walleij commit 8959b304c7062889b1276092cc8590dc1ba98f65 upstream. The implementation if .irq_disable() which kicks in between the gpiolib and the driver is not properly mimicking the expected semantics of the irqchip core: the irqchip will call .irq_disable() if that exists, else it will call mask_irq() which first checks if .irq_mask() is defined before calling it. Since we are calling it unconditionally, we get this bug from drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c, as it only defines .irq_mask_ack and not .irq_mask: Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = (ptrval) (...) PC is at 0x0 LR is at gpiochip_irq_disable+0x20/0x30 Fix this by only calling .irq_mask() if it exists. Cc: Brian Masney Cc: Hans Verkuil Cc: stable@vger.kernel.org Reviewed-by: Bartosz Golaszewski Fixes: 461c1a7d4733 ("gpiolib: override irq_enable/disable") Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20200306132326.1329640-1-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpiolib.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2194,9 +2194,16 @@ static void gpiochip_irq_disable(struct { struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + /* + * Since we override .irq_disable() we need to mimic the + * behaviour of __irq_disable() in irq/chip.c. + * First call .irq_disable() if it exists, else mimic the + * behaviour of mask_irq() which calls .irq_mask() if + * it exists. + */ if (chip->irq.irq_disable) chip->irq.irq_disable(d); - else + else if (chip->irq.chip->irq_mask) chip->irq.chip->irq_mask(d); gpiochip_disable_irq(chip, d->hwirq); }