164 lines
6.4 KiB
Diff
164 lines
6.4 KiB
Diff
|
Path: news.gmane.org!not-for-mail
|
||
|
From: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||
|
Newsgroups: gmane.linux.kernel.gpio,gmane.linux.kernel
|
||
|
Subject: [PATCH] gpio / ACPI: Don't crash on NULL chip->dev
|
||
|
Date: Mon, 31 Mar 2014 15:16:49 +0300
|
||
|
Lines: 114
|
||
|
Approved: news@gmane.org
|
||
|
Message-ID: <1396268209-19108-1-git-send-email-mika.westerberg@linux.intel.com>
|
||
|
NNTP-Posting-Host: plane.gmane.org
|
||
|
X-Trace: ger.gmane.org 1396268225 9280 80.91.229.3 (31 Mar 2014 12:17:05 GMT)
|
||
|
X-Complaints-To: usenet@ger.gmane.org
|
||
|
NNTP-Posting-Date: Mon, 31 Mar 2014 12:17:05 +0000 (UTC)
|
||
|
Cc: Alexandre Courbot <gnurou@gmail.com>,
|
||
|
Sabrina Dubroca <sd@queasysnail.net>,
|
||
|
linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
|
||
|
Mika Westerberg <mika.westerberg@linux.intel.com>
|
||
|
To: Linus Walleij <linus.walleij@linaro.org>
|
||
|
Original-X-From: linux-gpio-owner@vger.kernel.org Mon Mar 31 14:16:58 2014
|
||
|
Return-path: <linux-gpio-owner@vger.kernel.org>
|
||
|
Envelope-to: glg-linux-gpio@plane.gmane.org
|
||
|
Original-Received: from vger.kernel.org ([209.132.180.67])
|
||
|
by plane.gmane.org with esmtp (Exim 4.69)
|
||
|
(envelope-from <linux-gpio-owner@vger.kernel.org>)
|
||
|
id 1WUb96-00049j-5K
|
||
|
for glg-linux-gpio@plane.gmane.org; Mon, 31 Mar 2014 14:16:56 +0200
|
||
|
Original-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
|
||
|
id S1752154AbaCaMQz (ORCPT <rfc822;glg-linux-gpio@m.gmane.org>);
|
||
|
Mon, 31 Mar 2014 08:16:55 -0400
|
||
|
Original-Received: from mga11.intel.com ([192.55.52.93]:46420 "EHLO mga11.intel.com"
|
||
|
rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP
|
||
|
id S1751749AbaCaMQy (ORCPT <rfc822;linux-gpio@vger.kernel.org>);
|
||
|
Mon, 31 Mar 2014 08:16:54 -0400
|
||
|
Original-Received: from fmsmga002.fm.intel.com ([10.253.24.26])
|
||
|
by fmsmga102.fm.intel.com with ESMTP; 31 Mar 2014 05:16:54 -0700
|
||
|
X-ExtLoop1: 1
|
||
|
X-IronPort-AV: E=Sophos;i="4.97,764,1389772800";
|
||
|
d="scan'208";a="510938110"
|
||
|
Original-Received: from blue.fi.intel.com ([10.237.72.156])
|
||
|
by fmsmga002.fm.intel.com with ESMTP; 31 Mar 2014 05:16:50 -0700
|
||
|
Original-Received: by blue.fi.intel.com (Postfix, from userid 1004)
|
||
|
id 73976E0098; Mon, 31 Mar 2014 15:16:49 +0300 (EEST)
|
||
|
X-Mailer: git-send-email 1.9.1
|
||
|
Original-Sender: linux-gpio-owner@vger.kernel.org
|
||
|
Precedence: bulk
|
||
|
List-ID: <linux-gpio.vger.kernel.org>
|
||
|
X-Mailing-List: linux-gpio@vger.kernel.org
|
||
|
Xref: news.gmane.org gmane.linux.kernel.gpio:2461 gmane.linux.kernel:1675129
|
||
|
Archived-At: <http://permalink.gmane.org/gmane.linux.kernel.gpio/2461>
|
||
|
|
||
|
Commit aa92b6f689ac (gpio / ACPI: Allocate ACPI specific data directly in
|
||
|
acpi_gpiochip_add()) moved ACPI handle checking to acpi_gpiochip_add() but
|
||
|
forgot to check whether chip->dev is NULL before dereferencing it.
|
||
|
|
||
|
Since chip->dev pointer is optional we can end up with crash like following:
|
||
|
|
||
|
BUG: unable to handle kernel NULL pointer dereference at 00000138
|
||
|
IP: [<c126c2b3>] acpi_gpiochip_add+0x13/0x190
|
||
|
*pde = 00000000
|
||
|
Oops: 0000 [#1] PREEMPT SMP
|
||
|
Modules linked in: ssb(+) ...
|
||
|
CPU: 0 PID: 512 Comm: modprobe Tainted: G W 3.14.0-rc7-next-20140324-t1 #24
|
||
|
Hardware name: Dell Inc. Latitude D830 /0UY141, BIOS A02 06/07/2007
|
||
|
task: f5799900 ti: f543e000 task.ti: f543e000
|
||
|
EIP: 0060:[<c126c2b3>] EFLAGS: 00010282 CPU: 0
|
||
|
EIP is at acpi_gpiochip_add+0x13/0x190
|
||
|
EAX: 00000000 EBX: f57824c4 ECX: 00000000 EDX: 00000000
|
||
|
ESI: f57824c4 EDI: 00000010 EBP: f543fc54 ESP: f543fc40
|
||
|
DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
|
||
|
CR0: 8005003b CR2: 00000138 CR3: 355f8000 CR4: 000007d0
|
||
|
Stack:
|
||
|
f543fc5c fd1f7790 f57824c4 000000be 00000010 f543fc84 c1269f4e f543fc74
|
||
|
fd1f78bd 00008002 f57822b0 f5782090 fd1f8400 00000286 fd1f9994 00000000
|
||
|
f5782000 f543fc8c fd1f7e39 f543fcc8 fd1f0bd8 000000c0 00000000 00000000
|
||
|
Call Trace:
|
||
|
[<fd1f7790>] ? ssb_pcie_mdio_write+0xa0/0xd0 [ssb]
|
||
|
[<c1269f4e>] gpiochip_add+0xee/0x300
|
||
|
[<fd1f78bd>] ? ssb_pcicore_serdes_workaround+0xfd/0x140 [ssb]
|
||
|
[<fd1f7e39>] ssb_gpio_init+0x89/0xa0 [ssb]
|
||
|
[<fd1f0bd8>] ssb_attach_queued_buses+0xc8/0x2d0 [ssb]
|
||
|
[<fd1f0f65>] ssb_bus_register+0x185/0x1f0 [ssb]
|
||
|
[<fd1f3120>] ? ssb_pci_xtal+0x220/0x220 [ssb]
|
||
|
[<fd1f106c>] ssb_bus_pcibus_register+0x2c/0x80 [ssb]
|
||
|
[<fd1f40dc>] ssb_pcihost_probe+0x9c/0x110 [ssb]
|
||
|
[<c1276c8f>] pci_device_probe+0x6f/0xc0
|
||
|
[<c11bdb55>] ? sysfs_create_link+0x25/0x40
|
||
|
[<c131d8b9>] driver_probe_device+0x79/0x360
|
||
|
[<c1276512>] ? pci_match_device+0xb2/0xc0
|
||
|
[<c131dc51>] __driver_attach+0x71/0x80
|
||
|
[<c131dbe0>] ? __device_attach+0x40/0x40
|
||
|
[<c131bd87>] bus_for_each_dev+0x47/0x80
|
||
|
[<c131d3ae>] driver_attach+0x1e/0x20
|
||
|
[<c131dbe0>] ? __device_attach+0x40/0x40
|
||
|
[<c131d007>] bus_add_driver+0x157/0x230
|
||
|
[<c131e219>] driver_register+0x59/0xe0
|
||
|
...
|
||
|
|
||
|
Fix this by checking chip->dev pointer against NULL first. Also we can now
|
||
|
remove redundant check in acpi_gpiochip_request/free_interrupts().
|
||
|
|
||
|
Reported-by: Sabrina Dubroca <sd@queasysnail.net>
|
||
|
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||
|
---
|
||
|
Sabrina,
|
||
|
|
||
|
Can you please re-test this and provide your tested-by? I changed the patch
|
||
|
a bit to remove redundant checks. Just to be sure that I don't accidentally
|
||
|
break something.
|
||
|
|
||
|
Thanks.
|
||
|
|
||
|
drivers/gpio/gpiolib-acpi.c | 10 ++++++++--
|
||
|
1 file changed, 8 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
|
||
|
index bf0f8b476696..d5be56fe689e 100644
|
||
|
--- a/drivers/gpio/gpiolib-acpi.c
|
||
|
+++ b/drivers/gpio/gpiolib-acpi.c
|
||
|
@@ -233,7 +233,7 @@ static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio)
|
||
|
{
|
||
|
struct gpio_chip *chip = acpi_gpio->chip;
|
||
|
|
||
|
- if (!chip->dev || !chip->to_irq)
|
||
|
+ if (!chip->to_irq)
|
||
|
return;
|
||
|
|
||
|
INIT_LIST_HEAD(&acpi_gpio->events);
|
||
|
@@ -253,7 +253,7 @@ static void acpi_gpiochip_free_interrupts(struct acpi_gpio_chip *acpi_gpio)
|
||
|
struct acpi_gpio_event *event, *ep;
|
||
|
struct gpio_chip *chip = acpi_gpio->chip;
|
||
|
|
||
|
- if (!chip->dev || !chip->to_irq)
|
||
|
+ if (!chip->to_irq)
|
||
|
return;
|
||
|
|
||
|
list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
|
||
|
@@ -501,6 +501,9 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
|
||
|
acpi_handle handle;
|
||
|
acpi_status status;
|
||
|
|
||
|
+ if (!chip || !chip->dev)
|
||
|
+ return;
|
||
|
+
|
||
|
handle = ACPI_HANDLE(chip->dev);
|
||
|
if (!handle)
|
||
|
return;
|
||
|
@@ -531,6 +534,9 @@ void acpi_gpiochip_remove(struct gpio_chip *chip)
|
||
|
acpi_handle handle;
|
||
|
acpi_status status;
|
||
|
|
||
|
+ if (!chip || !chip->dev)
|
||
|
+ return;
|
||
|
+
|
||
|
handle = ACPI_HANDLE(chip->dev);
|
||
|
if (!handle)
|
||
|
return;
|
||
|
--
|
||
|
1.9.1
|
||
|
|
||
|
--
|
||
|
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
|
||
|
the body of a message to majordomo@vger.kernel.org
|
||
|
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||
|
|