Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp460688pxb; Wed, 3 Mar 2021 07:30:26 -0800 (PST) X-Google-Smtp-Source: ABdhPJyIThoV6vAQGWqdhjgU+arWVWkYCAYruWF5/nUXPD0UToMtUfTYs4JDmOCx6xfKw/ijbUas X-Received: by 2002:a50:bc15:: with SMTP id j21mr25677347edh.187.1614785426715; Wed, 03 Mar 2021 07:30:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614785426; cv=none; d=google.com; s=arc-20160816; b=ZmWKphYcqcgZ9ALscjZDIIEGoAXqFIvrk+DASOWBjEly8vVYgl65TS+Lyy9YqkVvr0 llqemL0a4Fuf7z0u1CcBXpAoCqQhUvGxY3M4qIyg9Ln+6z2clE6PjB0KU5macLfu3lBk hEG5/N57qBteaVvyeSEOrBsguGnK53W1YUQFWoz2HJOABbj6U24xvZ3hFL8NjK61GiM+ HQA3UVK5orr93rtF6dhQwB7vRXamptA/ruAmJi5aZE5HssdNfeoNyy79SMvWhw5ZK3ZY f/3HDtodwqxsfYwMBLBw3Yav+GDEDzugFAOW7sCm1xpOHDLM4WBXr3CTV6LUOYKGgSGQ XeRA== 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=U4Klbx+i+Adqm9HwPG9V6m07N4YHwpBgdV+htZCj+K8=; b=uiS72tjbWsBA+SLklSJiB3TjObHOI3MagRqZX9I4VfteapwcuQ7JxwK+kiB/kfaEYc FNXhgvSoqCnLxDnUEUcmW3SN/uGs7sV5yqfmwL6NgLzLFBRRXF3/lw4zCrfWADmFnGCW pE97rYiDkD5m2lRBPmxbRsICSDgcnSW4OVe+EZtsHk4mvtD7iNC5XayfRq/LrC/sQFdi iBYcu4tpZBt82GrlFKoZjLWAg/cBVyTAGqxu0IXooVHlz/PG64TBI45cTrfQsutkxvDs PhjFqpHrZKX+z6uA8vce3eLXE7CZv4Cri/dkd61/LEq2p9GRu5UOj/Mlfgkh/Ys2owIM HpWA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=vrufsdy8; 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 he13si15201005ejc.666.2021.03.03.07.29.01; Wed, 03 Mar 2021 07:30:26 -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=vrufsdy8; 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 S1343908AbhCAWiU (ORCPT + 99 others); Mon, 1 Mar 2021 17:38:20 -0500 Received: from mail.kernel.org ([198.145.29.99]:40268 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238534AbhCARqq (ORCPT ); Mon, 1 Mar 2021 12:46:46 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 5C6FB650DA; Mon, 1 Mar 2021 16:58:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1614617929; bh=nhG+mPkNm4OVj7lm0N6+F/9SjWccEWKME955T8reZo4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vrufsdy81pwCCpxYFnlZ2f2UG3JGN2+KjF091W4rSgYmWFl+ve80ixkRH58j8ArQW 3/GcmIUQ/K5zAgohdFy/NmVAi506BXGI/5fsfDBCNNpN6/+NaJUGLDp8iDFwZR8MIO W6RGA0Ee5f7mpppmlGFFAYL7H373iz+sQ05ddx3A= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Tony Lindgren , Paul Cercueil Subject: [PATCH 5.4 246/340] usb: musb: Fix runtime PM race in musb_queue_resume_work Date: Mon, 1 Mar 2021 17:13:10 +0100 Message-Id: <20210301161100.394773185@linuxfoundation.org> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210301161048.294656001@linuxfoundation.org> References: <20210301161048.294656001@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 @@ -2102,32 +2102,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);