--- /dev/null
+From 712a951025c0667ff00b25afc360f74e639dfabe Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Tue, 2 Nov 2021 11:10:37 +0100
+Subject: fuse: fix page stealing
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit 712a951025c0667ff00b25afc360f74e639dfabe upstream.
+
+It is possible to trigger a crash by splicing anon pipe bufs to the fuse
+device.
+
+The reason for this is that anon_pipe_buf_release() will reuse buf->page if
+the refcount is 1, but that page might have already been stolen and its
+flags modified (e.g. PG_lru added).
+
+This happens in the unlikely case of fuse_dev_splice_write() getting around
+to calling pipe_buf_release() after a page has been stolen, added to the
+page cache and removed from the page cache.
+
+Fix by calling pipe_buf_release() right after the page was inserted into
+the page cache. In this case the page has an elevated refcount so any
+release function will know that the page isn't reusable.
+
+Reported-by: Frank Dinoff <fdinoff@google.com>
+Link: https://lore.kernel.org/r/CAAmZXrsGg2xsP1CK+cbuEMumtrqdvD-NKnWzhNcvn71RV3c1yw@mail.gmail.com/
+Fixes: dd3bb14f44a6 ("fuse: support splice() writing to fuse device")
+Cc: <stable@vger.kernel.org> # v2.6.35
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/dev.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -922,6 +922,13 @@ static int fuse_try_move_page(struct fus
+ return err;
+ }
+
++ /*
++ * Release while we have extra ref on stolen page. Otherwise
++ * anon_pipe_buf_release() might think the page can be reused.
++ */
++ buf->ops->release(cs->pipe, buf);
++ buf->ops = NULL;
++
+ page_cache_get(newpage);
+
+ if (!(buf->flags & PIPE_BUF_FLAG_LRU))
+@@ -2090,7 +2097,8 @@ static ssize_t fuse_dev_splice_write(str
+ out_free:
+ for (idx = 0; idx < nbuf; idx++) {
+ struct pipe_buffer *buf = &bufs[idx];
+- buf->ops->release(pipe, buf);
++ if (buf->ops)
++ buf->ops->release(pipe, buf);
+ }
+ pipe_unlock(pipe);
+
--- /dev/null
+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
+@@ -518,7 +518,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;
+@@ -571,6 +571,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)
+ {
+@@ -584,7 +593,7 @@ static int ci_vbus_notifier(struct notif
+
+ vbus->changed = true;
+
+- ci_irq(ci->irq, ci);
++ ci_irq(ci);
+ return NOTIFY_DONE;
+ }
+
+@@ -601,7 +610,7 @@ static int ci_id_notifier(struct notifie
+
+ id->changed = true;
+
+- ci_irq(ci->irq, ci);
++ ci_irq(ci);
+ return NOTIFY_DONE;
+ }
+
+@@ -1023,7 +1032,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;
+@@ -1138,11 +1147,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)