Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp407559pxb; Wed, 3 Mar 2021 06:23:42 -0800 (PST) X-Google-Smtp-Source: ABdhPJypMZPO7pfdvGuo5ZJ2rSvVl7umUjQJgqR5NUrhY2jkDsjczDM7mUm9Pviqaz+lnlvQE7Hd X-Received: by 2002:a05:6402:1152:: with SMTP id g18mr26022755edw.18.1614781422256; Wed, 03 Mar 2021 06:23:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614781422; cv=none; d=google.com; s=arc-20160816; b=jr3zjwEIXFiHdh06Cdw0tOCDjx6jMtQjdFlE8SiCGOBItDxAkU5UOYHDnhZD+VoZR0 g8p7VSzcK9Hf9Kx0xATbyf05i5Lhst3lIpgi1H23kbEunD7l0pX+KPbv5QlHKAJmCcg0 0pxr11qg0T4LJcIM2gc9EHmpfVM0GyeHD2dL+dzeucocMrIQAifw6EdqdxM7d6eXo74V 0zGcgIj8F22swkqvSIBHo6GS5g3WE0RFBO9ZcrwE9EsSyOzS7GkJWVa77vAU71wGcAHz lYwrs/KD+BsOplIek5XTUUalKoz+qWA3dNVwv+Kb2u3H/+qNtzUCPboKDk68blmHpXYL CFsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=FeoqlsoHyez3W2iw5MdB63YsTtl9FgyOtIEruWqyVYE=; b=KtbZ00hwugCF7lWQcoO9GxP0CfTz624GMf0Yx5eFHkc4KD8aRKk9n0a4p7FIvR0bGa 94EL4Ij3+Ps6DkxtVqsWaxDe97ZA3pRClm47QP+HbnEz9uyolVQJ9wVWHXky6fzYMgvY vWu0KXOVH9KJxrjs6uG+bftSYIXJAB9CLbuaXTtDc7R4QQy6oFxyylP8Wr22b4/BCVgk XuAfK54nvAlj5mcEVeKVSPXMGHr6xMTqistV97tnkDihqXuxWH0mwqA9R73btxZnVkvN aGo1swgyUD/FVlXZR+uvOsFDNIeCpPtibyGw685keeJ46geUVRhjDZjhxnS4mIIlDvwM Zk6Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=CGYRzUFQ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id r12si9762115ejz.5.2021.03.03.06.22.40; Wed, 03 Mar 2021 06:23:42 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=CGYRzUFQ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244436AbhCAVTP (ORCPT + 99 others); Mon, 1 Mar 2021 16:19:15 -0500 Received: from mail.kernel.org ([198.145.29.99]:57224 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237988AbhCARQE (ORCPT ); Mon, 1 Mar 2021 12:16:04 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id D4D9765049; Mon, 1 Mar 2021 16:46:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1614617171; bh=T5N5cxLsQvJY7duFiwBVY57v7LKXaW2XD6nWBcXQMoM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CGYRzUFQXa2WXKGE3M4itkLQPI+WBO0ZdagR591b/AZxHj+io/tjgqoGWD3dyj1dc kmtEvTVOYlm2z/IYvz4+mN2iE0nUfRVaisYArCl3RVfMDlMIYkGnE4hZXt7qXOPFYH u6m05mBdJRI9OeXr8nTil7i6ugdwm6PVgpVvtNdU= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Tony Lindgren , Paul Cercueil Subject: [PATCH 4.19 187/247] usb: musb: Fix runtime PM race in musb_queue_resume_work Date: Mon, 1 Mar 2021 17:13:27 +0100 Message-Id: <20210301161040.807618824@linuxfoundation.org> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210301161031.684018251@linuxfoundation.org> References: <20210301161031.684018251@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Paul Cercueil commit 0eaa1a3714db34a59ce121de5733c3909c529463 upstream. musb_queue_resume_work() would call the provided callback if the runtime PM status was 'active'. Otherwise, it would enqueue the request if the hardware was still suspended (musb->is_runtime_suspended is true). This causes a race with the runtime PM handlers, as it is possible to be in the case where the runtime PM status is not yet 'active', but the hardware has been awaken (PM resume function has been called). When hitting the race, the resume work was not enqueued, which probably triggered other bugs further down the stack. For instance, a telnet connection on Ingenic SoCs would result in a 50/50 chance of a segmentation fault somewhere in the musb code. Rework the code so that either we call the callback directly if (musb->is_runtime_suspended == 0), or enqueue the query otherwise. Fixes: ea2f35c01d5e ("usb: musb: Fix sleeping function called from invalid context for hdrc glue") Cc: stable@vger.kernel.org # v4.9+ Tested-by: Tony Lindgren Reviewed-by: Tony Lindgren Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20210123142502.16980-1-paul@crapouillou.net Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2108,32 +2108,35 @@ int musb_queue_resume_work(struct musb * { struct musb_pending_work *w; unsigned long flags; + bool is_suspended; int error; if (WARN_ON(!callback)) return -EINVAL; - if (pm_runtime_active(musb->controller)) - return callback(musb, data); + spin_lock_irqsave(&musb->list_lock, flags); + is_suspended = musb->is_runtime_suspended; - w = devm_kzalloc(musb->controller, sizeof(*w), GFP_ATOMIC); - if (!w) - return -ENOMEM; + if (is_suspended) { + w = devm_kzalloc(musb->controller, sizeof(*w), GFP_ATOMIC); + if (!w) { + error = -ENOMEM; + goto out_unlock; + } + + w->callback = callback; + w->data = data; - w->callback = callback; - w->data = data; - spin_lock_irqsave(&musb->list_lock, flags); - if (musb->is_runtime_suspended) { list_add_tail(&w->node, &musb->pending_list); error = 0; - } else { - dev_err(musb->controller, "could not add resume work %p\n", - callback); - devm_kfree(musb->controller, w); - error = -EINPROGRESS; } + +out_unlock: spin_unlock_irqrestore(&musb->list_lock, flags); + if (!is_suspended) + error = callback(musb, data); + return error; } EXPORT_SYMBOL_GPL(musb_queue_resume_work);