Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp1813435pxb; Sat, 23 Jan 2021 06:28:48 -0800 (PST) X-Google-Smtp-Source: ABdhPJygmEI2OiJqtbyij9JflKEEs1QHZcKpm9SsiwT3OdMkLScCz3xhw8DMHf9CDL8q8NsPFGPE X-Received: by 2002:a50:f288:: with SMTP id f8mr960731edm.388.1611412128553; Sat, 23 Jan 2021 06:28:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1611412128; cv=none; d=google.com; s=arc-20160816; b=zr3SEL8kLFlvz+Db7qsYgnLOYB50eYMTHrePNAvvpI14NDV54uFM1iYtB50oVx9van EVciEwazGJhRVu5Pwop9fIJ+TqP2cuN88e3goq1/fBChsBclD7LxClsDy7GZ7C6eP3Q1 81FElBh89533IWEPzb1IlztY8m7lKVsHUT+SIi/K3xlopARGrrwdCQoBh2WD2L85VQVb dIZ6l9gfZILe1Hwzkeq+TtwZhFGa3JejMCc2N8Ye0bZe/jbDNb9wqRt/DMowSKeA/Q+e k6YDXVHFAQiQSSZ2QL1igmq6J/c08OBG3T/t6iq1m4NfnKsy1+JXFW4sf/+AbQRp5Mwn ovMQ== 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 :message-id:date:subject:cc:to:from; bh=zcCs0KrlnlbI2YtZoNcP4WnP5AjVfWlTG2BEhLMcmxY=; b=txXnC5eEZ1mYDs3vR/fRJHwigf/d9KHEDvvs0j5QzY4kWN5p0GPY1MatOYGYgzNb1b WutR13r0qou7V7D8u8v1XXA3Tts1MTP3ol97v2TSkIFW37lEm2KjxUwEzdfHPgjE9d+O OxXvP/j5QsHdxcG8U/FTBpiOZ6xcZ0YiFZaDuFFVpCIFwzObXRMl3kXmdoJ5vV8HPisW SCybhiJx8oT2awPmB9IIvimqUod9SC5U6xLLV338h2iHM/PRMGkWapJY91fCQJ8MOn3X 7+y5vzvwSXJtp1NKPm9gMNWdflTRbKTPnPCi3/I0D+N7hQefA0xYiAaNUiyPAIAzjnqs 6GsQ== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q18si4020993ejt.469.2021.01.23.06.28.25; Sat, 23 Jan 2021 06:28:48 -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; 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=fail (p=NONE sp=NONE dis=NONE) header.from=crapouillou.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726013AbhAWO0H (ORCPT + 99 others); Sat, 23 Jan 2021 09:26:07 -0500 Received: from aposti.net ([89.234.176.197]:33652 "EHLO aposti.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725899AbhAWO0F (ORCPT ); Sat, 23 Jan 2021 09:26:05 -0500 From: Paul Cercueil To: Bin Liu , Greg Kroah-Hartman Cc: Tony Lindgren , od@zcrc.me, linux-mips@vger.kernel.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Paul Cercueil , stable@vger.kernel.org Subject: [RE-RESEND PATCH 1/4] usb: musb: Fix runtime PM race in musb_queue_resume_work Date: Sat, 23 Jan 2021 14:24:59 +0000 Message-Id: <20210123142502.16980-1-paul@crapouillou.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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+ Signed-off-by: Paul Cercueil Reviewed-by: Tony Lindgren Tested-by: Tony Lindgren --- drivers/usb/musb/musb_core.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 849e0b770130..1cd87729ba60 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2240,32 +2240,35 @@ int musb_queue_resume_work(struct musb *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; + + if (is_suspended) { + w = devm_kzalloc(musb->controller, sizeof(*w), GFP_ATOMIC); + if (!w) { + error = -ENOMEM; + goto out_unlock; + } - w = devm_kzalloc(musb->controller, sizeof(*w), GFP_ATOMIC); - if (!w) - return -ENOMEM; + 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); -- 2.29.2