From: Greg Kroah-Hartman Date: Mon, 31 Aug 2020 10:33:08 +0000 (+0200) Subject: 5.8-stable patches X-Git-Tag: v4.4.235~41 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c95059cab431aed9d42bd519fe9b0b3528d974ac;p=thirdparty%2Fkernel%2Fstable-queue.git 5.8-stable patches 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 --- 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 index 00000000000..c76ded207df --- /dev/null +++ b/queue-5.8/io-wq-fix-hang-after-cancelling-pending-hashed-work.patch @@ -0,0 +1,60 @@ +From 204361a77f4018627addd4a06877448f088ddfc0 Mon Sep 17 00:00:00 2001 +From: Pavel Begunkov +Date: Sun, 23 Aug 2020 20:33:10 +0300 +Subject: io-wq: fix hang after cancelling pending hashed work + +From: Pavel Begunkov + +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 +Fixes: 86f3cd1b589a1 ("io-wq: handle hashed writes in chains") +Signed-off-by: Pavel Begunkov +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..36d3e966b39 --- /dev/null +++ b/queue-5.8/io_uring-clear-req-result-on-iopoll-re-issue.patch @@ -0,0 +1,33 @@ +From 56450c20fe10d4d93f58019109aa4e06fc0b9206 Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Wed, 26 Aug 2020 18:58:26 -0600 +Subject: io_uring: clear req->result on IOPOLL re-issue + +From: Jens Axboe + +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 +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d3e14e5c3fe --- /dev/null +++ b/queue-5.8/kvm-arm64-set-hcr_el2.ptw-to-prevent-at-taking-synchronous-exception.patch @@ -0,0 +1,57 @@ +From 71a7f8cb1ca4ca7214a700b1243626759b6c11d4 Mon Sep 17 00:00:00 2001 +From: James Morse +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 + +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 # +Reviewed-by: Marc Zyngier +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c1b5b05c6c2 --- /dev/null +++ b/queue-5.8/serial-8250-change-lock-order-in-serial8250_do_startup.patch @@ -0,0 +1,215 @@ +From 205d300aea75623e1ae4aa43e0d265ab9cf195fd Mon Sep 17 00:00:00 2001 +From: Sergey Senozhatsky +Date: Mon, 17 Aug 2020 11:26:46 +0900 +Subject: serial: 8250: change lock order in serial8250_do_startup() + +From: Sergey Senozhatsky + +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: + + 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 + + +Signed-off-by: Sergey Senozhatsky +Fixes: 768aec0b5bcc ("serial: 8250: fix shared interrupts issues with SMP and RT kernels") +Reported-by: Guenter Roeck +Reported-by: Raul Rangel +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 +Reviewed-by: Guenter Roeck +Tested-by: Guenter Roeck +Cc: stable +Link: https://lore.kernel.org/r/20200817022646.1484638-1-sergey.senozhatsky@gmail.com +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..42eaa714980 --- /dev/null +++ b/queue-5.8/serial-8250_exar-fix-number-of-ports-for-commtech-pcie-cards.patch @@ -0,0 +1,79 @@ +From c6b9e95dde7b54e6a53c47241201ab5a4035c320 Mon Sep 17 00:00:00 2001 +From: Valmer Huhn +Date: Thu, 13 Aug 2020 12:52:55 -0400 +Subject: serial: 8250_exar: Fix number of ports for Commtech PCIe cards + +From: Valmer Huhn + +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 +Tested-by: Valmer Huhn +Cc: stable +Link: https://lore.kernel.org/r/20200813165255.GC345440@icarus.concurrent-rt.com +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8ab6df2da9e --- /dev/null +++ b/queue-5.8/serial-pl011-don-t-leak-amba_ports-entry-on-driver-register-error.patch @@ -0,0 +1,52 @@ +From 89efbe70b27dd325d8a8c177743a26b885f7faec Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +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 + +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 +Cc: stable@vger.kernel.org # v3.15+ +Cc: Tushar Behera +Link: https://lore.kernel.org/r/138f8c15afb2f184d8102583f8301575566064a6.1597316167.git.lukas@wunner.de +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b549981eadb --- /dev/null +++ b/queue-5.8/serial-pl011-fix-oops-on-eprobe_defer.patch @@ -0,0 +1,93 @@ +From 27afac93e3bd7fa89749cf11da5d86ac9cde4dba Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +Date: Thu, 13 Aug 2020 12:52:40 +0200 +Subject: serial: pl011: Fix oops on -EPROBE_DEFER + +From: Lukas Wunner + +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 +Cc: stable@vger.kernel.org # v4.10+ +Cc: Aleksey Makarov +Cc: Peter Hurley +Cc: Russell King +Cc: Christopher Covington +Link: https://lore.kernel.org/r/f827ff09da55b8c57d316a1b008a137677b58921.1597315557.git.lukas@wunner.de +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f429af2a347 --- /dev/null +++ b/queue-5.8/serial-samsung-removes-the-irq-not-found-warning.patch @@ -0,0 +1,50 @@ +From 8c6c378b0cbe0c9f1390986b5f8ffb5f6ff7593b Mon Sep 17 00:00:00 2001 +From: Tamseel Shams +Date: Mon, 10 Aug 2020 08:30:21 +0530 +Subject: serial: samsung: Removes the IRQ not found warning + +From: Tamseel Shams + +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 +Tested-by: Marek Szyprowski +Reviewed-by: Krzysztof Kozlowski +Reviewed-by: Alim Akhtar +Signed-off-by: Tamseel Shams +Cc: stable +Link: https://lore.kernel.org/r/20200810030021.45348-1-m.shams@samsung.com +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8043d125009 --- /dev/null +++ b/queue-5.8/serial-stm32-avoid-kernel-warning-on-absence-of-optional-irq.patch @@ -0,0 +1,38 @@ +From fdf16d78941b4f380753053d229955baddd00712 Mon Sep 17 00:00:00 2001 +From: Holger Assmann +Date: Thu, 13 Aug 2020 17:27:57 +0200 +Subject: serial: stm32: avoid kernel warning on absence of optional IRQ + +From: Holger Assmann + +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 +Cc: stable +Link: https://lore.kernel.org/r/20200813152757.32751-1-h.assmann@pengutronix.de +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-5.8/series b/queue-5.8/series index 4005e32e1dc..d61356179d4 100644 --- a/queue-5.8/series +++ b/queue-5.8/series @@ -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 index 00000000000..8977fd8c5b5 --- /dev/null +++ b/queue-5.8/usb-host-xhci-fix-ep-context-print-mismatch-in-debugfs.patch @@ -0,0 +1,48 @@ +From 0077b1b2c8d9ad5f7a08b62fb8524cdb9938388f Mon Sep 17 00:00:00 2001 +From: Li Jun +Date: Fri, 21 Aug 2020 12:15:47 +0300 +Subject: usb: host: xhci: fix ep context print mismatch in debugfs + +From: Li Jun + +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 # v4.15+ +Fixes: 02b6fdc2a153 ("usb: xhci: Add debugfs interface for xHCI driver") +Signed-off-by: Li Jun +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20200821091549.20556-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b143963b7bc --- /dev/null +++ b/queue-5.8/usb-host-xhci-tegra-fix-tegra_xusb_get_phy.patch @@ -0,0 +1,31 @@ +From d54343a87732726b04ac5af873916b5ed4f52932 Mon Sep 17 00:00:00 2001 +From: JC Kuo +Date: Tue, 11 Aug 2020 17:25:53 +0800 +Subject: usb: host: xhci-tegra: fix tegra_xusb_get_phy() + +From: JC Kuo + +commit d54343a87732726b04ac5af873916b5ed4f52932 upstream. + +tegra_xusb_get_phy() should take input argument "name". + +Signed-off-by: JC Kuo +Cc: stable +Link: https://lore.kernel.org/r/20200811092553.657762-1-jckuo@nvidia.com +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9f01b9db4e4 --- /dev/null +++ b/queue-5.8/usb-host-xhci-tegra-otg-usb2-usb3-port-init.patch @@ -0,0 +1,33 @@ +From 316a2868bc269be8c6e69ccc3a1f902a3f518eb9 Mon Sep 17 00:00:00 2001 +From: JC Kuo +Date: Tue, 11 Aug 2020 17:31:43 +0800 +Subject: usb: host: xhci-tegra: otg usb2/usb3 port init + +From: JC Kuo + +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 +Cc: stable +Link: https://lore.kernel.org/r/20200811093143.699541-1-jckuo@nvidia.com +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d10138fab15 --- /dev/null +++ b/queue-5.8/usb-lvtest-return-proper-error-code-in-probe.patch @@ -0,0 +1,35 @@ +From 531412492ce93ea29b9ca3b4eb5e3ed771f851dd Mon Sep 17 00:00:00 2001 +From: Evgeny Novikov +Date: Wed, 5 Aug 2020 12:06:43 +0300 +Subject: USB: lvtest: return proper error code in probe + +From: Evgeny Novikov + +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 +Cc: stable +Link: https://lore.kernel.org/r/20200805090643.3432-1-novikov@ispras.ru +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e102aedb4e1 --- /dev/null +++ b/queue-5.8/usb-renesas-xhci-remove-version-check.patch @@ -0,0 +1,60 @@ +From d66a57be2f9a315fc10d0f524f670fec903e0fb4 Mon Sep 17 00:00:00 2001 +From: Vinod Koul +Date: Tue, 18 Aug 2020 12:47:39 +0530 +Subject: usb: renesas-xhci: remove version check + +From: Vinod Koul + +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 +Reported by: Glen Journeay +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 +Cc: stable +Link: https://lore.kernel.org/r/20200818071739.789720-1-vkoul@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f807ff13505 --- /dev/null +++ b/queue-5.8/vt-defer-kfree-of-vc_screenbuf-in-vc_do_resize.patch @@ -0,0 +1,57 @@ +From f8d1653daec02315e06d30246cff4af72e76e54e Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Wed, 29 Jul 2020 23:57:01 +0900 +Subject: vt: defer kfree() of vc_screenbuf in vc_do_resize() + +From: Tetsuo Handa + +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 +Signed-off-by: Tetsuo Handa +Cc: stable +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 + +--- + 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 index 00000000000..061f66f86dd --- /dev/null +++ b/queue-5.8/vt_ioctl-change-vt_resizex-ioctl-to-check-for-error-return-from-vc_resize.patch @@ -0,0 +1,49 @@ +From bc5269ca765057a1b762e79a1cfd267cd7bf1c46 Mon Sep 17 00:00:00 2001 +From: George Kennedy +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 + +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 +Cc: stable +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 + +--- + 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 index 00000000000..454db6e5dcf --- /dev/null +++ b/queue-5.8/writeback-avoid-skipping-inode-writeback.patch @@ -0,0 +1,149 @@ +From 5afced3bf28100d81fb2fe7e98918632a08feaf5 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Fri, 29 May 2020 15:05:22 +0200 +Subject: writeback: Avoid skipping inode writeback + +From: Jan Kara + +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 +Reviewed-by: Martijn Coenen +Tested-by: Martijn Coenen +Reviewed-by: Christoph Hellwig +Fixes: 0ae45f63d4ef ("vfs: add support for a lazytime mount option") +CC: stable@vger.kernel.org +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..53b0158f48d --- /dev/null +++ b/queue-5.8/writeback-fix-sync-livelock-due-to-b_dirty_time-processing.patch @@ -0,0 +1,193 @@ +From f9cae926f35e8230330f28c7b743ad088611a8de Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Fri, 29 May 2020 16:08:58 +0200 +Subject: writeback: Fix sync livelock due to b_dirty_time processing + +From: Jan Kara + +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 +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..78b66a47f13 --- /dev/null +++ b/queue-5.8/writeback-protect-inode-i_io_list-with-inode-i_lock.patch @@ -0,0 +1,107 @@ +From b35250c0816c7cf7d0a8de92f5fafb6a7508a708 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Wed, 10 Jun 2020 17:36:03 +0200 +Subject: writeback: Protect inode->i_io_list with inode->i_lock + +From: Jan Kara + +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 +Reviewed-by: Christoph Hellwig +CC: stable@vger.kernel.org # Prerequisite for "writeback: Avoid skipping inode writeback" +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9f0c7b33a9c --- /dev/null +++ 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 @@ -0,0 +1,107 @@ +From c330fb1ddc0a922f044989492b7fcca77ee1db46 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +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 + +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 +Signed-off-by: Thomas Gleixner +Tested-by: Roman Shaposhnik +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/87lfi2yckt.fsf@nanos.tec.linutronix.de +Signed-off-by: Juergen Gross +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9cb13e8d50f --- /dev/null +++ b/queue-5.8/xhci-always-restore-ep_soft_clear_toggle-even-if-ep-reset-failed.patch @@ -0,0 +1,55 @@ +From f1ec7ae6c9f8c016db320e204cb519a1da1581b8 Mon Sep 17 00:00:00 2001 +From: Ding Hui +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 + +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 # v4.17+ +Signed-off-by: Ding Hui +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20200821091549.20556-4-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9ee5bce50db --- /dev/null +++ b/queue-5.8/xhci-do-warm-reset-when-both-cas-and-xdev_resume-are-set.patch @@ -0,0 +1,69 @@ +From 904df64a5f4d5ebd670801d869ca0a6d6a6e8df6 Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng +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 + +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 +Signed-off-by: Kai-Heng Feng +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20200821091549.20556-3-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + 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.