From: Mathias Nyman <mathias.nyman@linux.intel.com>
To: Sergey Shtylyov <s.shtylyov@omp.ru>,
Mathias Nyman <mathias.nyman@intel.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
linux-usb@vger.kernel.org
Cc: Florian Fainelli <f.fainelli@gmail.com>
Subject: Re: [PATCH v4] usb: host: xhci-plat: fix possible kernel oops while resuming
Date: Mon, 11 Sep 2023 15:53:34 +0300 [thread overview]
Message-ID: <0957c21d-144b-1d84-2f79-f4cc6ba2a493@linux.intel.com> (raw)
In-Reply-To: <e0459058-5ca5-1c1a-c06a-47100c176ba2@omp.ru>
Hi
Sorry about the delay
On 11.7.2023 22.18, Sergey Shtylyov wrote:
> If this driver enables the xHC clocks while resuming from sleep, it calls
> clk_prepare_enable() without checking for errors and blithely goes on to
> read/write the xHC's registers -- which, with the xHC not being clocked,
> at least on ARM32 usually causes an imprecise external abort exceptions
> which cause kernel oops. Currently, the chips for which the driver does
> the clock dance on suspend/resume seem to be the Broadcom STB SoCs, based
> on ARM32 CPUs, as it seems...
>
> In order to fix this issue, add the result checks for clk_prepare_enable()
> calls in xhci_plat_resume(), add conditional clk_disable_unprepare() calls
> on the error path of xhci_plat_resume(); then factor out the common clock
> disabling code from the suspend() and resume() driver PM methods into a
> separate function to avoid code duplication.
Minor nitpick, but not sure a separate function is helpful here.
It's two lines of code called twice.
>
> Found by Linux Verification Center (linuxtesting.org) with the Svace static
> analysis tool.
>
> Fixes: 8bd954c56197 ("usb: host: xhci-plat: suspend and resume clocks")
> Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
If I understood correctly this issue hasn't been seen in real life,
and this patch only changes how we fail?
So I guess this would be more suitable for usb-next than usb-linus.
>
> ---
> This patch is against the 'usb-linus' branch of Greg KH's 'usb.git' repo...
>
> Changes in version 4:
> - resolved reject in xhci_plat_resume() due to the changed xhci_resume() call;
> - added the __maybe_unused attribute to xhci_plat_disable_clocks().
>
> Changes in version 3:
> - sanitized the clock enabling error paths in xhci_plat_resume() WRT the
> applicability checks;
> - factored out the common clock disabling code from the suspend() and resume()
> driver PM methods;
> - added to the patch sescriptiun a passage describing the change being done.
>
> Changes in version 2:
> - fixed up the error path for clk_prepare_enable() calls in xhci_plat_resume().
>
> drivers/usb/host/xhci-plat.c | 35 +++++++++++++++++++++++++++--------
> 1 file changed, 27 insertions(+), 8 deletions(-)
>
> Index: usb/drivers/usb/host/xhci-plat.c
> ===================================================================
> --- usb.orig/drivers/usb/host/xhci-plat.c
> +++ usb/drivers/usb/host/xhci-plat.c
> @@ -424,6 +424,14 @@ void xhci_plat_remove(struct platform_de
> }
> EXPORT_SYMBOL_GPL(xhci_plat_remove);
>
> +static void __maybe_unused xhci_plat_disable_clocks(struct xhci_hcd *xhci)
> +{
> + if (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS) {
> + clk_disable_unprepare(xhci->clk);
> + clk_disable_unprepare(xhci->reg_clk);
> + }
> +}
> +
xhci_plat_disable_clocks() name is a bit misleading, it only disables the clocks
if clocks are set to be disabled/enabled during suspend/resume.
> static int __maybe_unused xhci_plat_suspend(struct device *dev)
> {
> struct usb_hcd *hcd = dev_get_drvdata(dev);
> @@ -444,10 +452,8 @@ static int __maybe_unused xhci_plat_susp
> if (ret)
> return ret;
>
> - if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) {
> - clk_disable_unprepare(xhci->clk);
> - clk_disable_unprepare(xhci->reg_clk);
> - }
> + if (!device_may_wakeup(dev))
> + xhci_plat_disable_clocks(xhci);
Not sure this change improves things
>
> return 0;
> }
> @@ -459,23 +465,36 @@ static int __maybe_unused xhci_plat_resu
> int ret;
>
> if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) {
> - clk_prepare_enable(xhci->clk);
> - clk_prepare_enable(xhci->reg_clk);
> + ret = clk_prepare_enable(xhci->clk);
> + if (ret)
> + return ret;
> +
> + ret = clk_prepare_enable(xhci->reg_clk);
> + if (ret) {
> + clk_disable_unprepare(xhci->clk);
> + return ret;
> + }
> }
>
> ret = xhci_priv_resume_quirk(hcd);
> if (ret)
> - return ret;
> + goto disable_clks;
>
> ret = xhci_resume(xhci, PMSG_RESUME);
> if (ret)
> - return ret;
> + goto disable_clks;
>
> pm_runtime_disable(dev);
> pm_runtime_set_active(dev);
> pm_runtime_enable(dev);
>
> return 0;
> +
> +disable_clks:
> + if (!device_may_wakeup(dev))
> + xhci_plat_disable_clocks(xhci);
I'd skip the helper and just do:
if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) {
clk_disable_unprepare(xhci->clk);
clk_disable_unprepare(xhci->reg_clk);
}
It better matches the if condition when enabling the clocks:
if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) {
ret = clk_prepare_enable(xhci->clk);
...
We also don't save any lines of code by adding the helper.
Thanks
Mathias
next prev parent reply other threads:[~2023-09-11 21:41 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-11 19:18 [PATCH v4] usb: host: xhci-plat: fix possible kernel oops while resuming Sergey Shtylyov
2023-09-08 18:58 ` Sergey Shtylyov
2023-09-11 12:53 ` Mathias Nyman [this message]
2023-09-19 20:53 ` Sergey Shtylyov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0957c21d-144b-1d84-2f79-f4cc6ba2a493@linux.intel.com \
--to=mathias.nyman@linux.intel.com \
--cc=f.fainelli@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-usb@vger.kernel.org \
--cc=mathias.nyman@intel.com \
--cc=s.shtylyov@omp.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox