]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.8-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 31 Aug 2020 10:33:08 +0000 (12:33 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 31 Aug 2020 10:33:08 +0000 (12:33 +0200)
added patches:
io-wq-fix-hang-after-cancelling-pending-hashed-work.patch
io_uring-clear-req-result-on-iopoll-re-issue.patch
kvm-arm64-set-hcr_el2.ptw-to-prevent-at-taking-synchronous-exception.patch
serial-8250-change-lock-order-in-serial8250_do_startup.patch
serial-8250_exar-fix-number-of-ports-for-commtech-pcie-cards.patch
serial-pl011-don-t-leak-amba_ports-entry-on-driver-register-error.patch
serial-pl011-fix-oops-on-eprobe_defer.patch
serial-samsung-removes-the-irq-not-found-warning.patch
serial-stm32-avoid-kernel-warning-on-absence-of-optional-irq.patch
usb-host-xhci-fix-ep-context-print-mismatch-in-debugfs.patch
usb-host-xhci-tegra-fix-tegra_xusb_get_phy.patch
usb-host-xhci-tegra-otg-usb2-usb3-port-init.patch
usb-lvtest-return-proper-error-code-in-probe.patch
usb-renesas-xhci-remove-version-check.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
writeback-avoid-skipping-inode-writeback.patch
writeback-fix-sync-livelock-due-to-b_dirty_time-processing.patch
writeback-protect-inode-i_io_list-with-inode-i_lock.patch
xen-uses-irqdesc-irq_data_common-handler_data-to-store-a-per-interrupt-xen-data-pointer-which-contains-xen-specific-information.patch
xhci-always-restore-ep_soft_clear_toggle-even-if-ep-reset-failed.patch
xhci-do-warm-reset-when-both-cas-and-xdev_resume-are-set.patch

23 files changed:
queue-5.8/io-wq-fix-hang-after-cancelling-pending-hashed-work.patch [new file with mode: 0644]
queue-5.8/io_uring-clear-req-result-on-iopoll-re-issue.patch [new file with mode: 0644]
queue-5.8/kvm-arm64-set-hcr_el2.ptw-to-prevent-at-taking-synchronous-exception.patch [new file with mode: 0644]
queue-5.8/serial-8250-change-lock-order-in-serial8250_do_startup.patch [new file with mode: 0644]
queue-5.8/serial-8250_exar-fix-number-of-ports-for-commtech-pcie-cards.patch [new file with mode: 0644]
queue-5.8/serial-pl011-don-t-leak-amba_ports-entry-on-driver-register-error.patch [new file with mode: 0644]
queue-5.8/serial-pl011-fix-oops-on-eprobe_defer.patch [new file with mode: 0644]
queue-5.8/serial-samsung-removes-the-irq-not-found-warning.patch [new file with mode: 0644]
queue-5.8/serial-stm32-avoid-kernel-warning-on-absence-of-optional-irq.patch [new file with mode: 0644]
queue-5.8/series
queue-5.8/usb-host-xhci-fix-ep-context-print-mismatch-in-debugfs.patch [new file with mode: 0644]
queue-5.8/usb-host-xhci-tegra-fix-tegra_xusb_get_phy.patch [new file with mode: 0644]
queue-5.8/usb-host-xhci-tegra-otg-usb2-usb3-port-init.patch [new file with mode: 0644]
queue-5.8/usb-lvtest-return-proper-error-code-in-probe.patch [new file with mode: 0644]
queue-5.8/usb-renesas-xhci-remove-version-check.patch [new file with mode: 0644]
queue-5.8/vt-defer-kfree-of-vc_screenbuf-in-vc_do_resize.patch [new file with mode: 0644]
queue-5.8/vt_ioctl-change-vt_resizex-ioctl-to-check-for-error-return-from-vc_resize.patch [new file with mode: 0644]
queue-5.8/writeback-avoid-skipping-inode-writeback.patch [new file with mode: 0644]
queue-5.8/writeback-fix-sync-livelock-due-to-b_dirty_time-processing.patch [new file with mode: 0644]
queue-5.8/writeback-protect-inode-i_io_list-with-inode-i_lock.patch [new file with mode: 0644]
queue-5.8/xen-uses-irqdesc-irq_data_common-handler_data-to-store-a-per-interrupt-xen-data-pointer-which-contains-xen-specific-information.patch [new file with mode: 0644]
queue-5.8/xhci-always-restore-ep_soft_clear_toggle-even-if-ep-reset-failed.patch [new file with mode: 0644]
queue-5.8/xhci-do-warm-reset-when-both-cas-and-xdev_resume-are-set.patch [new file with mode: 0644]

diff --git a/queue-5.8/io-wq-fix-hang-after-cancelling-pending-hashed-work.patch b/queue-5.8/io-wq-fix-hang-after-cancelling-pending-hashed-work.patch
new file mode 100644 (file)
index 0000000..c76ded2
--- /dev/null
@@ -0,0 +1,60 @@
+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++;
diff --git a/queue-5.8/io_uring-clear-req-result-on-iopoll-re-issue.patch b/queue-5.8/io_uring-clear-req-result-on-iopoll-re-issue.patch
new file mode 100644 (file)
index 0000000..36d3e96
--- /dev/null
@@ -0,0 +1,33 @@
+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;
diff --git a/queue-5.8/kvm-arm64-set-hcr_el2.ptw-to-prevent-at-taking-synchronous-exception.patch b/queue-5.8/kvm-arm64-set-hcr_el2.ptw-to-prevent-at-taking-synchronous-exception.patch
new file mode 100644 (file)
index 0000000..d3e14e5
--- /dev/null
@@ -0,0 +1,57 @@
+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)
diff --git a/queue-5.8/serial-8250-change-lock-order-in-serial8250_do_startup.patch b/queue-5.8/serial-8250-change-lock-order-in-serial8250_do_startup.patch
new file mode 100644 (file)
index 0000000..c1b5b05
--- /dev/null
@@ -0,0 +1,215 @@
+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
diff --git a/queue-5.8/serial-8250_exar-fix-number-of-ports-for-commtech-pcie-cards.patch b/queue-5.8/serial-8250_exar-fix-number-of-ports-for-commtech-pcie-cards.patch
new file mode 100644 (file)
index 0000000..42eaa71
--- /dev/null
@@ -0,0 +1,79 @@
+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),
diff --git a/queue-5.8/serial-pl011-don-t-leak-amba_ports-entry-on-driver-register-error.patch b/queue-5.8/serial-pl011-don-t-leak-amba_ports-entry-on-driver-register-error.patch
new file mode 100644 (file)
index 0000000..8ab6df2
--- /dev/null
@@ -0,0 +1,52 @@
+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;
+               }
+       }
diff --git a/queue-5.8/serial-pl011-fix-oops-on-eprobe_defer.patch b/queue-5.8/serial-pl011-fix-oops-on-eprobe_defer.patch
new file mode 100644 (file)
index 0000000..b549981
--- /dev/null
@@ -0,0 +1,93 @@
+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;
diff --git a/queue-5.8/serial-samsung-removes-the-irq-not-found-warning.patch b/queue-5.8/serial-samsung-removes-the-irq-not-found-warning.patch
new file mode 100644 (file)
index 0000000..f429af2
--- /dev/null
@@ -0,0 +1,50 @@
+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.
diff --git a/queue-5.8/serial-stm32-avoid-kernel-warning-on-absence-of-optional-irq.patch b/queue-5.8/serial-stm32-avoid-kernel-warning-on-absence-of-optional-irq.patch
new file mode 100644 (file)
index 0000000..8043d12
--- /dev/null
@@ -0,0 +1,38 @@
+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;
+       }
index 4005e32e1dc77ec8ba910313e814ebe5bc3bad7a..d61356179d47712440ecf50c517cfa2c3b08ba15 100644 (file)
@@ -174,3 +174,25 @@ btrfs-check-the-right-error-variable-in-btrfs_del_dir_entries_in_log.patch
 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
