From patchwork Wed Dec 4 21:14:08 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Nikula X-Patchwork-Id: 3284331 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CDEF1C0D4A for ; Wed, 4 Dec 2013 19:14:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B166B204DF for ; Wed, 4 Dec 2013 19:14:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 757AE20498 for ; Wed, 4 Dec 2013 19:14:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756008Ab3LDTOp (ORCPT ); Wed, 4 Dec 2013 14:14:45 -0500 Received: from bitmer.com ([213.157.87.50]:48190 "EHLO bitmer.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756016Ab3LDTOc (ORCPT ); Wed, 4 Dec 2013 14:14:32 -0500 Received: from host-94-101-4-66.igua.fi ([94.101.4.66] helo=localhost.localdomain) by bitmer.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.72) (envelope-from ) id 1VoHtx-0004RA-GK; Wed, 04 Dec 2013 21:14:25 +0200 From: Jarkko Nikula To: Chris Ball Cc: linux-mmc@vger.kernel.org, linux-omap@vger.kernel.org, Tony Lindgren , Dan Carpenter , Aaro Koskinen , Jarkko Lavinen , Jarkko Nikula Subject: [PATCH 1/7] mmc: omap: Fix NULL pointer dereference due uninitialized cover_tasklet Date: Wed, 4 Dec 2013 21:14:08 +0000 Message-Id: <1386191654-7686-2-git-send-email-jarkko.nikula@bitmer.com> X-Mailer: git-send-email 1.8.4.3 In-Reply-To: <1386191654-7686-1-git-send-email-jarkko.nikula@bitmer.com> References: <20131202193459.GL26766@atomide.com> <1386191654-7686-1-git-send-email-jarkko.nikula@bitmer.com> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Omap MMC driver initialization can cause a NULL pointer dereference in tasklet_hi_action on Nokia N810 if its miniSD cover is open during driver initialization. [ 1.070000] Unable to handle kernel NULL pointer dereference at virtual address 00000000 [ 1.080000] pgd = c0004000 [ 1.080000] [00000000] *pgd=00000000 [ 1.080000] Internal error: Oops: 80000005 [#1] PREEMPT ARM [ 1.080000] Modules linked in: [ 1.080000] CPU: 0 PID: 24 Comm: kworker/0:1 Not tainted 3.13.0-rc2+ #95 [ 1.080000] Workqueue: events menelaus_work [ 1.080000] task: c7863340 ti: c7878000 task.ti: c7878000 [ 1.080000] PC is at 0x0 [ 1.080000] LR is at tasklet_hi_action+0x68/0xa4 ... [ 1.080000] [] (tasklet_hi_action+0x68/0xa4) from [] (__do_softirq+0xbc/0x208) [ 1.080000] [] (__do_softirq+0xbc/0x208) from [] (irq_exit+0x84/0xac) [ 1.080000] [] (irq_exit+0x84/0xac) from [] (handle_IRQ+0x64/0x84) [ 1.080000] [] (handle_IRQ+0x64/0x84) from [] (omap2_intc_handle_irq+0x54/0x68) [ 1.080000] [] (omap2_intc_handle_irq+0x54/0x68) from [] (__irq_svc+0x40/0x74) [ 1.080000] Exception stack(0xc7879d70 to 0xc7879db8) [ 1.080000] 9d60: 000003f1 0000000a 00000009 0000001c [ 1.080000] 9d80: c7879e70 c780bc10 c780bc10 00000000 00000001 00008603 c780bc78 c7879e4e [ 1.080000] 9da0: 00000002 c7879db8 c00343b0 c0160c9c 20000113 ffffffff [ 1.080000] [] (__irq_svc+0x40/0x74) from [] (__aeabi_uidiv+0x20/0x9c) [ 1.080000] [] (__aeabi_uidiv+0x20/0x9c) from [] (msecs_to_jiffies+0x18/0x24) [ 1.080000] [] (msecs_to_jiffies+0x18/0x24) from [] (omap_i2c_xfer+0x30c/0x458) [ 1.080000] [] (omap_i2c_xfer+0x30c/0x458) from [] (__i2c_transfer+0x3c/0x74) [ 1.080000] [] (__i2c_transfer+0x3c/0x74) from [] (i2c_transfer+0x78/0x94) [ 1.080000] [] (i2c_transfer+0x78/0x94) from [] (i2c_smbus_xfer+0x3c0/0x4f8) [ 1.080000] [] (i2c_smbus_xfer+0x3c0/0x4f8) from [] (i2c_smbus_write_byte_data+0x34/0x3c) [ 1.080000] [] (i2c_smbus_write_byte_data+0x34/0x3c) from [] (menelaus_write_reg+0x1c/0x40) [ 1.080000] [] (menelaus_write_reg+0x1c/0x40) from [] (menelaus_work+0xa0/0xc4) [ 1.080000] [] (menelaus_work+0xa0/0xc4) from [] (process_one_work+0x1fc/0x334) [ 1.080000] [] (process_one_work+0x1fc/0x334) from [] (worker_thread+0x244/0x380) [ 1.080000] [] (worker_thread+0x244/0x380) from [] (kthread+0xc0/0xd4) [ 1.080000] [] (kthread+0xc0/0xd4) from [] (ret_from_fork+0x14/0x3c) [ 1.080000] Code: bad PC value [ 1.090000] ---[ end trace 7bc2fc7cd14f1d95 ]--- [ 1.100000] Kernel panic - not syncing: Fatal exception in interrupt Reason for this is that omap_notify_cover_event which calls tasklet_hi_schedule gets called before struct cover_tasklet is initialized. Call to omap_notify_cover_event on Nokia N810 happens from menelaus.c PMIC driver via board-n8x0.c during execution of mmc_add_host in case of open miniSD cover. Fix this by moving cover_timer and cover_tasklet initialization before mmc_add_host call in mmc_omap_new_slot. Signed-off-by: Jarkko Nikula --- v2: a snip of stack dump added to commit log --- drivers/mmc/host/omap.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 98b6b6e..42b665d 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1262,6 +1262,13 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id) mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; mmc->max_seg_size = mmc->max_req_size; + if (slot->pdata->get_cover_state != NULL) { + setup_timer(&slot->cover_timer, mmc_omap_cover_timer, + (unsigned long)slot); + tasklet_init(&slot->cover_tasklet, mmc_omap_cover_handler, + (unsigned long)slot); + } + r = mmc_add_host(mmc); if (r < 0) goto err_remove_host; @@ -1278,11 +1285,6 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id) &dev_attr_cover_switch); if (r < 0) goto err_remove_slot_name; - - setup_timer(&slot->cover_timer, mmc_omap_cover_timer, - (unsigned long)slot); - tasklet_init(&slot->cover_tasklet, mmc_omap_cover_handler, - (unsigned long)slot); tasklet_schedule(&slot->cover_tasklet); }