]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Nov 2021 12:28:37 +0000 (13:28 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Nov 2021 12:28:37 +0000 (13:28 +0100)
added patches:
usb-chipidea-fix-interrupt-deadlock.patch

queue-4.9/series
queue-4.9/usb-chipidea-fix-interrupt-deadlock.patch [new file with mode: 0644]

index d7e5f180fcf3f90d4d66cb4434d1b864951f3b67..0bdea1a5245730ad0a70d5def5cefdc977d98f74 100644 (file)
@@ -151,3 +151,4 @@ mm-zsmalloc.c-close-race-window-between-zs_pool_dec_.patch
 llc-fix-out-of-bound-array-index-in-llc_sk_dev_hash.patch
 nfc-pn533-fix-double-free-when-pn533_fill_fragment_s.patch
 vsock-prevent-unnecessary-refcnt-inc-for-nonblocking.patch
+usb-chipidea-fix-interrupt-deadlock.patch
diff --git a/queue-4.9/usb-chipidea-fix-interrupt-deadlock.patch b/queue-4.9/usb-chipidea-fix-interrupt-deadlock.patch
new file mode 100644 (file)
index 0000000..aead494
--- /dev/null
@@ -0,0 +1,97 @@
+From 9aaa81c3366e8393a62374e3a1c67c69edc07b8a Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 21 Oct 2021 10:34:47 +0200
+Subject: USB: chipidea: fix interrupt deadlock
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 9aaa81c3366e8393a62374e3a1c67c69edc07b8a upstream.
+
+Chipidea core was calling the interrupt handler from non-IRQ context
+with interrupts enabled, something which can lead to a deadlock if
+there's an actual interrupt trying to take a lock that's already held
+(e.g. the controller lock in udc_irq()).
+
+Add a wrapper that can be used to fake interrupts instead of calling the
+handler directly.
+
+Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect")
+Fixes: 876d4e1e8298 ("usb: chipidea: core: add wakeup support for extcon")
+Cc: Peter Chen <peter.chen@kernel.org>
+Cc: stable@vger.kernel.org      # 4.4
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20211021083447.20078-1-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/chipidea/core.c |   21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/chipidea/core.c
++++ b/drivers/usb/chipidea/core.c
+@@ -516,7 +516,7 @@ int hw_device_reset(struct ci_hdrc *ci)
+       return 0;
+ }
+-static irqreturn_t ci_irq(int irq, void *data)
++static irqreturn_t ci_irq_handler(int irq, void *data)
+ {
+       struct ci_hdrc *ci = data;
+       irqreturn_t ret = IRQ_NONE;
+@@ -569,6 +569,15 @@ static irqreturn_t ci_irq(int irq, void
+       return ret;
+ }
++static void ci_irq(struct ci_hdrc *ci)
++{
++      unsigned long flags;
++
++      local_irq_save(flags);
++      ci_irq_handler(ci->irq, ci);
++      local_irq_restore(flags);
++}
++
+ static int ci_vbus_notifier(struct notifier_block *nb, unsigned long event,
+                           void *ptr)
+ {
+@@ -582,7 +591,7 @@ static int ci_vbus_notifier(struct notif
+       vbus->changed = true;
+-      ci_irq(ci->irq, ci);
++      ci_irq(ci);
+       return NOTIFY_DONE;
+ }
+@@ -599,7 +608,7 @@ static int ci_id_notifier(struct notifie
+       id->changed = true;
+-      ci_irq(ci->irq, ci);
++      ci_irq(ci);
+       return NOTIFY_DONE;
+ }
+@@ -1011,7 +1020,7 @@ static int ci_hdrc_probe(struct platform
+       }
+       platform_set_drvdata(pdev, ci);
+-      ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED,
++      ret = devm_request_irq(dev, ci->irq, ci_irq_handler, IRQF_SHARED,
+                       ci->platdata->name, ci);
+       if (ret)
+               goto stop;
+@@ -1126,11 +1135,11 @@ static void ci_extcon_wakeup_int(struct
+       if (!IS_ERR(cable_id->edev) && ci->is_otg &&
+               (otgsc & OTGSC_IDIE) && (otgsc & OTGSC_IDIS))
+-              ci_irq(ci->irq, ci);
++              ci_irq(ci);
+       if (!IS_ERR(cable_vbus->edev) && ci->is_otg &&
+               (otgsc & OTGSC_BSVIE) && (otgsc & OTGSC_BSVIS))
+-              ci_irq(ci->irq, ci);
++              ci_irq(ci);
+ }
+ static int ci_controller_resume(struct device *dev)