diff --git a/queue-5.8/usb-host-xhci-fix-ep-context-print-mismatch-in-debugfs.patch b/queue-5.8/usb-host-xhci-fix-ep-context-print-mismatch-in-debugfs.patch
new file mode 100644 (file)
index 0000000..8977fd8
--- /dev/null
@@ -0,0 +1,48 @@
+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),
diff --git a/queue-5.8/usb-host-xhci-tegra-fix-tegra_xusb_get_phy.patch b/queue-5.8/usb-host-xhci-tegra-fix-tegra_xusb_get_phy.patch
new file mode 100644 (file)
index 0000000..b143963
--- /dev/null
@@ -0,0 +1,31 @@
+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];
diff --git a/queue-5.8/usb-host-xhci-tegra-otg-usb2-usb3-port-init.patch b/queue-5.8/usb-host-xhci-tegra-otg-usb2-usb3-port-init.patch
new file mode 100644 (file)
index 0000000..9f01b9d
--- /dev/null
@@ -0,0 +1,33 @@
+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);
diff --git a/queue-5.8/usb-lvtest-return-proper-error-code-in-probe.patch b/queue-5.8/usb-lvtest-return-proper-error-code-in-probe.patch
new file mode 100644 (file)
index 0000000..d10138f
--- /dev/null
@@ -0,0 +1,35 @@
+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 */
diff --git a/queue-5.8/usb-renesas-xhci-remove-version-check.patch b/queue-5.8/usb-renesas-xhci-remove-version-check.patch
new file mode 100644 (file)
index 0000000..e102aed
--- /dev/null
@@ -0,0 +1,60 @@
+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
diff --git a/queue-5.8/vt-defer-kfree-of-vc_screenbuf-in-vc_do_resize.patch b/queue-5.8/vt-defer-kfree-of-vc_screenbuf-in-vc_do_resize.patch
new file mode 100644 (file)
index 0000000..f807ff1
--- /dev/null
@@ -0,0 +1,57 @@
+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;
diff --git a/queue-5.8/vt_ioctl-change-vt_resizex-ioctl-to-check-for-error-return-from-vc_resize.patch b/queue-5.8/vt_ioctl-change-vt_resizex-ioctl-to-check-for-error-return-from-vc_resize.patch
new file mode 100644 (file)
index 0000000..061f66f
--- /dev/null
@@ -0,0 +1,49 @@
+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();
+               }
diff --git a/queue-5.8/writeback-avoid-skipping-inode-writeback.patch b/queue-5.8/writeback-avoid-skipping-inode-writeback.patch
new file mode 100644 (file)
index 0000000..454db6e
--- /dev/null
@@ -0,0 +1,149 @@
+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)
diff --git a/queue-5.8/writeback-fix-sync-livelock-due-to-b_dirty_time-processing.patch b/queue-5.8/writeback-fix-sync-livelock-due-to-b_dirty_time-processing.patch
new file mode 100644 (file)
index 0000000..53b0158
--- /dev/null
@@ -0,0 +1,193 @@
+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
diff --git a/queue-5.8/writeback-protect-inode-i_io_list-with-inode-i_lock.patch b/queue-5.8/writeback-protect-inode-i_io_list-with-inode-i_lock.patch
new file mode 100644 (file)
index 0000000..78b66a4
--- /dev/null
@@ -0,0 +1,107 @@
+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) {
diff --git a/queue-5.8/xen-uses-irqdesc-irq_data_common-handler_data-to-store-a-per-interrupt-xen-data-pointer-which-contains-xen-specific-information.patch b/queue-5.8/xen-uses-irqdesc-irq_data_common-handler_data-to-store-a-per-interrupt-xen-data-pointer-which-contains-xen-specific-information.patch
new file mode 100644 (file)
index 0000000..9f0c7b3
--- /dev/null
@@ -0,0 +1,107 @@
+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;
diff --git a/queue-5.8/xhci-always-restore-ep_soft_clear_toggle-even-if-ep-reset-failed.patch b/queue-5.8/xhci-always-restore-ep_soft_clear_toggle-even-if-ep-reset-failed.patch
new file mode 100644 (file)
index 0000000..9cb13e8
--- /dev/null
@@ -0,0 +1,55 @@
+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,
diff --git a/queue-5.8/xhci-do-warm-reset-when-both-cas-and-xdev_resume-are-set.patch b/queue-5.8/xhci-do-warm-reset-when-both-cas-and-xdev_resume-are-set.patch
new file mode 100644 (file)
index 0000000..9ee5bce
--- /dev/null
@@ -0,0 +1,69 @@
+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.