--- /dev/null
+From 204361a77f4018627addd4a06877448f088ddfc0 Mon Sep 17 00:00:00 2001
+From: Pavel Begunkov <asml.silence@gmail.com>
+Date: Sun, 23 Aug 2020 20:33:10 +0300
+Subject: io-wq: fix hang after cancelling pending hashed work
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+commit 204361a77f4018627addd4a06877448f088ddfc0 upstream.
+
+Don't forget to update wqe->hash_tail after cancelling a pending work
+item, if it was hashed.
+
+Cc: stable@vger.kernel.org # 5.7+
+Reported-by: Dmitry Shulyak <yashulyak@gmail.com>
+Fixes: 86f3cd1b589a1 ("io-wq: handle hashed writes in chains")
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/io-wq.c | 21 +++++++++++++++++++--
+ 1 file changed, 19 insertions(+), 2 deletions(-)
+
+--- a/fs/io-wq.c
++++ b/fs/io-wq.c
+@@ -929,6 +929,24 @@ static bool io_wq_worker_cancel(struct i
+ return match->nr_running && !match->cancel_all;
+ }
+
++static inline void io_wqe_remove_pending(struct io_wqe *wqe,
++ struct io_wq_work *work,
++ struct io_wq_work_node *prev)
++{
++ unsigned int hash = io_get_work_hash(work);
++ struct io_wq_work *prev_work = NULL;
++
++ if (io_wq_is_hashed(work) && work == wqe->hash_tail[hash]) {
++ if (prev)
++ prev_work = container_of(prev, struct io_wq_work, list);
++ if (prev_work && io_get_work_hash(prev_work) == hash)
++ wqe->hash_tail[hash] = prev_work;
++ else
++ wqe->hash_tail[hash] = NULL;
++ }
++ wq_list_del(&wqe->work_list, &work->list, prev);
++}
++
+ static void io_wqe_cancel_pending_work(struct io_wqe *wqe,
+ struct io_cb_cancel_data *match)
+ {
+@@ -942,8 +960,7 @@ retry:
+ work = container_of(node, struct io_wq_work, list);
+ if (!match->fn(work, match->data))
+ continue;
+-
+- wq_list_del(&wqe->work_list, node, prev);
++ io_wqe_remove_pending(wqe, work, prev);
+ spin_unlock_irqrestore(&wqe->lock, flags);
+ io_run_cancel(work, wqe);
+ match->nr_pending++;
--- /dev/null
+From 56450c20fe10d4d93f58019109aa4e06fc0b9206 Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Wed, 26 Aug 2020 18:58:26 -0600
+Subject: io_uring: clear req->result on IOPOLL re-issue
+
+From: Jens Axboe <axboe@kernel.dk>
+
+commit 56450c20fe10d4d93f58019109aa4e06fc0b9206 upstream.
+
+Make sure we clear req->result, which was set to -EAGAIN for retry
+purposes, when moving it to the reissue list. Otherwise we can end up
+retrying a request more than once, which leads to weird results in
+the io-wq handling (and other spots).
+
+Cc: stable@vger.kernel.org
+Reported-by: Andres Freund <andres@anarazel.de>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/io_uring.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -1810,6 +1810,7 @@ static void io_iopoll_complete(struct io
+
+ req = list_first_entry(done, struct io_kiocb, list);
+ if (READ_ONCE(req->result) == -EAGAIN) {
++ req->result = 0;
+ req->iopoll_completed = 0;
+ list_move_tail(&req->list, &again);
+ continue;
--- /dev/null
+From 71a7f8cb1ca4ca7214a700b1243626759b6c11d4 Mon Sep 17 00:00:00 2001
+From: James Morse <james.morse@arm.com>
+Date: Fri, 21 Aug 2020 15:07:07 +0100
+Subject: KVM: arm64: Set HCR_EL2.PTW to prevent AT taking synchronous exception
+
+From: James Morse <james.morse@arm.com>
+
+commit 71a7f8cb1ca4ca7214a700b1243626759b6c11d4 upstream.
+
+AT instructions do a translation table walk and return the result, or
+the fault in PAR_EL1. KVM uses these to find the IPA when the value is
+not provided by the CPU in HPFAR_EL1.
+
+If a translation table walk causes an external abort it is taken as an
+exception, even if it was due to an AT instruction. (DDI0487F.a's D5.2.11
+"Synchronous faults generated by address translation instructions")
+
+While we previously made KVM resilient to exceptions taken due to AT
+instructions, the device access causes mismatched attributes, and may
+occur speculatively. Prevent this, by forbidding a walk through memory
+described as device at stage2. Now such AT instructions will report a
+stage2 fault.
+
+Such a fault will cause KVM to restart the guest. If the AT instructions
+always walk the page tables, but guest execution uses the translation cached
+in the TLB, the guest can't make forward progress until the TLB entry is
+evicted. This isn't a problem, as since commit 5dcd0fdbb492 ("KVM: arm64:
+Defer guest entry when an asynchronous exception is pending"), KVM will
+return to the host to process IRQs allowing the rest of the system to keep
+running.
+
+Cc: stable@vger.kernel.org # <v5.3: 5dcd0fdbb492 ("KVM: arm64: Defer guest entry when an asynchronous exception is pending")
+Signed-off-by: James Morse <james.morse@arm.com>
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/include/asm/kvm_arm.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/include/asm/kvm_arm.h
++++ b/arch/arm64/include/asm/kvm_arm.h
+@@ -71,11 +71,12 @@
+ * IMO: Override CPSR.I and enable signaling with VI
+ * FMO: Override CPSR.F and enable signaling with VF
+ * SWIO: Turn set/way invalidates into set/way clean+invalidate
++ * PTW: Take a stage2 fault if a stage1 walk steps in device memory
+ */
+ #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \
+ HCR_BSU_IS | HCR_FB | HCR_TAC | \
+ HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \
+- HCR_FMO | HCR_IMO)
++ HCR_FMO | HCR_IMO | HCR_PTW )
+ #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF)
+ #define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK)
+ #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
--- /dev/null
+From 205d300aea75623e1ae4aa43e0d265ab9cf195fd Mon Sep 17 00:00:00 2001
+From: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Date: Mon, 17 Aug 2020 11:26:46 +0900
+Subject: serial: 8250: change lock order in serial8250_do_startup()
+
+From: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+
+commit 205d300aea75623e1ae4aa43e0d265ab9cf195fd upstream.
+
+We have a number of "uart.port->desc.lock vs desc.lock->uart.port"
+lockdep reports coming from 8250 driver; this causes a bit of trouble
+to people, so let's fix it.
+
+The problem is reverse lock order in two different call paths:
+
+chain #1:
+
+ serial8250_do_startup()
+ spin_lock_irqsave(&port->lock);
+ disable_irq_nosync(port->irq);
+ raw_spin_lock_irqsave(&desc->lock)
+
+chain #2:
+
+ __report_bad_irq()
+ raw_spin_lock_irqsave(&desc->lock)
+ for_each_action_of_desc()
+ printk()
+ spin_lock_irqsave(&port->lock);
+
+Fix this by changing the order of locks in serial8250_do_startup():
+ do disable_irq_nosync() first, which grabs desc->lock, and grab
+ uart->port after that, so that chain #1 and chain #2 have same lock
+ order.
+
+Full lockdep splat:
+
+ ======================================================
+ WARNING: possible circular locking dependency detected
+ 5.4.39 #55 Not tainted
+ ======================================================
+
+ swapper/0/0 is trying to acquire lock:
+ ffffffffab65b6c0 (console_owner){-...}, at: console_lock_spinning_enable+0x31/0x57
+
+ but task is already holding lock:
+ ffff88810a8e34c0 (&irq_desc_lock_class){-.-.}, at: __report_bad_irq+0x5b/0xba
+
+ which lock already depends on the new lock.
+
+ the existing dependency chain (in reverse order) is:
+
+ -> #2 (&irq_desc_lock_class){-.-.}:
+ _raw_spin_lock_irqsave+0x61/0x8d
+ __irq_get_desc_lock+0x65/0x89
+ __disable_irq_nosync+0x3b/0x93
+ serial8250_do_startup+0x451/0x75c
+ uart_startup+0x1b4/0x2ff
+ uart_port_activate+0x73/0xa0
+ tty_port_open+0xae/0x10a
+ uart_open+0x1b/0x26
+ tty_open+0x24d/0x3a0
+ chrdev_open+0xd5/0x1cc
+ do_dentry_open+0x299/0x3c8
+ path_openat+0x434/0x1100
+ do_filp_open+0x9b/0x10a
+ do_sys_open+0x15f/0x3d7
+ kernel_init_freeable+0x157/0x1dd
+ kernel_init+0xe/0x105
+ ret_from_fork+0x27/0x50
+
+ -> #1 (&port_lock_key){-.-.}:
+ _raw_spin_lock_irqsave+0x61/0x8d
+ serial8250_console_write+0xa7/0x2a0
+ console_unlock+0x3b7/0x528
+ vprintk_emit+0x111/0x17f
+ printk+0x59/0x73
+ register_console+0x336/0x3a4
+ uart_add_one_port+0x51b/0x5be
+ serial8250_register_8250_port+0x454/0x55e
+ dw8250_probe+0x4dc/0x5b9
+ platform_drv_probe+0x67/0x8b
+ really_probe+0x14a/0x422
+ driver_probe_device+0x66/0x130
+ device_driver_attach+0x42/0x5b
+ __driver_attach+0xca/0x139
+ bus_for_each_dev+0x97/0xc9
+ bus_add_driver+0x12b/0x228
+ driver_register+0x64/0xed
+ do_one_initcall+0x20c/0x4a6
+ do_initcall_level+0xb5/0xc5
+ do_basic_setup+0x4c/0x58
+ kernel_init_freeable+0x13f/0x1dd
+ kernel_init+0xe/0x105
+ ret_from_fork+0x27/0x50
+
+ -> #0 (console_owner){-...}:
+ __lock_acquire+0x118d/0x2714
+ lock_acquire+0x203/0x258
+ console_lock_spinning_enable+0x51/0x57
+ console_unlock+0x25d/0x528
+ vprintk_emit+0x111/0x17f
+ printk+0x59/0x73
+ __report_bad_irq+0xa3/0xba
+ note_interrupt+0x19a/0x1d6
+ handle_irq_event_percpu+0x57/0x79
+ handle_irq_event+0x36/0x55
+ handle_fasteoi_irq+0xc2/0x18a
+ do_IRQ+0xb3/0x157
+ ret_from_intr+0x0/0x1d
+ cpuidle_enter_state+0x12f/0x1fd
+ cpuidle_enter+0x2e/0x3d
+ do_idle+0x1ce/0x2ce
+ cpu_startup_entry+0x1d/0x1f
+ start_kernel+0x406/0x46a
+ secondary_startup_64+0xa4/0xb0
+
+ other info that might help us debug this:
+
+ Chain exists of:
+ console_owner --> &port_lock_key --> &irq_desc_lock_class
+
+ Possible unsafe locking scenario:
+
+ CPU0 CPU1
+ ---- ----
+ lock(&irq_desc_lock_class);
+ lock(&port_lock_key);
+ lock(&irq_desc_lock_class);
+ lock(console_owner);
+
+ *** DEADLOCK ***
+
+ 2 locks held by swapper/0/0:
+ #0: ffff88810a8e34c0 (&irq_desc_lock_class){-.-.}, at: __report_bad_irq+0x5b/0xba
+ #1: ffffffffab65b5c0 (console_lock){+.+.}, at: console_trylock_spinning+0x20/0x181
+
+ stack backtrace:
+ CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.39 #55
+ Hardware name: XXXXXX
+ Call Trace:
+ <IRQ>
+ dump_stack+0xbf/0x133
+ ? print_circular_bug+0xd6/0xe9
+ check_noncircular+0x1b9/0x1c3
+ __lock_acquire+0x118d/0x2714
+ lock_acquire+0x203/0x258
+ ? console_lock_spinning_enable+0x31/0x57
+ console_lock_spinning_enable+0x51/0x57
+ ? console_lock_spinning_enable+0x31/0x57
+ console_unlock+0x25d/0x528
+ ? console_trylock+0x18/0x4e
+ vprintk_emit+0x111/0x17f
+ ? lock_acquire+0x203/0x258
+ printk+0x59/0x73
+ __report_bad_irq+0xa3/0xba
+ note_interrupt+0x19a/0x1d6
+ handle_irq_event_percpu+0x57/0x79
+ handle_irq_event+0x36/0x55
+ handle_fasteoi_irq+0xc2/0x18a
+ do_IRQ+0xb3/0x157
+ common_interrupt+0xf/0xf
+ </IRQ>
+
+Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Fixes: 768aec0b5bcc ("serial: 8250: fix shared interrupts issues with SMP and RT kernels")
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Reported-by: Raul Rangel <rrangel@google.com>
+BugLink: https://bugs.chromium.org/p/chromium/issues/detail?id=1114800
+Link: https://lore.kernel.org/lkml/CAHQZ30BnfX+gxjPm1DUd5psOTqbyDh4EJE=2=VAMW_VDafctkA@mail.gmail.com/T/#u
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200817022646.1484638-1-sergey.senozhatsky@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/8250/8250_port.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -2274,6 +2274,10 @@ int serial8250_do_startup(struct uart_po
+
+ if (port->irq && !(up->port.flags & UPF_NO_THRE_TEST)) {
+ unsigned char iir1;
++
++ if (port->irqflags & IRQF_SHARED)
++ disable_irq_nosync(port->irq);
++
+ /*
+ * Test for UARTs that do not reassert THRE when the
+ * transmitter is idle and the interrupt has already
+@@ -2283,8 +2287,6 @@ int serial8250_do_startup(struct uart_po
+ * allow register changes to become visible.
+ */
+ spin_lock_irqsave(&port->lock, flags);
+- if (up->port.irqflags & IRQF_SHARED)
+- disable_irq_nosync(port->irq);
+
+ wait_for_xmitr(up, UART_LSR_THRE);
+ serial_port_out_sync(port, UART_IER, UART_IER_THRI);
+@@ -2296,9 +2298,10 @@ int serial8250_do_startup(struct uart_po
+ iir = serial_port_in(port, UART_IIR);
+ serial_port_out(port, UART_IER, 0);
+
++ spin_unlock_irqrestore(&port->lock, flags);
++
+ if (port->irqflags & IRQF_SHARED)
+ enable_irq(port->irq);
+- spin_unlock_irqrestore(&port->lock, flags);
+
+ /*
+ * If the interrupt is not reasserted, or we otherwise
--- /dev/null
+From c6b9e95dde7b54e6a53c47241201ab5a4035c320 Mon Sep 17 00:00:00 2001
+From: Valmer Huhn <valmer.huhn@concurrent-rt.com>
+Date: Thu, 13 Aug 2020 12:52:55 -0400
+Subject: serial: 8250_exar: Fix number of ports for Commtech PCIe cards
+
+From: Valmer Huhn <valmer.huhn@concurrent-rt.com>
+
+commit c6b9e95dde7b54e6a53c47241201ab5a4035c320 upstream.
+
+The following in 8250_exar.c line 589 is used to determine the number
+of ports for each Exar board:
+
+nr_ports = board->num_ports ? board->num_ports : pcidev->device & 0x0f;
+
+If the number of ports a card has is not explicitly specified, it defaults
+to the rightmost 4 bits of the PCI device ID. This is prone to error since
+not all PCI device IDs contain a number which corresponds to the number of
+ports that card provides.
+
+This particular case involves COMMTECH_4222PCIE, COMMTECH_4224PCIE and
+COMMTECH_4228PCIE cards with device IDs 0x0022, 0x0020 and 0x0021.
+Currently the multiport cards receive 2, 0 and 1 port instead of 2, 4 and
+8 ports respectively.
+
+To fix this, each Commtech Fastcom PCIe card is given a struct where the
+number of ports is explicitly specified. This ensures 'board->num_ports'
+is used instead of the default 'pcidev->device & 0x0f'.
+
+Fixes: d0aeaa83f0b0 ("serial: exar: split out the exar code from 8250_pci")
+Signed-off-by: Valmer Huhn <valmer.huhn@concurrent-rt.com>
+Tested-by: Valmer Huhn <valmer.huhn@concurrent-rt.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200813165255.GC345440@icarus.concurrent-rt.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/8250/8250_exar.c | 24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+--- a/drivers/tty/serial/8250/8250_exar.c
++++ b/drivers/tty/serial/8250/8250_exar.c
+@@ -744,6 +744,24 @@ static const struct exar8250_board pbn_e
+ .exit = pci_xr17v35x_exit,
+ };
+
++static const struct exar8250_board pbn_fastcom35x_2 = {
++ .num_ports = 2,
++ .setup = pci_xr17v35x_setup,
++ .exit = pci_xr17v35x_exit,
++};
++
++static const struct exar8250_board pbn_fastcom35x_4 = {
++ .num_ports = 4,
++ .setup = pci_xr17v35x_setup,
++ .exit = pci_xr17v35x_exit,
++};
++
++static const struct exar8250_board pbn_fastcom35x_8 = {
++ .num_ports = 8,
++ .setup = pci_xr17v35x_setup,
++ .exit = pci_xr17v35x_exit,
++};
++
+ static const struct exar8250_board pbn_exar_XR17V4358 = {
+ .num_ports = 12,
+ .setup = pci_xr17v35x_setup,
+@@ -811,9 +829,9 @@ static const struct pci_device_id exar_p
+ EXAR_DEVICE(EXAR, XR17V358, pbn_exar_XR17V35x),
+ EXAR_DEVICE(EXAR, XR17V4358, pbn_exar_XR17V4358),
+ EXAR_DEVICE(EXAR, XR17V8358, pbn_exar_XR17V8358),
+- EXAR_DEVICE(COMMTECH, 4222PCIE, pbn_exar_XR17V35x),
+- EXAR_DEVICE(COMMTECH, 4224PCIE, pbn_exar_XR17V35x),
+- EXAR_DEVICE(COMMTECH, 4228PCIE, pbn_exar_XR17V35x),
++ EXAR_DEVICE(COMMTECH, 4222PCIE, pbn_fastcom35x_2),
++ EXAR_DEVICE(COMMTECH, 4224PCIE, pbn_fastcom35x_4),
++ EXAR_DEVICE(COMMTECH, 4228PCIE, pbn_fastcom35x_8),
+
+ EXAR_DEVICE(COMMTECH, 4222PCI335, pbn_fastcom335_2),
+ EXAR_DEVICE(COMMTECH, 4224PCI335, pbn_fastcom335_4),
--- /dev/null
+From 89efbe70b27dd325d8a8c177743a26b885f7faec Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Thu, 13 Aug 2020 12:59:54 +0200
+Subject: serial: pl011: Don't leak amba_ports entry on driver register error
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 89efbe70b27dd325d8a8c177743a26b885f7faec upstream.
+
+pl011_probe() calls pl011_setup_port() to reserve an amba_ports[] entry,
+then calls pl011_register_port() to register the uart driver with the
+tty layer.
+
+If registration of the uart driver fails, the amba_ports[] entry is not
+released. If this happens 14 times (value of UART_NR macro), then all
+amba_ports[] entries will have been leaked and driver probing is no
+longer possible. (To be fair, that can only happen if the DeviceTree
+doesn't contain alias IDs since they cause the same entry to be used for
+a given port.) Fix it.
+
+Fixes: ef2889f7ffee ("serial: pl011: Move uart_register_driver call to device")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: stable@vger.kernel.org # v3.15+
+Cc: Tushar Behera <tushar.behera@linaro.org>
+Link: https://lore.kernel.org/r/138f8c15afb2f184d8102583f8301575566064a6.1597316167.git.lukas@wunner.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/amba-pl011.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -2615,7 +2615,7 @@ static int pl011_setup_port(struct devic
+
+ static int pl011_register_port(struct uart_amba_port *uap)
+ {
+- int ret;
++ int ret, i;
+
+ /* Ensure interrupts from this UART are masked and cleared */
+ pl011_write(0, uap, REG_IMSC);
+@@ -2626,6 +2626,9 @@ static int pl011_register_port(struct ua
+ if (ret < 0) {
+ dev_err(uap->port.dev,
+ "Failed to register AMBA-PL011 driver\n");
++ for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
++ if (amba_ports[i] == uap)
++ amba_ports[i] = NULL;
+ return ret;
+ }
+ }
--- /dev/null
+From 27afac93e3bd7fa89749cf11da5d86ac9cde4dba Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Thu, 13 Aug 2020 12:52:40 +0200
+Subject: serial: pl011: Fix oops on -EPROBE_DEFER
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 27afac93e3bd7fa89749cf11da5d86ac9cde4dba upstream.
+
+If probing of a pl011 gets deferred until after free_initmem(), an oops
+ensues because pl011_console_match() is called which has been freed.
+
+Fix by removing the __init attribute from the function and those it
+calls.
+
+Commit 10879ae5f12e ("serial: pl011: add console matching function")
+introduced pl011_console_match() not just for early consoles but
+regular preferred consoles, such as those added by acpi_parse_spcr().
+Regular consoles may be registered after free_initmem() for various
+reasons, one being deferred probing, another being dynamic enablement
+of serial ports using a DeviceTree overlay.
+
+Thus, pl011_console_match() must not be declared __init and the
+functions it calls mustn't either.
+
+Stack trace for posterity:
+
+Unable to handle kernel paging request at virtual address 80c38b58
+Internal error: Oops: 8000000d [#1] PREEMPT SMP ARM
+PC is at pl011_console_match+0x0/0xfc
+LR is at register_console+0x150/0x468
+[<80187004>] (register_console)
+[<805a8184>] (uart_add_one_port)
+[<805b2b68>] (pl011_register_port)
+[<805b3ce4>] (pl011_probe)
+[<80569214>] (amba_probe)
+[<805ca088>] (really_probe)
+[<805ca2ec>] (driver_probe_device)
+[<805ca5b0>] (__device_attach_driver)
+[<805c8060>] (bus_for_each_drv)
+[<805c9dfc>] (__device_attach)
+[<805ca630>] (device_initial_probe)
+[<805c90a8>] (bus_probe_device)
+[<805c95a8>] (deferred_probe_work_func)
+
+Fixes: 10879ae5f12e ("serial: pl011: add console matching function")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: stable@vger.kernel.org # v4.10+
+Cc: Aleksey Makarov <amakarov@marvell.com>
+Cc: Peter Hurley <peter@hurleysoftware.com>
+Cc: Russell King <linux@armlinux.org.uk>
+Cc: Christopher Covington <cov@codeaurora.org>
+Link: https://lore.kernel.org/r/f827ff09da55b8c57d316a1b008a137677b58921.1597315557.git.lukas@wunner.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/amba-pl011.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -2241,9 +2241,8 @@ pl011_console_write(struct console *co,
+ clk_disable(uap->clk);
+ }
+
+-static void __init
+-pl011_console_get_options(struct uart_amba_port *uap, int *baud,
+- int *parity, int *bits)
++static void pl011_console_get_options(struct uart_amba_port *uap, int *baud,
++ int *parity, int *bits)
+ {
+ if (pl011_read(uap, REG_CR) & UART01x_CR_UARTEN) {
+ unsigned int lcr_h, ibrd, fbrd;
+@@ -2276,7 +2275,7 @@ pl011_console_get_options(struct uart_am
+ }
+ }
+
+-static int __init pl011_console_setup(struct console *co, char *options)
++static int pl011_console_setup(struct console *co, char *options)
+ {
+ struct uart_amba_port *uap;
+ int baud = 38400;
+@@ -2344,8 +2343,8 @@ static int __init pl011_console_setup(st
+ *
+ * Returns 0 if console matches; otherwise non-zero to use default matching
+ */
+-static int __init pl011_console_match(struct console *co, char *name, int idx,
+- char *options)
++static int pl011_console_match(struct console *co, char *name, int idx,
++ char *options)
+ {
+ unsigned char iotype;
+ resource_size_t addr;
--- /dev/null
+From 8c6c378b0cbe0c9f1390986b5f8ffb5f6ff7593b Mon Sep 17 00:00:00 2001
+From: Tamseel Shams <m.shams@samsung.com>
+Date: Mon, 10 Aug 2020 08:30:21 +0530
+Subject: serial: samsung: Removes the IRQ not found warning
+
+From: Tamseel Shams <m.shams@samsung.com>
+
+commit 8c6c378b0cbe0c9f1390986b5f8ffb5f6ff7593b upstream.
+
+In few older Samsung SoCs like s3c2410, s3c2412
+and s3c2440, UART IP is having 2 interrupt lines.
+However, in other SoCs like s3c6400, s5pv210,
+exynos5433, and exynos4210 UART is having only 1
+interrupt line. Due to this, "platform_get_irq(platdev, 1)"
+call in the driver gives the following false-positive error:
+"IRQ index 1 not found" on newer SoC's.
+
+This patch adds the condition to check for Tx interrupt
+only for the those SoC's which have 2 interrupt lines.
+
+Tested-by: Alim Akhtar <alim.akhtar@samsung.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
+Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
+Signed-off-by: Tamseel Shams <m.shams@samsung.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200810030021.45348-1-m.shams@samsung.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/samsung_tty.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/tty/serial/samsung_tty.c
++++ b/drivers/tty/serial/samsung_tty.c
+@@ -1911,9 +1911,11 @@ static int s3c24xx_serial_init_port(stru
+ ourport->tx_irq = ret + 1;
+ }
+
+- ret = platform_get_irq(platdev, 1);
+- if (ret > 0)
+- ourport->tx_irq = ret;
++ if (!s3c24xx_serial_has_interrupt_mask(port)) {
++ ret = platform_get_irq(platdev, 1);
++ if (ret > 0)
++ ourport->tx_irq = ret;
++ }
+ /*
+ * DMA is currently supported only on DT platforms, if DMA properties
+ * are specified.
--- /dev/null
+From fdf16d78941b4f380753053d229955baddd00712 Mon Sep 17 00:00:00 2001
+From: Holger Assmann <h.assmann@pengutronix.de>
+Date: Thu, 13 Aug 2020 17:27:57 +0200
+Subject: serial: stm32: avoid kernel warning on absence of optional IRQ
+
+From: Holger Assmann <h.assmann@pengutronix.de>
+
+commit fdf16d78941b4f380753053d229955baddd00712 upstream.
+
+stm32_init_port() of the stm32-usart may trigger a warning in
+platform_get_irq() when the device tree specifies no wakeup interrupt.
+
+The wakeup interrupt is usually a board-specific GPIO and the driver
+functions correctly in its absence. The mainline stm32mp151.dtsi does
+not specify it, so all mainline device trees trigger an unnecessary
+kernel warning. Use of platform_get_irq_optional() avoids this.
+
+Fixes: 2c58e56096dd ("serial: stm32: fix the get_irq error case")
+Signed-off-by: Holger Assmann <h.assmann@pengutronix.de>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200813152757.32751-1-h.assmann@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/stm32-usart.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/stm32-usart.c
++++ b/drivers/tty/serial/stm32-usart.c
+@@ -962,7 +962,7 @@ static int stm32_init_port(struct stm32_
+ return ret;
+
+ if (stm32port->info->cfg.has_wakeup) {
+- stm32port->wakeirq = platform_get_irq(pdev, 1);
++ stm32port->wakeirq = platform_get_irq_optional(pdev, 1);
+ if (stm32port->wakeirq <= 0 && stm32port->wakeirq != -ENXIO)
+ return stm32port->wakeirq ? : -ENODEV;
+ }
btrfs-fix-space-cache-memory-leak-after-transaction-abort.patch
btrfs-detect-nocow-for-swap-after-snapshot-delete.patch
fbcon-prevent-user-font-height-or-width-change-from-causing-potential-out-of-bounds-access.patch
+usb-lvtest-return-proper-error-code-in-probe.patch
+vt-defer-kfree-of-vc_screenbuf-in-vc_do_resize.patch
+vt_ioctl-change-vt_resizex-ioctl-to-check-for-error-return-from-vc_resize.patch
+serial-samsung-removes-the-irq-not-found-warning.patch
+serial-pl011-fix-oops-on-eprobe_defer.patch
+serial-pl011-don-t-leak-amba_ports-entry-on-driver-register-error.patch
+serial-stm32-avoid-kernel-warning-on-absence-of-optional-irq.patch
+serial-8250_exar-fix-number-of-ports-for-commtech-pcie-cards.patch
+serial-8250-change-lock-order-in-serial8250_do_startup.patch
+io_uring-clear-req-result-on-iopoll-re-issue.patch
+writeback-protect-inode-i_io_list-with-inode-i_lock.patch
+writeback-avoid-skipping-inode-writeback.patch
+writeback-fix-sync-livelock-due-to-b_dirty_time-processing.patch
+xen-uses-irqdesc-irq_data_common-handler_data-to-store-a-per-interrupt-xen-data-pointer-which-contains-xen-specific-information.patch
+usb-renesas-xhci-remove-version-check.patch
+usb-host-xhci-tegra-otg-usb2-usb3-port-init.patch
+usb-host-xhci-tegra-fix-tegra_xusb_get_phy.patch
+usb-host-xhci-fix-ep-context-print-mismatch-in-debugfs.patch
+xhci-do-warm-reset-when-both-cas-and-xdev_resume-are-set.patch
+xhci-always-restore-ep_soft_clear_toggle-even-if-ep-reset-failed.patch
+io-wq-fix-hang-after-cancelling-pending-hashed-work.patch
+kvm-arm64-set-hcr_el2.ptw-to-prevent-at-taking-synchronous-exception.patch
--- /dev/null
+From 0077b1b2c8d9ad5f7a08b62fb8524cdb9938388f Mon Sep 17 00:00:00 2001
+From: Li Jun <jun.li@nxp.com>
+Date: Fri, 21 Aug 2020 12:15:47 +0300
+Subject: usb: host: xhci: fix ep context print mismatch in debugfs
+
+From: Li Jun <jun.li@nxp.com>
+
+commit 0077b1b2c8d9ad5f7a08b62fb8524cdb9938388f upstream.
+
+dci is 0 based and xhci_get_ep_ctx() will do ep index increment to get
+the ep context.
+
+[rename dci to ep_index -Mathias]
+Cc: stable <stable@vger.kernel.org> # v4.15+
+Fixes: 02b6fdc2a153 ("usb: xhci: Add debugfs interface for xHCI driver")
+Signed-off-by: Li Jun <jun.li@nxp.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20200821091549.20556-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-debugfs.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/xhci-debugfs.c
++++ b/drivers/usb/host/xhci-debugfs.c
+@@ -273,7 +273,7 @@ static int xhci_slot_context_show(struct
+
+ static int xhci_endpoint_context_show(struct seq_file *s, void *unused)
+ {
+- int dci;
++ int ep_index;
+ dma_addr_t dma;
+ struct xhci_hcd *xhci;
+ struct xhci_ep_ctx *ep_ctx;
+@@ -282,9 +282,9 @@ static int xhci_endpoint_context_show(st
+
+ xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus));
+
+- for (dci = 1; dci < 32; dci++) {
+- ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, dci);
+- dma = dev->out_ctx->dma + dci * CTX_SIZE(xhci->hcc_params);
++ for (ep_index = 0; ep_index < 31; ep_index++) {
++ ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
++ dma = dev->out_ctx->dma + (ep_index + 1) * CTX_SIZE(xhci->hcc_params);
+ seq_printf(s, "%pad: %s\n", &dma,
+ xhci_decode_ep_context(le32_to_cpu(ep_ctx->ep_info),
+ le32_to_cpu(ep_ctx->ep_info2),
--- /dev/null
+From d54343a87732726b04ac5af873916b5ed4f52932 Mon Sep 17 00:00:00 2001
+From: JC Kuo <jckuo@nvidia.com>
+Date: Tue, 11 Aug 2020 17:25:53 +0800
+Subject: usb: host: xhci-tegra: fix tegra_xusb_get_phy()
+
+From: JC Kuo <jckuo@nvidia.com>
+
+commit d54343a87732726b04ac5af873916b5ed4f52932 upstream.
+
+tegra_xusb_get_phy() should take input argument "name".
+
+Signed-off-by: JC Kuo <jckuo@nvidia.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200811092553.657762-1-jckuo@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-tegra.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-tegra.c
++++ b/drivers/usb/host/xhci-tegra.c
+@@ -1136,7 +1136,7 @@ static struct phy *tegra_xusb_get_phy(st
+ unsigned int i, phy_count = 0;
+
+ for (i = 0; i < tegra->soc->num_types; i++) {
+- if (!strncmp(tegra->soc->phy_types[i].name, "usb2",
++ if (!strncmp(tegra->soc->phy_types[i].name, name,
+ strlen(name)))
+ return tegra->phys[phy_count+port];
+
--- /dev/null
+From 316a2868bc269be8c6e69ccc3a1f902a3f518eb9 Mon Sep 17 00:00:00 2001
+From: JC Kuo <jckuo@nvidia.com>
+Date: Tue, 11 Aug 2020 17:31:43 +0800
+Subject: usb: host: xhci-tegra: otg usb2/usb3 port init
+
+From: JC Kuo <jckuo@nvidia.com>
+
+commit 316a2868bc269be8c6e69ccc3a1f902a3f518eb9 upstream.
+
+tegra_xusb_init_usb_phy() should initialize "otg_usb2_port" and
+"otg_usb3_port" with -EINVAL because "0" is a valid value
+represents usb2 port 0 or usb3 port 0.
+
+Signed-off-by: JC Kuo <jckuo@nvidia.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200811093143.699541-1-jckuo@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-tegra.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/host/xhci-tegra.c
++++ b/drivers/usb/host/xhci-tegra.c
+@@ -1258,6 +1258,8 @@ static int tegra_xusb_init_usb_phy(struc
+
+ INIT_WORK(&tegra->id_work, tegra_xhci_id_work);
+ tegra->id_nb.notifier_call = tegra_xhci_id_notify;
++ tegra->otg_usb2_port = -EINVAL;
++ tegra->otg_usb3_port = -EINVAL;
+
+ for (i = 0; i < tegra->num_usb_phys; i++) {
+ struct phy *phy = tegra_xusb_get_phy(tegra, "usb2", i);
--- /dev/null
+From 531412492ce93ea29b9ca3b4eb5e3ed771f851dd Mon Sep 17 00:00:00 2001
+From: Evgeny Novikov <novikov@ispras.ru>
+Date: Wed, 5 Aug 2020 12:06:43 +0300
+Subject: USB: lvtest: return proper error code in probe
+
+From: Evgeny Novikov <novikov@ispras.ru>
+
+commit 531412492ce93ea29b9ca3b4eb5e3ed771f851dd upstream.
+
+lvs_rh_probe() can return some nonnegative value from usb_control_msg()
+when it is less than "USB_DT_HUB_NONVAR_SIZE + 2" that is considered as
+a failure. Make lvs_rh_probe() return -EINVAL in this case.
+
+Found by Linux Driver Verification project (linuxtesting.org).
+
+Signed-off-by: Evgeny Novikov <novikov@ispras.ru>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200805090643.3432-1-novikov@ispras.ru
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/lvstest.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/lvstest.c
++++ b/drivers/usb/misc/lvstest.c
+@@ -426,7 +426,7 @@ static int lvs_rh_probe(struct usb_inter
+ USB_DT_SS_HUB_SIZE, USB_CTRL_GET_TIMEOUT);
+ if (ret < (USB_DT_HUB_NONVAR_SIZE + 2)) {
+ dev_err(&hdev->dev, "wrong root hub descriptor read %d\n", ret);
+- return ret;
++ return ret < 0 ? ret : -EINVAL;
+ }
+
+ /* submit urb to poll interrupt endpoint */
--- /dev/null
+From d66a57be2f9a315fc10d0f524f670fec903e0fb4 Mon Sep 17 00:00:00 2001
+From: Vinod Koul <vkoul@kernel.org>
+Date: Tue, 18 Aug 2020 12:47:39 +0530
+Subject: usb: renesas-xhci: remove version check
+
+From: Vinod Koul <vkoul@kernel.org>
+
+commit d66a57be2f9a315fc10d0f524f670fec903e0fb4 upstream.
+
+Some devices in wild are reporting bunch of firmware versions, so remove
+the check for versions in driver
+
+Reported by: Anastasios Vacharakis <vacharakis@gmail.com>
+Reported by: Glen Journeay <journeay@gmail.com>
+Fixes: 2478be82de44 ("usb: renesas-xhci: Add ROM loader for uPD720201")
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=208911
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200818071739.789720-1-vkoul@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-pci-renesas.c | 19 +------------------
+ 1 file changed, 1 insertion(+), 18 deletions(-)
+
+--- a/drivers/usb/host/xhci-pci-renesas.c
++++ b/drivers/usb/host/xhci-pci-renesas.c
+@@ -50,20 +50,6 @@
+ #define RENESAS_RETRY 10000
+ #define RENESAS_DELAY 10
+
+-#define ROM_VALID_01 0x2013
+-#define ROM_VALID_02 0x2026
+-
+-static int renesas_verify_fw_version(struct pci_dev *pdev, u32 version)
+-{
+- switch (version) {
+- case ROM_VALID_01:
+- case ROM_VALID_02:
+- return 0;
+- }
+- dev_err(&pdev->dev, "FW has invalid version :%d\n", version);
+- return -EINVAL;
+-}
+-
+ static int renesas_fw_download_image(struct pci_dev *dev,
+ const u32 *fw, size_t step, bool rom)
+ {
+@@ -202,10 +188,7 @@ static int renesas_check_rom_state(struc
+
+ version &= RENESAS_FW_VERSION_FIELD;
+ version = version >> RENESAS_FW_VERSION_OFFSET;
+-
+- err = renesas_verify_fw_version(pdev, version);
+- if (err)
+- return err;
++ dev_dbg(&pdev->dev, "Found ROM version: %x\n", version);
+
+ /*
+ * Test if ROM is present and loaded, if so we can skip everything
--- /dev/null
+From f8d1653daec02315e06d30246cff4af72e76e54e Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Wed, 29 Jul 2020 23:57:01 +0900
+Subject: vt: defer kfree() of vc_screenbuf in vc_do_resize()
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit f8d1653daec02315e06d30246cff4af72e76e54e upstream.
+
+syzbot is reporting UAF bug in set_origin() from vc_do_resize() [1], for
+vc_do_resize() calls kfree(vc->vc_screenbuf) before calling set_origin().
+
+Unfortunately, in set_origin(), vc->vc_sw->con_set_origin() might access
+vc->vc_pos when scroll is involved in order to manipulate cursor, but
+vc->vc_pos refers already released vc->vc_screenbuf until vc->vc_pos gets
+updated based on the result of vc->vc_sw->con_set_origin().
+
+Preserving old buffer and tolerating outdated vc members until set_origin()
+completes would be easier than preventing vc->vc_sw->con_set_origin() from
+accessing outdated vc members.
+
+[1] https://syzkaller.appspot.com/bug?id=6649da2081e2ebdc65c0642c214b27fe91099db3
+
+Reported-by: syzbot <syzbot+9116ecc1978ca3a12f43@syzkaller.appspotmail.com>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/1596034621-4714-1-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/vt/vt.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -1196,7 +1196,7 @@ static int vc_do_resize(struct tty_struc
+ unsigned int old_rows, old_row_size, first_copied_row;
+ unsigned int new_cols, new_rows, new_row_size, new_screen_size;
+ unsigned int user;
+- unsigned short *newscreen;
++ unsigned short *oldscreen, *newscreen;
+ struct uni_screen *new_uniscr = NULL;
+
+ WARN_CONSOLE_UNLOCKED();
+@@ -1294,10 +1294,11 @@ static int vc_do_resize(struct tty_struc
+ if (new_scr_end > new_origin)
+ scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
+ new_scr_end - new_origin);
+- kfree(vc->vc_screenbuf);
++ oldscreen = vc->vc_screenbuf;
+ vc->vc_screenbuf = newscreen;
+ vc->vc_screenbuf_size = new_screen_size;
+ set_origin(vc);
++ kfree(oldscreen);
+
+ /* do part of a reset_terminal() */
+ vc->vc_top = 0;
--- /dev/null
+From bc5269ca765057a1b762e79a1cfd267cd7bf1c46 Mon Sep 17 00:00:00 2001
+From: George Kennedy <george.kennedy@oracle.com>
+Date: Fri, 31 Jul 2020 12:33:12 -0400
+Subject: vt_ioctl: change VT_RESIZEX ioctl to check for error return from vc_resize()
+
+From: George Kennedy <george.kennedy@oracle.com>
+
+commit bc5269ca765057a1b762e79a1cfd267cd7bf1c46 upstream.
+
+vc_resize() can return with an error after failure. Change VT_RESIZEX ioctl
+to save struct vc_data values that are modified and restore the original
+values in case of error.
+
+Signed-off-by: George Kennedy <george.kennedy@oracle.com>
+Cc: stable <stable@vger.kernel.org>
+Reported-by: syzbot+38a3699c7eaf165b97a6@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/r/1596213192-6635-2-git-send-email-george.kennedy@oracle.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/vt/vt_ioctl.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/tty/vt/vt_ioctl.c
++++ b/drivers/tty/vt/vt_ioctl.c
+@@ -893,12 +893,22 @@ int vt_ioctl(struct tty_struct *tty,
+ console_lock();
+ vcp = vc_cons[i].d;
+ if (vcp) {
++ int ret;
++ int save_scan_lines = vcp->vc_scan_lines;
++ int save_font_height = vcp->vc_font.height;
++
+ if (v.v_vlin)
+ vcp->vc_scan_lines = v.v_vlin;
+ if (v.v_clin)
+ vcp->vc_font.height = v.v_clin;
+ vcp->vc_resize_user = 1;
+- vc_resize(vcp, v.v_cols, v.v_rows);
++ ret = vc_resize(vcp, v.v_cols, v.v_rows);
++ if (ret) {
++ vcp->vc_scan_lines = save_scan_lines;
++ vcp->vc_font.height = save_font_height;
++ console_unlock();
++ return ret;
++ }
+ }
+ console_unlock();
+ }
--- /dev/null
+From 5afced3bf28100d81fb2fe7e98918632a08feaf5 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Fri, 29 May 2020 15:05:22 +0200
+Subject: writeback: Avoid skipping inode writeback
+
+From: Jan Kara <jack@suse.cz>
+
+commit 5afced3bf28100d81fb2fe7e98918632a08feaf5 upstream.
+
+Inode's i_io_list list head is used to attach inode to several different
+lists - wb->{b_dirty, b_dirty_time, b_io, b_more_io}. When flush worker
+prepares a list of inodes to writeback e.g. for sync(2), it moves inodes
+to b_io list. Thus it is critical for sync(2) data integrity guarantees
+that inode is not requeued to any other writeback list when inode is
+queued for processing by flush worker. That's the reason why
+writeback_single_inode() does not touch i_io_list (unless the inode is
+completely clean) and why __mark_inode_dirty() does not touch i_io_list
+if I_SYNC flag is set.
+
+However there are two flaws in the current logic:
+
+1) When inode has only I_DIRTY_TIME set but it is already queued in b_io
+list due to sync(2), concurrent __mark_inode_dirty(inode, I_DIRTY_SYNC)
+can still move inode back to b_dirty list resulting in skipping
+writeback of inode time stamps during sync(2).
+
+2) When inode is on b_dirty_time list and writeback_single_inode() races
+with __mark_inode_dirty() like:
+
+writeback_single_inode() __mark_inode_dirty(inode, I_DIRTY_PAGES)
+ inode->i_state |= I_SYNC
+ __writeback_single_inode()
+ inode->i_state |= I_DIRTY_PAGES;
+ if (inode->i_state & I_SYNC)
+ bail
+ if (!(inode->i_state & I_DIRTY_ALL))
+ - not true so nothing done
+
+We end up with I_DIRTY_PAGES inode on b_dirty_time list and thus
+standard background writeback will not writeback this inode leading to
+possible dirty throttling stalls etc. (thanks to Martijn Coenen for this
+analysis).
+
+Fix these problems by tracking whether inode is queued in b_io or
+b_more_io lists in a new I_SYNC_QUEUED flag. When this flag is set, we
+know flush worker has queued inode and we should not touch i_io_list.
+On the other hand we also know that once flush worker is done with the
+inode it will requeue the inode to appropriate dirty list. When
+I_SYNC_QUEUED is not set, __mark_inode_dirty() can (and must) move inode
+to appropriate dirty list.
+
+Reported-by: Martijn Coenen <maco@android.com>
+Reviewed-by: Martijn Coenen <maco@android.com>
+Tested-by: Martijn Coenen <maco@android.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Fixes: 0ae45f63d4ef ("vfs: add support for a lazytime mount option")
+CC: stable@vger.kernel.org
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fs-writeback.c | 17 ++++++++++++-----
+ include/linux/fs.h | 8 ++++++--
+ 2 files changed, 18 insertions(+), 7 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -146,6 +146,7 @@ static void inode_io_list_del_locked(str
+ assert_spin_locked(&wb->list_lock);
+ assert_spin_locked(&inode->i_lock);
+
++ inode->i_state &= ~I_SYNC_QUEUED;
+ list_del_init(&inode->i_io_list);
+ wb_io_lists_depopulated(wb);
+ }
+@@ -1187,6 +1188,7 @@ static void redirty_tail_locked(struct i
+ inode->dirtied_when = jiffies;
+ }
+ inode_io_list_move_locked(inode, wb, &wb->b_dirty);
++ inode->i_state &= ~I_SYNC_QUEUED;
+ }
+
+ static void redirty_tail(struct inode *inode, struct bdi_writeback *wb)
+@@ -1262,8 +1264,11 @@ static int move_expired_inodes(struct li
+ break;
+ list_move(&inode->i_io_list, &tmp);
+ moved++;
++ spin_lock(&inode->i_lock);
+ if (flags & EXPIRE_DIRTY_ATIME)
+- set_bit(__I_DIRTY_TIME_EXPIRED, &inode->i_state);
++ inode->i_state |= I_DIRTY_TIME_EXPIRED;
++ inode->i_state |= I_SYNC_QUEUED;
++ spin_unlock(&inode->i_lock);
+ if (sb_is_blkdev_sb(inode->i_sb))
+ continue;
+ if (sb && sb != inode->i_sb)
+@@ -1438,6 +1443,7 @@ static void requeue_inode(struct inode *
+ } else if (inode->i_state & I_DIRTY_TIME) {
+ inode->dirtied_when = jiffies;
+ inode_io_list_move_locked(inode, wb, &wb->b_dirty_time);
++ inode->i_state &= ~I_SYNC_QUEUED;
+ } else {
+ /* The inode is clean. Remove from writeback lists. */
+ inode_io_list_del_locked(inode, wb);
+@@ -2301,11 +2307,12 @@ void __mark_inode_dirty(struct inode *in
+ inode->i_state |= flags;
+
+ /*
+- * If the inode is being synced, just update its dirty state.
+- * The unlocker will place the inode on the appropriate
+- * superblock list, based upon its state.
++ * If the inode is queued for writeback by flush worker, just
++ * update its dirty state. Once the flush worker is done with
++ * the inode it will place it on the appropriate superblock
++ * list, based upon its state.
+ */
+- if (inode->i_state & I_SYNC)
++ if (inode->i_state & I_SYNC_QUEUED)
+ goto out_unlock_inode;
+
+ /*
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -2168,6 +2168,10 @@ static inline void kiocb_clone(struct ki
+ *
+ * I_DONTCACHE Evict inode as soon as it is not used anymore.
+ *
++ * I_SYNC_QUEUED Inode is queued in b_io or b_more_io writeback lists.
++ * Used to detect that mark_inode_dirty() should not move
++ * inode between dirty lists.
++ *
+ * Q: What is the difference between I_WILL_FREE and I_FREEING?
+ */
+ #define I_DIRTY_SYNC (1 << 0)
+@@ -2185,12 +2189,12 @@ static inline void kiocb_clone(struct ki
+ #define I_DIO_WAKEUP (1 << __I_DIO_WAKEUP)
+ #define I_LINKABLE (1 << 10)
+ #define I_DIRTY_TIME (1 << 11)
+-#define __I_DIRTY_TIME_EXPIRED 12
+-#define I_DIRTY_TIME_EXPIRED (1 << __I_DIRTY_TIME_EXPIRED)
++#define I_DIRTY_TIME_EXPIRED (1 << 12)
+ #define I_WB_SWITCH (1 << 13)
+ #define I_OVL_INUSE (1 << 14)
+ #define I_CREATING (1 << 15)
+ #define I_DONTCACHE (1 << 16)
++#define I_SYNC_QUEUED (1 << 17)
+
+ #define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
+ #define I_DIRTY (I_DIRTY_INODE | I_DIRTY_PAGES)
--- /dev/null
+From f9cae926f35e8230330f28c7b743ad088611a8de Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Fri, 29 May 2020 16:08:58 +0200
+Subject: writeback: Fix sync livelock due to b_dirty_time processing
+
+From: Jan Kara <jack@suse.cz>
+
+commit f9cae926f35e8230330f28c7b743ad088611a8de upstream.
+
+When we are processing writeback for sync(2), move_expired_inodes()
+didn't set any inode expiry value (older_than_this). This can result in
+writeback never completing if there's steady stream of inodes added to
+b_dirty_time list as writeback rechecks dirty lists after each writeback
+round whether there's more work to be done. Fix the problem by using
+sync(2) start time is inode expiry value when processing b_dirty_time
+list similarly as for ordinarily dirtied inodes. This requires some
+refactoring of older_than_this handling which simplifies the code
+noticeably as a bonus.
+
+Fixes: 0ae45f63d4ef ("vfs: add support for a lazytime mount option")
+CC: stable@vger.kernel.org
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fs-writeback.c | 44 +++++++++++++++------------------------
+ include/trace/events/writeback.h | 13 +++++------
+ 2 files changed, 23 insertions(+), 34 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -42,7 +42,6 @@
+ struct wb_writeback_work {
+ long nr_pages;
+ struct super_block *sb;
+- unsigned long *older_than_this;
+ enum writeback_sync_modes sync_mode;
+ unsigned int tagged_writepages:1;
+ unsigned int for_kupdate:1;
+@@ -1234,16 +1233,13 @@ static bool inode_dirtied_after(struct i
+ #define EXPIRE_DIRTY_ATIME 0x0001
+
+ /*
+- * Move expired (dirtied before work->older_than_this) dirty inodes from
++ * Move expired (dirtied before dirtied_before) dirty inodes from
+ * @delaying_queue to @dispatch_queue.
+ */
+ static int move_expired_inodes(struct list_head *delaying_queue,
+ struct list_head *dispatch_queue,
+- int flags,
+- struct wb_writeback_work *work)
++ int flags, unsigned long dirtied_before)
+ {
+- unsigned long *older_than_this = NULL;
+- unsigned long expire_time;
+ LIST_HEAD(tmp);
+ struct list_head *pos, *node;
+ struct super_block *sb = NULL;
+@@ -1251,16 +1247,9 @@ static int move_expired_inodes(struct li
+ int do_sb_sort = 0;
+ int moved = 0;
+
+- if ((flags & EXPIRE_DIRTY_ATIME) == 0)
+- older_than_this = work->older_than_this;
+- else if (!work->for_sync) {
+- expire_time = jiffies - (dirtytime_expire_interval * HZ);
+- older_than_this = &expire_time;
+- }
+ while (!list_empty(delaying_queue)) {
+ inode = wb_inode(delaying_queue->prev);
+- if (older_than_this &&
+- inode_dirtied_after(inode, *older_than_this))
++ if (inode_dirtied_after(inode, dirtied_before))
+ break;
+ list_move(&inode->i_io_list, &tmp);
+ moved++;
+@@ -1306,18 +1295,22 @@ out:
+ * |
+ * +--> dequeue for IO
+ */
+-static void queue_io(struct bdi_writeback *wb, struct wb_writeback_work *work)
++static void queue_io(struct bdi_writeback *wb, struct wb_writeback_work *work,
++ unsigned long dirtied_before)
+ {
+ int moved;
++ unsigned long time_expire_jif = dirtied_before;
+
+ assert_spin_locked(&wb->list_lock);
+ list_splice_init(&wb->b_more_io, &wb->b_io);
+- moved = move_expired_inodes(&wb->b_dirty, &wb->b_io, 0, work);
++ moved = move_expired_inodes(&wb->b_dirty, &wb->b_io, 0, dirtied_before);
++ if (!work->for_sync)
++ time_expire_jif = jiffies - dirtytime_expire_interval * HZ;
+ moved += move_expired_inodes(&wb->b_dirty_time, &wb->b_io,
+- EXPIRE_DIRTY_ATIME, work);
++ EXPIRE_DIRTY_ATIME, time_expire_jif);
+ if (moved)
+ wb_io_lists_populated(wb);
+- trace_writeback_queue_io(wb, work, moved);
++ trace_writeback_queue_io(wb, work, dirtied_before, moved);
+ }
+
+ static int write_inode(struct inode *inode, struct writeback_control *wbc)
+@@ -1829,7 +1822,7 @@ static long writeback_inodes_wb(struct b
+ blk_start_plug(&plug);
+ spin_lock(&wb->list_lock);
+ if (list_empty(&wb->b_io))
+- queue_io(wb, &work);
++ queue_io(wb, &work, jiffies);
+ __writeback_inodes_wb(wb, &work);
+ spin_unlock(&wb->list_lock);
+ blk_finish_plug(&plug);
+@@ -1849,7 +1842,7 @@ static long writeback_inodes_wb(struct b
+ * takes longer than a dirty_writeback_interval interval, then leave a
+ * one-second gap.
+ *
+- * older_than_this takes precedence over nr_to_write. So we'll only write back
++ * dirtied_before takes precedence over nr_to_write. So we'll only write back
+ * all dirty pages if they are all attached to "old" mappings.
+ */
+ static long wb_writeback(struct bdi_writeback *wb,
+@@ -1857,14 +1850,11 @@ static long wb_writeback(struct bdi_writ
+ {
+ unsigned long wb_start = jiffies;
+ long nr_pages = work->nr_pages;
+- unsigned long oldest_jif;
++ unsigned long dirtied_before = jiffies;
+ struct inode *inode;
+ long progress;
+ struct blk_plug plug;
+
+- oldest_jif = jiffies;
+- work->older_than_this = &oldest_jif;
+-
+ blk_start_plug(&plug);
+ spin_lock(&wb->list_lock);
+ for (;;) {
+@@ -1898,14 +1888,14 @@ static long wb_writeback(struct bdi_writ
+ * safe.
+ */
+ if (work->for_kupdate) {
+- oldest_jif = jiffies -
++ dirtied_before = jiffies -
+ msecs_to_jiffies(dirty_expire_interval * 10);
+ } else if (work->for_background)
+- oldest_jif = jiffies;
++ dirtied_before = jiffies;
+
+ trace_writeback_start(wb, work);
+ if (list_empty(&wb->b_io))
+- queue_io(wb, work);
++ queue_io(wb, work, dirtied_before);
+ if (work->sb)
+ progress = writeback_sb_inodes(work->sb, wb, work);
+ else
+--- a/include/trace/events/writeback.h
++++ b/include/trace/events/writeback.h
+@@ -498,8 +498,9 @@ DEFINE_WBC_EVENT(wbc_writepage);
+ TRACE_EVENT(writeback_queue_io,
+ TP_PROTO(struct bdi_writeback *wb,
+ struct wb_writeback_work *work,
++ unsigned long dirtied_before,
+ int moved),
+- TP_ARGS(wb, work, moved),
++ TP_ARGS(wb, work, dirtied_before, moved),
+ TP_STRUCT__entry(
+ __array(char, name, 32)
+ __field(unsigned long, older)
+@@ -509,19 +510,17 @@ TRACE_EVENT(writeback_queue_io,
+ __field(ino_t, cgroup_ino)
+ ),
+ TP_fast_assign(
+- unsigned long *older_than_this = work->older_than_this;
+ strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32);
+- __entry->older = older_than_this ? *older_than_this : 0;
+- __entry->age = older_than_this ?
+- (jiffies - *older_than_this) * 1000 / HZ : -1;
++ __entry->older = dirtied_before;
++ __entry->age = (jiffies - dirtied_before) * 1000 / HZ;
+ __entry->moved = moved;
+ __entry->reason = work->reason;
+ __entry->cgroup_ino = __trace_wb_assign_cgroup(wb);
+ ),
+ TP_printk("bdi %s: older=%lu age=%ld enqueue=%d reason=%s cgroup_ino=%lu",
+ __entry->name,
+- __entry->older, /* older_than_this in jiffies */
+- __entry->age, /* older_than_this in relative milliseconds */
++ __entry->older, /* dirtied_before in jiffies */
++ __entry->age, /* dirtied_before in relative milliseconds */
+ __entry->moved,
+ __print_symbolic(__entry->reason, WB_WORK_REASON),
+ (unsigned long)__entry->cgroup_ino
--- /dev/null
+From b35250c0816c7cf7d0a8de92f5fafb6a7508a708 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 10 Jun 2020 17:36:03 +0200
+Subject: writeback: Protect inode->i_io_list with inode->i_lock
+
+From: Jan Kara <jack@suse.cz>
+
+commit b35250c0816c7cf7d0a8de92f5fafb6a7508a708 upstream.
+
+Currently, operations on inode->i_io_list are protected by
+wb->list_lock. In the following patches we'll need to maintain
+consistency between inode->i_state and inode->i_io_list so change the
+code so that inode->i_lock protects also all inode's i_io_list handling.
+
+Reviewed-by: Martijn Coenen <maco@android.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+CC: stable@vger.kernel.org # Prerequisite for "writeback: Avoid skipping inode writeback"
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fs-writeback.c | 22 +++++++++++++++++-----
+ 1 file changed, 17 insertions(+), 5 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -144,6 +144,7 @@ static void inode_io_list_del_locked(str
+ struct bdi_writeback *wb)
+ {
+ assert_spin_locked(&wb->list_lock);
++ assert_spin_locked(&inode->i_lock);
+
+ list_del_init(&inode->i_io_list);
+ wb_io_lists_depopulated(wb);
+@@ -1122,7 +1123,9 @@ void inode_io_list_del(struct inode *ino
+ struct bdi_writeback *wb;
+
+ wb = inode_to_wb_and_lock_list(inode);
++ spin_lock(&inode->i_lock);
+ inode_io_list_del_locked(inode, wb);
++ spin_unlock(&inode->i_lock);
+ spin_unlock(&wb->list_lock);
+ }
+ EXPORT_SYMBOL(inode_io_list_del);
+@@ -1172,8 +1175,10 @@ void sb_clear_inode_writeback(struct ino
+ * the case then the inode must have been redirtied while it was being written
+ * out and we don't reset its dirtied_when.
+ */
+-static void redirty_tail(struct inode *inode, struct bdi_writeback *wb)
++static void redirty_tail_locked(struct inode *inode, struct bdi_writeback *wb)
+ {
++ assert_spin_locked(&inode->i_lock);
++
+ if (!list_empty(&wb->b_dirty)) {
+ struct inode *tail;
+
+@@ -1184,6 +1189,13 @@ static void redirty_tail(struct inode *i
+ inode_io_list_move_locked(inode, wb, &wb->b_dirty);
+ }
+
++static void redirty_tail(struct inode *inode, struct bdi_writeback *wb)
++{
++ spin_lock(&inode->i_lock);
++ redirty_tail_locked(inode, wb);
++ spin_unlock(&inode->i_lock);
++}
++
+ /*
+ * requeue inode for re-scanning after bdi->b_io list is exhausted.
+ */
+@@ -1394,7 +1406,7 @@ static void requeue_inode(struct inode *
+ * writeback is not making progress due to locked
+ * buffers. Skip this inode for now.
+ */
+- redirty_tail(inode, wb);
++ redirty_tail_locked(inode, wb);
+ return;
+ }
+
+@@ -1414,7 +1426,7 @@ static void requeue_inode(struct inode *
+ * retrying writeback of the dirty page/inode
+ * that cannot be performed immediately.
+ */
+- redirty_tail(inode, wb);
++ redirty_tail_locked(inode, wb);
+ }
+ } else if (inode->i_state & I_DIRTY) {
+ /*
+@@ -1422,7 +1434,7 @@ static void requeue_inode(struct inode *
+ * such as delayed allocation during submission or metadata
+ * updates after data IO completion.
+ */
+- redirty_tail(inode, wb);
++ redirty_tail_locked(inode, wb);
+ } else if (inode->i_state & I_DIRTY_TIME) {
+ inode->dirtied_when = jiffies;
+ inode_io_list_move_locked(inode, wb, &wb->b_dirty_time);
+@@ -1669,8 +1681,8 @@ static long writeback_sb_inodes(struct s
+ */
+ spin_lock(&inode->i_lock);
+ if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE)) {
++ redirty_tail_locked(inode, wb);
+ spin_unlock(&inode->i_lock);
+- redirty_tail(inode, wb);
+ continue;
+ }
+ if ((inode->i_state & I_SYNC) && wbc.sync_mode != WB_SYNC_ALL) {
--- /dev/null
+From c330fb1ddc0a922f044989492b7fcca77ee1db46 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 25 Aug 2020 17:22:58 +0200
+Subject: XEN uses irqdesc::irq_data_common::handler_data to store a per interrupt XEN data pointer which contains XEN specific information.
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit c330fb1ddc0a922f044989492b7fcca77ee1db46 upstream.
+
+handler data is meant for interrupt handlers and not for storing irq chip
+specific information as some devices require handler data to store internal
+per interrupt information, e.g. pinctrl/GPIO chained interrupt handlers.
+
+This obviously creates a conflict of interests and crashes the machine
+because the XEN pointer is overwritten by the driver pointer.
+
+As the XEN data is not handler specific it should be stored in
+irqdesc::irq_data::chip_data instead.
+
+A simple sed s/irq_[sg]et_handler_data/irq_[sg]et_chip_data/ cures that.
+
+Cc: stable@vger.kernel.org
+Reported-by: Roman Shaposhnik <roman@zededa.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Roman Shaposhnik <roman@zededa.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://lore.kernel.org/r/87lfi2yckt.fsf@nanos.tec.linutronix.de
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/xen/events/events_base.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/xen/events/events_base.c
++++ b/drivers/xen/events/events_base.c
+@@ -156,7 +156,7 @@ int get_evtchn_to_irq(evtchn_port_t evtc
+ /* Get info for IRQ */
+ struct irq_info *info_for_irq(unsigned irq)
+ {
+- return irq_get_handler_data(irq);
++ return irq_get_chip_data(irq);
+ }
+
+ /* Constructors for packed IRQ information. */
+@@ -377,7 +377,7 @@ static void xen_irq_init(unsigned irq)
+ info->type = IRQT_UNBOUND;
+ info->refcnt = -1;
+
+- irq_set_handler_data(irq, info);
++ irq_set_chip_data(irq, info);
+
+ list_add_tail(&info->list, &xen_irq_list_head);
+ }
+@@ -426,14 +426,14 @@ static int __must_check xen_allocate_irq
+
+ static void xen_free_irq(unsigned irq)
+ {
+- struct irq_info *info = irq_get_handler_data(irq);
++ struct irq_info *info = irq_get_chip_data(irq);
+
+ if (WARN_ON(!info))
+ return;
+
+ list_del(&info->list);
+
+- irq_set_handler_data(irq, NULL);
++ irq_set_chip_data(irq, NULL);
+
+ WARN_ON(info->refcnt > 0);
+
+@@ -603,7 +603,7 @@ EXPORT_SYMBOL_GPL(xen_irq_from_gsi);
+ static void __unbind_from_irq(unsigned int irq)
+ {
+ evtchn_port_t evtchn = evtchn_from_irq(irq);
+- struct irq_info *info = irq_get_handler_data(irq);
++ struct irq_info *info = irq_get_chip_data(irq);
+
+ if (info->refcnt > 0) {
+ info->refcnt--;
+@@ -1108,7 +1108,7 @@ int bind_ipi_to_irqhandler(enum ipi_vect
+
+ void unbind_from_irqhandler(unsigned int irq, void *dev_id)
+ {
+- struct irq_info *info = irq_get_handler_data(irq);
++ struct irq_info *info = irq_get_chip_data(irq);
+
+ if (WARN_ON(!info))
+ return;
+@@ -1142,7 +1142,7 @@ int evtchn_make_refcounted(evtchn_port_t
+ if (irq == -1)
+ return -ENOENT;
+
+- info = irq_get_handler_data(irq);
++ info = irq_get_chip_data(irq);
+
+ if (!info)
+ return -ENOENT;
+@@ -1170,7 +1170,7 @@ int evtchn_get(evtchn_port_t evtchn)
+ if (irq == -1)
+ goto done;
+
+- info = irq_get_handler_data(irq);
++ info = irq_get_chip_data(irq);
+
+ if (!info)
+ goto done;
--- /dev/null
+From f1ec7ae6c9f8c016db320e204cb519a1da1581b8 Mon Sep 17 00:00:00 2001
+From: Ding Hui <dinghui@sangfor.com.cn>
+Date: Fri, 21 Aug 2020 12:15:49 +0300
+Subject: xhci: Always restore EP_SOFT_CLEAR_TOGGLE even if ep reset failed
+
+From: Ding Hui <dinghui@sangfor.com.cn>
+
+commit f1ec7ae6c9f8c016db320e204cb519a1da1581b8 upstream.
+
+Some device drivers call libusb_clear_halt when target ep queue
+is not empty. (eg. spice client connected to qemu for usb redir)
+
+Before commit f5249461b504 ("xhci: Clear the host side toggle
+manually when endpoint is soft reset"), that works well.
+But now, we got the error log:
+
+ EP not empty, refuse reset
+
+xhci_endpoint_reset failed and left ep_state's EP_SOFT_CLEAR_TOGGLE
+bit still set
+
+So all the subsequent urb sumbits to the ep will fail with the
+warn log:
+
+ Can't enqueue URB while manually clearing toggle
+
+We need to clear ep_state EP_SOFT_CLEAR_TOGGLE bit after
+xhci_endpoint_reset, even if it failed.
+
+Fixes: f5249461b504 ("xhci: Clear the host side toggle manually when endpoint is soft reset")
+Cc: stable <stable@vger.kernel.org> # v4.17+
+Signed-off-by: Ding Hui <dinghui@sangfor.com.cn>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20200821091549.20556-4-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -3236,10 +3236,11 @@ static void xhci_endpoint_reset(struct u
+
+ wait_for_completion(cfg_cmd->completion);
+
+- ep->ep_state &= ~EP_SOFT_CLEAR_TOGGLE;
+ xhci_free_command(xhci, cfg_cmd);
+ cleanup:
+ xhci_free_command(xhci, stop_cmd);
++ if (ep->ep_state & EP_SOFT_CLEAR_TOGGLE)
++ ep->ep_state &= ~EP_SOFT_CLEAR_TOGGLE;
+ }
+
+ static int xhci_check_streams_endpoint(struct xhci_hcd *xhci,
--- /dev/null
+From 904df64a5f4d5ebd670801d869ca0a6d6a6e8df6 Mon Sep 17 00:00:00 2001
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Date: Fri, 21 Aug 2020 12:15:48 +0300
+Subject: xhci: Do warm-reset when both CAS and XDEV_RESUME are set
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+commit 904df64a5f4d5ebd670801d869ca0a6d6a6e8df6 upstream.
+
+Sometimes re-plugging a USB device during system sleep renders the device
+useless:
+[ 173.418345] xhci_hcd 0000:00:14.0: Get port status 2-4 read: 0x14203e2, return 0x10262
+...
+[ 176.496485] usb 2-4: Waited 2000ms for CONNECT
+[ 176.496781] usb usb2-port4: status 0000.0262 after resume, -19
+[ 176.497103] usb 2-4: can't resume, status -19
+[ 176.497438] usb usb2-port4: logical disconnect
+
+Because PLS equals to XDEV_RESUME, xHCI driver reports U3 to usbcore,
+despite of CAS bit is flagged.
+
+So proritize CAS over XDEV_RESUME to let usbcore handle warm-reset for
+the port.
+
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20200821091549.20556-3-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-hub.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -740,15 +740,6 @@ static void xhci_hub_report_usb3_link_st
+ {
+ u32 pls = status_reg & PORT_PLS_MASK;
+
+- /* resume state is a xHCI internal state.
+- * Do not report it to usb core, instead, pretend to be U3,
+- * thus usb core knows it's not ready for transfer
+- */
+- if (pls == XDEV_RESUME) {
+- *status |= USB_SS_PORT_LS_U3;
+- return;
+- }
+-
+ /* When the CAS bit is set then warm reset
+ * should be performed on port
+ */
+@@ -771,6 +762,16 @@ static void xhci_hub_report_usb3_link_st
+ pls |= USB_PORT_STAT_CONNECTION;
+ } else {
+ /*
++ * Resume state is an xHCI internal state. Do not report it to
++ * usb core, instead, pretend to be U3, thus usb core knows
++ * it's not ready for transfer.
++ */
++ if (pls == XDEV_RESUME) {
++ *status |= USB_SS_PORT_LS_U3;
++ return;
++ }
++
++ /*
+ * If CAS bit isn't set but the Port is already at
+ * Compliance Mode, fake a connection so the USB core
+ * notices the Compliance state and resets the port.