From: Sasha Levin Date: Thu, 31 Dec 2020 04:14:50 +0000 (-0500) Subject: Fixes for 4.14 X-Git-Tag: v4.19.165~36 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=49b7d0bd2d465d9a7ec7ddfed844ee2ea2967d26;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.14 Signed-off-by: Sasha Levin --- diff --git a/queue-4.14/powerpc-bitops-fix-possible-undefined-behaviour-with.patch b/queue-4.14/powerpc-bitops-fix-possible-undefined-behaviour-with.patch new file mode 100644 index 00000000000..8ba441d8f2e --- /dev/null +++ b/queue-4.14/powerpc-bitops-fix-possible-undefined-behaviour-with.patch @@ -0,0 +1,122 @@ +From fe95acff763d8c5423d0a29719a104e0f5aecc94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Oct 2020 14:05:46 +0000 +Subject: powerpc/bitops: Fix possible undefined behaviour with fls() and + fls64() + +From: Christophe Leroy + +[ Upstream commit 1891ef21d92c4801ea082ee8ed478e304ddc6749 ] + +fls() and fls64() are using __builtin_ctz() and _builtin_ctzll(). +On powerpc, those builtins trivially use ctlzw and ctlzd power +instructions. + +Allthough those instructions provide the expected result with +input argument 0, __builtin_ctz() and __builtin_ctzll() are +documented as undefined for value 0. + +The easiest fix would be to use fls() and fls64() functions +defined in include/asm-generic/bitops/builtin-fls.h and +include/asm-generic/bitops/fls64.h, but GCC output is not optimal: + +00000388 : + 388: 2c 03 00 00 cmpwi r3,0 + 38c: 41 82 00 10 beq 39c + 390: 7c 63 00 34 cntlzw r3,r3 + 394: 20 63 00 20 subfic r3,r3,32 + 398: 4e 80 00 20 blr + 39c: 38 60 00 00 li r3,0 + 3a0: 4e 80 00 20 blr + +000003b0 : + 3b0: 2c 03 00 00 cmpwi r3,0 + 3b4: 40 82 00 1c bne 3d0 + 3b8: 2f 84 00 00 cmpwi cr7,r4,0 + 3bc: 38 60 00 00 li r3,0 + 3c0: 4d 9e 00 20 beqlr cr7 + 3c4: 7c 83 00 34 cntlzw r3,r4 + 3c8: 20 63 00 20 subfic r3,r3,32 + 3cc: 4e 80 00 20 blr + 3d0: 7c 63 00 34 cntlzw r3,r3 + 3d4: 20 63 00 40 subfic r3,r3,64 + 3d8: 4e 80 00 20 blr + +When the input of fls(x) is a constant, just check x for nullity and +return either 0 or __builtin_clz(x). Otherwise, use cntlzw instruction +directly. + +For fls64() on PPC64, do the same but with __builtin_clzll() and +cntlzd instruction. On PPC32, lets take the generic fls64() which +will use our fls(). The result is as expected: + +00000388 : + 388: 7c 63 00 34 cntlzw r3,r3 + 38c: 20 63 00 20 subfic r3,r3,32 + 390: 4e 80 00 20 blr + +000003a0 : + 3a0: 2c 03 00 00 cmpwi r3,0 + 3a4: 40 82 00 10 bne 3b4 + 3a8: 7c 83 00 34 cntlzw r3,r4 + 3ac: 20 63 00 20 subfic r3,r3,32 + 3b0: 4e 80 00 20 blr + 3b4: 7c 63 00 34 cntlzw r3,r3 + 3b8: 20 63 00 40 subfic r3,r3,64 + 3bc: 4e 80 00 20 blr + +Fixes: 2fcff790dcb4 ("powerpc: Use builtin functions for fls()/__fls()/fls64()") +Cc: stable@vger.kernel.org +Signed-off-by: Christophe Leroy +Acked-by: Segher Boessenkool +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/348c2d3f19ffcff8abe50d52513f989c4581d000.1603375524.git.christophe.leroy@csgroup.eu +Signed-off-by: Sasha Levin +--- + arch/powerpc/include/asm/bitops.h | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h +index b750ffef83c7d..0ec93d940d12c 100644 +--- a/arch/powerpc/include/asm/bitops.h ++++ b/arch/powerpc/include/asm/bitops.h +@@ -220,15 +220,34 @@ static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr) + */ + static __inline__ int fls(unsigned int x) + { +- return 32 - __builtin_clz(x); ++ int lz; ++ ++ if (__builtin_constant_p(x)) ++ return x ? 32 - __builtin_clz(x) : 0; ++ asm("cntlzw %0,%1" : "=r" (lz) : "r" (x)); ++ return 32 - lz; + } + + #include + ++/* ++ * 64-bit can do this using one cntlzd (count leading zeroes doubleword) ++ * instruction; for 32-bit we use the generic version, which does two ++ * 32-bit fls calls. ++ */ ++#ifdef CONFIG_PPC64 + static __inline__ int fls64(__u64 x) + { +- return 64 - __builtin_clzll(x); ++ int lz; ++ ++ if (__builtin_constant_p(x)) ++ return x ? 64 - __builtin_clzll(x) : 0; ++ asm("cntlzd %0,%1" : "=r" (lz) : "r" (x)); ++ return 64 - lz; + } ++#else ++#include ++#endif + + #ifdef CONFIG_PPC64 + unsigned int __arch_hweight8(unsigned int w); +-- +2.27.0 + diff --git a/queue-4.14/s390-dasd-fix-hanging-device-offline-processing.patch b/queue-4.14/s390-dasd-fix-hanging-device-offline-processing.patch new file mode 100644 index 00000000000..8b3de3046dc --- /dev/null +++ b/queue-4.14/s390-dasd-fix-hanging-device-offline-processing.patch @@ -0,0 +1,62 @@ +From aee4b627bc510664d799a70c1826eaee67b28e78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Dec 2020 16:59:04 +0100 +Subject: s390/dasd: fix hanging device offline processing + +From: Stefan Haberland + +[ Upstream commit 658a337a606f48b7ebe451591f7681d383fa115e ] + +For an LCU update a read unit address configuration IO is required. +This is started using sleep_on(), which has early exit paths in case the +device is not usable for IO. For example when it is in offline processing. + +In those cases the LCU update should fail and not be retried. +Therefore lcu_update_work checks if EOPNOTSUPP is returned or not. + +Commit 41995342b40c ("s390/dasd: fix endless loop after read unit address configuration") +accidentally removed the EOPNOTSUPP return code from +read_unit_address_configuration(), which in turn might lead to an endless +loop of the LCU update in offline processing. + +Fix by returning EOPNOTSUPP again if the device is not able to perform the +request. + +Fixes: 41995342b40c ("s390/dasd: fix endless loop after read unit address configuration") +Cc: stable@vger.kernel.org #5.3 +Signed-off-by: Stefan Haberland +Reviewed-by: Jan Hoeppner +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/s390/block/dasd_alias.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c +index 487b16ace0060..0f70cae1c01e3 100644 +--- a/drivers/s390/block/dasd_alias.c ++++ b/drivers/s390/block/dasd_alias.c +@@ -462,11 +462,19 @@ static int read_unit_address_configuration(struct dasd_device *device, + spin_unlock_irqrestore(&lcu->lock, flags); + + rc = dasd_sleep_on(cqr); +- if (rc && !suborder_not_supported(cqr)) { ++ if (!rc) ++ goto out; ++ ++ if (suborder_not_supported(cqr)) { ++ /* suborder not supported or device unusable for IO */ ++ rc = -EOPNOTSUPP; ++ } else { ++ /* IO failed but should be retried */ + spin_lock_irqsave(&lcu->lock, flags); + lcu->flags |= NEED_UAC_UPDATE; + spin_unlock_irqrestore(&lcu->lock, flags); + } ++out: + dasd_kfree_request(cqr, cqr->memdev); + return rc; + } +-- +2.27.0 + diff --git a/queue-4.14/series b/queue-4.14/series index 6ffa5407677..b891ae4d164 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -6,3 +6,7 @@ alsa-usb-audio-fix-sync-ep-altsetting-sanity-check.patch mm-memcontrol-eliminate-raw-access-to-stat-and-event-counters.patch mm-memcontrol-implement-lruvec-stat-functions-on-top-of-each-other.patch mm-memcontrol-fix-excessive-complexity-in-memory.stat-reporting.patch +vfio-pci-move-dummy_resources_list-init-in-vfio_pci_.patch +s390-dasd-fix-hanging-device-offline-processing.patch +usb-serial-digi_acceleport-fix-write-wakeup-deadlock.patch +powerpc-bitops-fix-possible-undefined-behaviour-with.patch diff --git a/queue-4.14/usb-serial-digi_acceleport-fix-write-wakeup-deadlock.patch b/queue-4.14/usb-serial-digi_acceleport-fix-write-wakeup-deadlock.patch new file mode 100644 index 00000000000..2ed163c95a4 --- /dev/null +++ b/queue-4.14/usb-serial-digi_acceleport-fix-write-wakeup-deadlock.patch @@ -0,0 +1,160 @@ +From 8eac8e4f2ee7251533844266f0589439ca1738ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Oct 2020 11:43:06 +0100 +Subject: USB: serial: digi_acceleport: fix write-wakeup deadlocks + +From: Johan Hovold + +[ Upstream commit 5098e77962e7c8947f87bd8c5869c83e000a522a ] + +The driver must not call tty_wakeup() while holding its private lock as +line disciplines are allowed to call back into write() from +write_wakeup(), leading to a deadlock. + +Also remove the unneeded work struct that was used to defer wakeup in +order to work around a possible race in ancient times (see comment about +n_tty write_chan() in commit 14b54e39b412 ("USB: serial: remove +changelogs and old todo entries")). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@vger.kernel.org +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Johan Hovold +Signed-off-by: Sasha Levin +--- + drivers/usb/serial/digi_acceleport.c | 45 ++++++++-------------------- + 1 file changed, 13 insertions(+), 32 deletions(-) + +diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c +index 2ce39af32cfa6..e494ffdc06bc9 100644 +--- a/drivers/usb/serial/digi_acceleport.c ++++ b/drivers/usb/serial/digi_acceleport.c +@@ -23,7 +23,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -202,14 +201,12 @@ struct digi_port { + int dp_throttle_restart; + wait_queue_head_t dp_flush_wait; + wait_queue_head_t dp_close_wait; /* wait queue for close */ +- struct work_struct dp_wakeup_work; + struct usb_serial_port *dp_port; + }; + + + /* Local Function Declarations */ + +-static void digi_wakeup_write_lock(struct work_struct *work); + static int digi_write_oob_command(struct usb_serial_port *port, + unsigned char *buf, int count, int interruptible); + static int digi_write_inb_command(struct usb_serial_port *port, +@@ -360,26 +357,6 @@ __releases(lock) + return timeout; + } + +- +-/* +- * Digi Wakeup Write +- * +- * Wake up port, line discipline, and tty processes sleeping +- * on writes. +- */ +- +-static void digi_wakeup_write_lock(struct work_struct *work) +-{ +- struct digi_port *priv = +- container_of(work, struct digi_port, dp_wakeup_work); +- struct usb_serial_port *port = priv->dp_port; +- unsigned long flags; +- +- spin_lock_irqsave(&priv->dp_port_lock, flags); +- tty_port_tty_wakeup(&port->port); +- spin_unlock_irqrestore(&priv->dp_port_lock, flags); +-} +- + /* + * Digi Write OOB Command + * +@@ -990,6 +967,7 @@ static void digi_write_bulk_callback(struct urb *urb) + struct digi_serial *serial_priv; + int ret = 0; + int status = urb->status; ++ bool wakeup; + + /* port and serial sanity check */ + if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) { +@@ -1016,6 +994,7 @@ static void digi_write_bulk_callback(struct urb *urb) + } + + /* try to send any buffered data on this port */ ++ wakeup = true; + spin_lock(&priv->dp_port_lock); + priv->dp_write_urb_in_use = 0; + if (priv->dp_out_buf_len > 0) { +@@ -1031,19 +1010,18 @@ static void digi_write_bulk_callback(struct urb *urb) + if (ret == 0) { + priv->dp_write_urb_in_use = 1; + priv->dp_out_buf_len = 0; ++ wakeup = false; + } + } +- /* wake up processes sleeping on writes immediately */ +- tty_port_tty_wakeup(&port->port); +- /* also queue up a wakeup at scheduler time, in case we */ +- /* lost the race in write_chan(). */ +- schedule_work(&priv->dp_wakeup_work); +- + spin_unlock(&priv->dp_port_lock); ++ + if (ret && ret != -EPERM) + dev_err_console(port, + "%s: usb_submit_urb failed, ret=%d, port=%d\n", + __func__, ret, priv->dp_port_num); ++ ++ if (wakeup) ++ tty_port_tty_wakeup(&port->port); + } + + static int digi_write_room(struct tty_struct *tty) +@@ -1243,7 +1221,6 @@ static int digi_port_init(struct usb_serial_port *port, unsigned port_num) + init_waitqueue_head(&priv->dp_transmit_idle_wait); + init_waitqueue_head(&priv->dp_flush_wait); + init_waitqueue_head(&priv->dp_close_wait); +- INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); + priv->dp_port = port; + + init_waitqueue_head(&port->write_wait); +@@ -1510,13 +1487,14 @@ static int digi_read_oob_callback(struct urb *urb) + rts = C_CRTSCTS(tty); + + if (tty && opcode == DIGI_CMD_READ_INPUT_SIGNALS) { ++ bool wakeup = false; ++ + spin_lock(&priv->dp_port_lock); + /* convert from digi flags to termiox flags */ + if (val & DIGI_READ_INPUT_SIGNALS_CTS) { + priv->dp_modem_signals |= TIOCM_CTS; +- /* port must be open to use tty struct */ + if (rts) +- tty_port_tty_wakeup(&port->port); ++ wakeup = true; + } else { + priv->dp_modem_signals &= ~TIOCM_CTS; + /* port must be open to use tty struct */ +@@ -1535,6 +1513,9 @@ static int digi_read_oob_callback(struct urb *urb) + priv->dp_modem_signals &= ~TIOCM_CD; + + spin_unlock(&priv->dp_port_lock); ++ ++ if (wakeup) ++ tty_port_tty_wakeup(&port->port); + } else if (opcode == DIGI_CMD_TRANSMIT_IDLE) { + spin_lock(&priv->dp_port_lock); + priv->dp_transmit_idle = 1; +-- +2.27.0 + diff --git a/queue-4.14/vfio-pci-move-dummy_resources_list-init-in-vfio_pci_.patch b/queue-4.14/vfio-pci-move-dummy_resources_list-init-in-vfio_pci_.patch new file mode 100644 index 00000000000..246fca4aeee --- /dev/null +++ b/queue-4.14/vfio-pci-move-dummy_resources_list-init-in-vfio_pci_.patch @@ -0,0 +1,49 @@ +From 6f2ebf2be85f3464c005eff7202fda93b76efe90 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Nov 2020 18:52:02 +0100 +Subject: vfio/pci: Move dummy_resources_list init in vfio_pci_probe() + +From: Eric Auger + +[ Upstream commit 16b8fe4caf499ae8e12d2ab1b1324497e36a7b83 ] + +In case an error occurs in vfio_pci_enable() before the call to +vfio_pci_probe_mmaps(), vfio_pci_disable() will try to iterate +on an uninitialized list and cause a kernel panic. + +Lets move to the initialization to vfio_pci_probe() to fix the +issue. + +Signed-off-by: Eric Auger +Fixes: 05f0c03fbac1 ("vfio-pci: Allow to mmap sub-page MMIO BARs if the mmio page is exclusive") +CC: Stable # v4.7+ +Signed-off-by: Alex Williamson +Signed-off-by: Sasha Levin +--- + drivers/vfio/pci/vfio_pci.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c +index 6fceefcab81db..dedc7edea5178 100644 +--- a/drivers/vfio/pci/vfio_pci.c ++++ b/drivers/vfio/pci/vfio_pci.c +@@ -118,8 +118,6 @@ static void vfio_pci_probe_mmaps(struct vfio_pci_device *vdev) + int bar; + struct vfio_pci_dummy_resource *dummy_res; + +- INIT_LIST_HEAD(&vdev->dummy_resources_list); +- + for (bar = PCI_STD_RESOURCES; bar <= PCI_STD_RESOURCE_END; bar++) { + res = vdev->pdev->resource + bar; + +@@ -1524,6 +1522,7 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + vdev->irq_type = VFIO_PCI_NUM_IRQS; + mutex_init(&vdev->igate); + spin_lock_init(&vdev->irqlock); ++ INIT_LIST_HEAD(&vdev->dummy_resources_list); + mutex_init(&vdev->vma_lock); + INIT_LIST_HEAD(&vdev->vma_list); + init_rwsem(&vdev->memory_lock); +-- +2.27.0 +