From patchwork Wed Sep 7 03:46:59 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: hotran X-Patchwork-Id: 9318157 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7A7E160869 for ; Wed, 7 Sep 2016 03:47:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5F51928FD8 for ; Wed, 7 Sep 2016 03:47:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 52C2428FEC; Wed, 7 Sep 2016 03:47:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 71A5B28FD8 for ; Wed, 7 Sep 2016 03:47:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756387AbcIGDrW (ORCPT ); Tue, 6 Sep 2016 23:47:22 -0400 Received: from mail-pf0-f180.google.com ([209.85.192.180]:34165 "EHLO mail-pf0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756118AbcIGDrW (ORCPT ); Tue, 6 Sep 2016 23:47:22 -0400 Received: by mail-pf0-f180.google.com with SMTP id p64so1726815pfb.1 for ; Tue, 06 Sep 2016 20:47:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=apm.com; s=apm; h=from:to:cc:subject:date:message-id; bh=fJWZxyA4LitQ+7QRZpuW8xcWVjtVOboX/lW0RHlZS/I=; b=f5+A0zqUqW8NY00gNjWjqJTel5jFLWXfbCxTfkKFuI/sdR2us/tij4+vBP4YQC00jH mg2pzoix33Lhe8w6nATLtRTg2iKShjXSiWuDC2JUVQ12BEkCglry5DxwnRg6H7nNVcrM P2dH/ga6f/e447rHn8g5vi1sY3UAylLF9nmmQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=fJWZxyA4LitQ+7QRZpuW8xcWVjtVOboX/lW0RHlZS/I=; b=SVg1xz1o2EogXGwrQG6/WNyhm47TS6f3LB7hzT8hve8PbR22Vpgd10H2cd2AbUO65K QmOmIA0Z3F4J8hXyRQzrKcommEAugMj18pgfnrd0jTjpBqNJSU1KyMpr8Gu3gW7OTurV SI3rrGQiKu5E3G2kMOF1wc2PJ3kKh37L84XA6+PWIaCa0HGz8NBhOn0eJDpxw/jW0/A1 O4ZHWBka1jgp6lhfI3rrZwM/Lzwg9s+mHqGYLsIrf1GjCetLgCqHePhmqcZsdkeU58aD Uz9Ly5U3CZZI6nrC8xbM3YW9fcAjWiwJ9BiI1P5bPyF5UuAIZuvidgT+LE7w2N1PCGVF kAzA== X-Gm-Message-State: AE9vXwPuOTP3Rk17QKaagAK0G6T4o/yjC76CpKJ0KmSgjqMigob25raAu55rR5YU2U/lK6S7 X-Received: by 10.98.216.129 with SMTP id e123mr27519872pfg.123.1473220041024; Tue, 06 Sep 2016 20:47:21 -0700 (PDT) Received: from hotran_localhost.amcc.com ([206.80.4.98]) by smtp.gmail.com with ESMTPSA id w76sm44175189pfd.69.2016.09.06.20.47.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 06 Sep 2016 20:47:20 -0700 (PDT) From: Hoan Tran To: Guenter Roeck , Jean Delvare Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org, Itaru Kitayama , lho@apm.com, Duc Dang , Hoan Tran Subject: [PATCH] hwmon: xgene: Fix crash when alarm occurs before driver probe Date: Tue, 6 Sep 2016 20:46:59 -0700 Message-Id: <1473220019-2519-1-git-send-email-hotran@apm.com> X-Mailer: git-send-email 1.9.1 Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The system crashes during probing xgene-hwmon driver when temperature alarm interrupt occurs before. It's because - xgene_hwmon_probe() requests PCC mailbox channel which also enables the mailbox interrupt. - As temperature alarm interrupt is pending, ISR runs and crashes when accesses into invalid resource as unmapped PCC shared memory. This patch fixes this issue by saving this alarm message and scheduling a bottom handler after xgene_hwmon_probe() finish. Signed-off-by: Hoan Tran Reported-by: Itaru Kitayama --- drivers/hwmon/xgene-hwmon.c | 75 +++++++++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 19 deletions(-) diff --git a/drivers/hwmon/xgene-hwmon.c b/drivers/hwmon/xgene-hwmon.c index bc78a5d..e3b4e84 100644 --- a/drivers/hwmon/xgene-hwmon.c +++ b/drivers/hwmon/xgene-hwmon.c @@ -107,6 +107,8 @@ struct xgene_hwmon_dev { struct completion rd_complete; int resp_pending; struct slimpro_resp_msg sync_msg; + bool init_flag; + bool rx_pending; struct work_struct workq; struct kfifo_rec_ptr_1 async_msg_fifo; @@ -465,13 +467,35 @@ static void xgene_hwmon_evt_work(struct work_struct *work) } } +static int xgene_hwmon_rx_ready(struct xgene_hwmon_dev *ctx, void *msg) +{ + if (!ctx->init_flag) { + ctx->rx_pending = true; + /* Enqueue to the FIFO */ + kfifo_in_spinlocked(&ctx->async_msg_fifo, msg, + sizeof(struct slimpro_resp_msg), + &ctx->kfifo_lock); + return -EBUSY; + } + + return 0; +} + /* * This function is called when the SLIMpro Mailbox received a message */ static void xgene_hwmon_rx_cb(struct mbox_client *cl, void *msg) { struct xgene_hwmon_dev *ctx = to_xgene_hwmon_dev(cl); - struct slimpro_resp_msg amsg; + + /* + * While the driver registers with the mailbox framework, an interrupt + * can be pending before the probe function completes its + * initialization. If such condition occurs, just queue up the message + * as the driver is not ready for servicing the callback. + */ + if (xgene_hwmon_rx_ready(ctx, msg) < 0) + return; /* * Response message format: @@ -500,12 +524,8 @@ static void xgene_hwmon_rx_cb(struct mbox_client *cl, void *msg) return; } - amsg.msg = ((u32 *)msg)[0]; - amsg.param1 = ((u32 *)msg)[1]; - amsg.param2 = ((u32 *)msg)[2]; - /* Enqueue to the FIFO */ - kfifo_in_spinlocked(&ctx->async_msg_fifo, &amsg, + kfifo_in_spinlocked(&ctx->async_msg_fifo, msg, sizeof(struct slimpro_resp_msg), &ctx->kfifo_lock); /* Schedule the bottom handler */ schedule_work(&ctx->workq); @@ -520,6 +540,15 @@ static void xgene_hwmon_pcc_rx_cb(struct mbox_client *cl, void *msg) struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr; struct slimpro_resp_msg amsg; + /* + * While the driver registers with the mailbox framework, an interrupt + * can be pending before the probe function completes its + * initialization. If such condition occurs, just queue up the message + * as the driver is not ready for servicing the callback. + */ + if (xgene_hwmon_rx_ready(ctx, &amsg) < 0) + return; + msg = generic_comm_base + 1; /* Check if platform sends interrupt */ if (!xgene_word_tst_and_clr(&generic_comm_base->status, @@ -596,6 +625,17 @@ static int xgene_hwmon_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ctx); cl = &ctx->mbox_client; + spin_lock_init(&ctx->kfifo_lock); + mutex_init(&ctx->rd_mutex); + + rc = kfifo_alloc(&ctx->async_msg_fifo, + sizeof(struct slimpro_resp_msg) * ASYNC_MSG_FIFO_SIZE, + GFP_KERNEL); + if (rc) + goto out_mbox_free; + + INIT_WORK(&ctx->workq, xgene_hwmon_evt_work); + /* Request mailbox channel */ cl->dev = &pdev->dev; cl->tx_done = xgene_hwmon_tx_done; @@ -676,17 +716,6 @@ static int xgene_hwmon_probe(struct platform_device *pdev) ctx->usecs_lat = PCC_NUM_RETRIES * cppc_ss->latency; } - spin_lock_init(&ctx->kfifo_lock); - mutex_init(&ctx->rd_mutex); - - rc = kfifo_alloc(&ctx->async_msg_fifo, - sizeof(struct slimpro_resp_msg) * ASYNC_MSG_FIFO_SIZE, - GFP_KERNEL); - if (rc) - goto out_mbox_free; - - INIT_WORK(&ctx->workq, xgene_hwmon_evt_work); - ctx->hwmon_dev = hwmon_device_register_with_groups(ctx->dev, "apm_xgene", ctx, @@ -697,17 +726,25 @@ static int xgene_hwmon_probe(struct platform_device *pdev) goto out; } + ctx->init_flag = true; + if (ctx->rx_pending) { + /* + * If there is a pending message, schedule the bottom handler + */ + schedule_work(&ctx->workq); + } + dev_info(&pdev->dev, "APM X-Gene SoC HW monitor driver registered\n"); return 0; out: - kfifo_free(&ctx->async_msg_fifo); -out_mbox_free: if (acpi_disabled) mbox_free_channel(ctx->mbox_chan); else pcc_mbox_free_channel(ctx->mbox_chan); +out_mbox_free: + kfifo_free(&ctx->async_msg_fifo); return rc; }