From patchwork Mon Sep 13 13:11:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kroah-Hartman X-Patchwork-Id: 510516 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=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham 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 41DACC433EF for ; Mon, 13 Sep 2021 14:25:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2CC83610A6 for ; Mon, 13 Sep 2021 14:25:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345375AbhIMO00 (ORCPT ); Mon, 13 Sep 2021 10:26:26 -0400 Received: from mail.kernel.org ([198.145.29.99]:41888 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345273AbhIMOW2 (ORCPT ); Mon, 13 Sep 2021 10:22:28 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 8B14561B42; Mon, 13 Sep 2021 13:47:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1631540853; bh=iLD+mXtGbR2r/Jtu3FVSTFfRzd3SciwMvd6HYDr/J6M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gLJPQQ0h/XdPW37SGRDereeTAIJbk35fI9LuF0ekibIDCl1XuE7s8xRbp4m6GFOnD vjoAMxHZoQJKUutJEibVZDeTLcArZ1A5WEOTlGUtLpRuZb1p+ldCRi7Jw43DsFh1qq XA6fpLUef0Y+mSV+rM/mFP3VlWBJjGIOpH+w/gvk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ben Hutchings , Herbert Xu , Sasha Levin Subject: [PATCH 5.14 029/334] crypto: omap - Fix inconsistent locking of device lists Date: Mon, 13 Sep 2021 15:11:23 +0200 Message-Id: <20210913131114.393965336@linuxfoundation.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210913131113.390368911@linuxfoundation.org> References: <20210913131113.390368911@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Ben Hutchings [ Upstream commit fe4d55773b879c785ae61da9b1c2160f0110f67e ] lockdep complains that in omap-aes, the list_lock is taken both with softirqs enabled at probe time, and also in softirq context, which could lead to a deadlock: ================================ WARNING: inconsistent lock state 5.14.0-rc1-00035-gc836005b01c5-dirty #69 Not tainted -------------------------------- inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. ksoftirqd/0/7 [HC0[0]:SC1[3]:HE1:SE0] takes: bf00e014 (list_lock){+.?.}-{2:2}, at: omap_aes_find_dev+0x18/0x54 [omap_aes_driver] {SOFTIRQ-ON-W} state was registered at: _raw_spin_lock+0x40/0x50 omap_aes_probe+0x1d4/0x664 [omap_aes_driver] platform_probe+0x58/0xb8 really_probe+0xbc/0x314 __driver_probe_device+0x80/0xe4 driver_probe_device+0x30/0xc8 __driver_attach+0x70/0xf4 bus_for_each_dev+0x70/0xb4 bus_add_driver+0xf0/0x1d4 driver_register+0x74/0x108 do_one_initcall+0x84/0x2e4 do_init_module+0x5c/0x240 load_module+0x221c/0x2584 sys_finit_module+0xb0/0xec ret_fast_syscall+0x0/0x2c 0xbed90b30 irq event stamp: 111800 hardirqs last enabled at (111800): [] __kmalloc+0x484/0x5ec hardirqs last disabled at (111799): [] __kmalloc+0x490/0x5ec softirqs last enabled at (111776): [] __do_softirq+0x2b8/0x4d0 softirqs last disabled at (111781): [] run_ksoftirqd+0x34/0x50 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(list_lock); lock(list_lock); *** DEADLOCK *** 2 locks held by ksoftirqd/0/7: #0: c0f5e8c8 (rcu_read_lock){....}-{1:2}, at: netif_receive_skb+0x6c/0x260 #1: c0f5e8c8 (rcu_read_lock){....}-{1:2}, at: ip_local_deliver_finish+0x2c/0xdc stack backtrace: CPU: 0 PID: 7 Comm: ksoftirqd/0 Not tainted 5.14.0-rc1-00035-gc836005b01c5-dirty #69 Hardware name: Generic AM43 (Flattened Device Tree) [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (mark_lock.part.17+0x5bc/0xd04) [] (mark_lock.part.17) from [] (__lock_acquire+0x960/0x2fa4) [] (__lock_acquire) from [] (lock_acquire+0x10c/0x358) [] (lock_acquire) from [] (_raw_spin_lock_bh+0x44/0x58) [] (_raw_spin_lock_bh) from [] (omap_aes_find_dev+0x18/0x54 [omap_aes_driver]) [] (omap_aes_find_dev [omap_aes_driver]) from [] (omap_aes_crypt+0x94/0xd4 [omap_aes_driver]) [] (omap_aes_crypt [omap_aes_driver]) from [] (esp_input+0x1b0/0x2c8) [] (esp_input) from [] (xfrm_input+0x410/0x1290) [] (xfrm_input) from [] (xfrm4_esp_rcv+0x54/0x11c) [] (xfrm4_esp_rcv) from [] (ip_protocol_deliver_rcu+0x48/0x3bc) [] (ip_protocol_deliver_rcu) from [] (ip_local_deliver_finish+0x9c/0xdc) [] (ip_local_deliver_finish) from [] (ip_local_deliver+0x148/0x1b0) [] (ip_local_deliver) from [] (ip_rcv+0x11c/0x180) [] (ip_rcv) from [] (__netif_receive_skb_one_core+0x54/0x74) [] (__netif_receive_skb_one_core) from [] (netif_receive_skb+0xa8/0x260) [] (netif_receive_skb) from [] (cpsw_rx_handler+0x224/0x2fc) [] (cpsw_rx_handler) from [] (__cpdma_chan_process+0xf4/0x188) [] (__cpdma_chan_process) from [] (cpdma_chan_process+0x3c/0x5c) [] (cpdma_chan_process) from [] (cpsw_rx_mq_poll+0x44/0x98) [] (cpsw_rx_mq_poll) from [] (__napi_poll+0x28/0x268) [] (__napi_poll) from [] (net_rx_action+0xcc/0x204) [] (net_rx_action) from [] (__do_softirq+0x140/0x4d0) [] (__do_softirq) from [] (run_ksoftirqd+0x34/0x50) [] (run_ksoftirqd) from [] (smpboot_thread_fn+0xf4/0x1d8) [] (smpboot_thread_fn) from [] (kthread+0x14c/0x174) [] (kthread) from [] (ret_from_fork+0x14/0x38) ... The omap-des and omap-sham drivers appear to have a similar issue. Fix this by using spin_{,un}lock_bh() around device list access in all the probe and remove functions. Signed-off-by: Ben Hutchings Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/omap-aes.c | 8 ++++---- drivers/crypto/omap-des.c | 8 ++++---- drivers/crypto/omap-sham.c | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index 0dd4c6b157de..9b968ac4ee7b 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -1175,9 +1175,9 @@ static int omap_aes_probe(struct platform_device *pdev) spin_lock_init(&dd->lock); INIT_LIST_HEAD(&dd->list); - spin_lock(&list_lock); + spin_lock_bh(&list_lock); list_add_tail(&dd->list, &dev_list); - spin_unlock(&list_lock); + spin_unlock_bh(&list_lock); /* Initialize crypto engine */ dd->engine = crypto_engine_alloc_init(dev, 1); @@ -1264,9 +1264,9 @@ static int omap_aes_remove(struct platform_device *pdev) if (!dd) return -ENODEV; - spin_lock(&list_lock); + spin_lock_bh(&list_lock); list_del(&dd->list); - spin_unlock(&list_lock); + spin_unlock_bh(&list_lock); for (i = dd->pdata->algs_info_size - 1; i >= 0; i--) for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) { diff --git a/drivers/crypto/omap-des.c b/drivers/crypto/omap-des.c index bc8631363d72..be77656864e3 100644 --- a/drivers/crypto/omap-des.c +++ b/drivers/crypto/omap-des.c @@ -1033,9 +1033,9 @@ static int omap_des_probe(struct platform_device *pdev) INIT_LIST_HEAD(&dd->list); - spin_lock(&list_lock); + spin_lock_bh(&list_lock); list_add_tail(&dd->list, &dev_list); - spin_unlock(&list_lock); + spin_unlock_bh(&list_lock); /* Initialize des crypto engine */ dd->engine = crypto_engine_alloc_init(dev, 1); @@ -1094,9 +1094,9 @@ static int omap_des_remove(struct platform_device *pdev) if (!dd) return -ENODEV; - spin_lock(&list_lock); + spin_lock_bh(&list_lock); list_del(&dd->list); - spin_unlock(&list_lock); + spin_unlock_bh(&list_lock); for (i = dd->pdata->algs_info_size - 1; i >= 0; i--) for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index a47ac60a4ee1..63beea7cdba5 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -2144,9 +2144,9 @@ static int omap_sham_probe(struct platform_device *pdev) (rev & dd->pdata->major_mask) >> dd->pdata->major_shift, (rev & dd->pdata->minor_mask) >> dd->pdata->minor_shift); - spin_lock(&sham.lock); + spin_lock_bh(&sham.lock); list_add_tail(&dd->list, &sham.dev_list); - spin_unlock(&sham.lock); + spin_unlock_bh(&sham.lock); dd->engine = crypto_engine_alloc_init(dev, 1); if (!dd->engine) { @@ -2194,9 +2194,9 @@ err_algs: err_engine_start: crypto_engine_exit(dd->engine); err_engine: - spin_lock(&sham.lock); + spin_lock_bh(&sham.lock); list_del(&dd->list); - spin_unlock(&sham.lock); + spin_unlock_bh(&sham.lock); err_pm: pm_runtime_disable(dev); if (!dd->polling_mode) @@ -2215,9 +2215,9 @@ static int omap_sham_remove(struct platform_device *pdev) dd = platform_get_drvdata(pdev); if (!dd) return -ENODEV; - spin_lock(&sham.lock); + spin_lock_bh(&sham.lock); list_del(&dd->list); - spin_unlock(&sham.lock); + spin_unlock_bh(&sham.lock); for (i = dd->pdata->algs_info_size - 1; i >= 0; i--) for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) { crypto_unregister_ahash(