]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 26 Feb 2020 10:47:22 +0000 (11:47 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 26 Feb 2020 10:47:22 +0000 (11:47 +0100)
added patches:
maintainers-update-drm-i915-bug-filing-url.patch
revert-ipc-sem-remove-uneeded-sem_undo_list-lock-usage-in-exit_sem.patch
serdev-ttyport-restore-client-ops-on-deregistration.patch
tty-serial-atmel-manage-shutdown-in-case-of-rs485-or-iso7816-mode.patch
tty-serial-imx-setup-the-correct-sg-entry-for-tx-dma.patch
x86-mce-amd-fix-kobject-lifetime.patch
x86-mce-amd-publish-the-bank-pointer-only-after-setup-has-succeeded.patch

queue-4.14/maintainers-update-drm-i915-bug-filing-url.patch [new file with mode: 0644]
queue-4.14/revert-ipc-sem-remove-uneeded-sem_undo_list-lock-usage-in-exit_sem.patch [new file with mode: 0644]
queue-4.14/serdev-ttyport-restore-client-ops-on-deregistration.patch [new file with mode: 0644]
queue-4.14/series
queue-4.14/tty-serial-atmel-manage-shutdown-in-case-of-rs485-or-iso7816-mode.patch [new file with mode: 0644]
queue-4.14/tty-serial-imx-setup-the-correct-sg-entry-for-tx-dma.patch [new file with mode: 0644]
queue-4.14/x86-mce-amd-fix-kobject-lifetime.patch [new file with mode: 0644]
queue-4.14/x86-mce-amd-publish-the-bank-pointer-only-after-setup-has-succeeded.patch [new file with mode: 0644]

diff --git a/queue-4.14/maintainers-update-drm-i915-bug-filing-url.patch b/queue-4.14/maintainers-update-drm-i915-bug-filing-url.patch
new file mode 100644 (file)
index 0000000..1c380e3
--- /dev/null
@@ -0,0 +1,34 @@
+From 96228b7df33f8eb9006f8ae96949400aed9bd303 Mon Sep 17 00:00:00 2001
+From: Jani Nikula <jani.nikula@intel.com>
+Date: Wed, 12 Feb 2020 18:04:33 +0200
+Subject: MAINTAINERS: Update drm/i915 bug filing URL
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+commit 96228b7df33f8eb9006f8ae96949400aed9bd303 upstream.
+
+We've moved from bugzilla to gitlab.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20200212160434.6437-1-jani.nikula@intel.com
+(cherry picked from commit 3a6a4f0810c8ade6f1ff63c34aa9834176b9d88b)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ MAINTAINERS |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -6877,7 +6877,7 @@ M:       Joonas Lahtinen <joonas.lahtinen@linu
+ M:    Rodrigo Vivi <rodrigo.vivi@intel.com>
+ L:    intel-gfx@lists.freedesktop.org
+ W:    https://01.org/linuxgraphics/
+-B:    https://01.org/linuxgraphics/documentation/how-report-bugs
++B:    https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs
+ C:    irc://chat.freenode.net/intel-gfx
+ Q:    http://patchwork.freedesktop.org/project/intel-gfx/
+ T:    git git://anongit.freedesktop.org/drm-intel
diff --git a/queue-4.14/revert-ipc-sem-remove-uneeded-sem_undo_list-lock-usage-in-exit_sem.patch b/queue-4.14/revert-ipc-sem-remove-uneeded-sem_undo_list-lock-usage-in-exit_sem.patch
new file mode 100644 (file)
index 0000000..e2c2a61
--- /dev/null
@@ -0,0 +1,135 @@
+From edf28f4061afe4c2d9eb1c3323d90e882c1d6800 Mon Sep 17 00:00:00 2001
+From: Ioanna Alifieraki <ioanna-maria.alifieraki@canonical.com>
+Date: Thu, 20 Feb 2020 20:04:00 -0800
+Subject: Revert "ipc,sem: remove uneeded sem_undo_list lock usage in exit_sem()"
+
+From: Ioanna Alifieraki <ioanna-maria.alifieraki@canonical.com>
+
+commit edf28f4061afe4c2d9eb1c3323d90e882c1d6800 upstream.
+
+This reverts commit a97955844807e327df11aa33869009d14d6b7de0.
+
+Commit a97955844807 ("ipc,sem: remove uneeded sem_undo_list lock usage
+in exit_sem()") removes a lock that is needed.  This leads to a process
+looping infinitely in exit_sem() and can also lead to a crash.  There is
+a reproducer available in [1] and with the commit reverted the issue
+does not reproduce anymore.
+
+Using the reproducer found in [1] is fairly easy to reach a point where
+one of the child processes is looping infinitely in exit_sem between
+for(;;) and if (semid == -1) block, while it's trying to free its last
+sem_undo structure which has already been freed by freeary().
+
+Each sem_undo struct is on two lists: one per semaphore set (list_id)
+and one per process (list_proc).  The list_id list tracks undos by
+semaphore set, and the list_proc by process.
+
+Undo structures are removed either by freeary() or by exit_sem().  The
+freeary function is invoked when the user invokes a syscall to remove a
+semaphore set.  During this operation freeary() traverses the list_id
+associated with the semaphore set and removes the undo structures from
+both the list_id and list_proc lists.
+
+For this case, exit_sem() is called at process exit.  Each process
+contains a struct sem_undo_list (referred to as "ulp") which contains
+the head for the list_proc list.  When the process exits, exit_sem()
+traverses this list to remove each sem_undo struct.  As in freeary(),
+whenever a sem_undo struct is removed from list_proc, it is also removed
+from the list_id list.
+
+Removing elements from list_id is safe for both exit_sem() and freeary()
+due to sem_lock().  Removing elements from list_proc is not safe;
+freeary() locks &un->ulp->lock when it performs
+list_del_rcu(&un->list_proc) but exit_sem() does not (locking was
+removed by commit a97955844807 ("ipc,sem: remove uneeded sem_undo_list
+lock usage in exit_sem()").
+
+This can result in the following situation while executing the
+reproducer [1] : Consider a child process in exit_sem() and the parent
+in freeary() (because of semctl(sid[i], NSEM, IPC_RMID)).
+
+ - The list_proc for the child contains the last two undo structs A and
+   B (the rest have been removed either by exit_sem() or freeary()).
+
+ - The semid for A is 1 and semid for B is 2.
+
+ - exit_sem() removes A and at the same time freeary() removes B.
+
+ - Since A and B have different semid sem_lock() will acquire different
+   locks for each process and both can proceed.
+
+The bug is that they remove A and B from the same list_proc at the same
+time because only freeary() acquires the ulp lock. When exit_sem()
+removes A it makes ulp->list_proc.next to point at B and at the same
+time freeary() removes B setting B->semid=-1.
+
+At the next iteration of for(;;) loop exit_sem() will try to remove B.
+
+The only way to break from for(;;) is for (&un->list_proc ==
+&ulp->list_proc) to be true which is not. Then exit_sem() will check if
+B->semid=-1 which is and will continue looping in for(;;) until the
+memory for B is reallocated and the value at B->semid is changed.
+
+At that point, exit_sem() will crash attempting to unlink B from the
+lists (this can be easily triggered by running the reproducer [1] a
+second time).
+
+To prove this scenario instrumentation was added to keep information
+about each sem_undo (un) struct that is removed per process and per
+semaphore set (sma).
+
+          CPU0                                CPU1
+  [caller holds sem_lock(sma for A)]      ...
+  freeary()                               exit_sem()
+  ...                                     ...
+  ...                                     sem_lock(sma for B)
+  spin_lock(A->ulp->lock)                 ...
+  list_del_rcu(un_A->list_proc)           list_del_rcu(un_B->list_proc)
+
+Undo structures A and B have different semid and sem_lock() operations
+proceed.  However they belong to the same list_proc list and they are
+removed at the same time.  This results into ulp->list_proc.next
+pointing to the address of B which is already removed.
+
+After reverting commit a97955844807 ("ipc,sem: remove uneeded
+sem_undo_list lock usage in exit_sem()") the issue was no longer
+reproducible.
+
+[1] https://bugzilla.redhat.com/show_bug.cgi?id=1694779
+
+Link: http://lkml.kernel.org/r/20191211191318.11860-1-ioanna-maria.alifieraki@canonical.com
+Fixes: a97955844807 ("ipc,sem: remove uneeded sem_undo_list lock usage in exit_sem()")
+Signed-off-by: Ioanna Alifieraki <ioanna-maria.alifieraki@canonical.com>
+Acked-by: Manfred Spraul <manfred@colorfullife.com>
+Acked-by: Herton R. Krzesinski <herton@redhat.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: <malat@debian.org>
+Cc: Joel Fernandes (Google) <joel@joelfernandes.org>
+Cc: Davidlohr Bueso <dave@stgolabs.net>
+Cc: Jay Vosburgh <jay.vosburgh@canonical.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/sem.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/ipc/sem.c
++++ b/ipc/sem.c
+@@ -2248,11 +2248,9 @@ void exit_sem(struct task_struct *tsk)
+               ipc_assert_locked_object(&sma->sem_perm);
+               list_del(&un->list_id);
+-              /* we are the last process using this ulp, acquiring ulp->lock
+-               * isn't required. Besides that, we are also protected against
+-               * IPC_RMID as we hold sma->sem_perm lock now
+-               */
++              spin_lock(&ulp->lock);
+               list_del_rcu(&un->list_proc);
++              spin_unlock(&ulp->lock);
+               /* perform adjustments registered in un */
+               for (i = 0; i < sma->sem_nsems; i++) {
diff --git a/queue-4.14/serdev-ttyport-restore-client-ops-on-deregistration.patch b/queue-4.14/serdev-ttyport-restore-client-ops-on-deregistration.patch
new file mode 100644 (file)
index 0000000..545b835
--- /dev/null
@@ -0,0 +1,107 @@
+From 0c5aae59270fb1f827acce182786094c9ccf598e Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 10 Feb 2020 15:57:30 +0100
+Subject: serdev: ttyport: restore client ops on deregistration
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 0c5aae59270fb1f827acce182786094c9ccf598e upstream.
+
+The serdev tty-port controller driver should reset the tty-port client
+operations also on deregistration to avoid a NULL-pointer dereference in
+case the port is later re-registered as a normal tty device.
+
+Note that this can only happen with tty drivers such as 8250 which have
+statically allocated port structures that can end up being reused and
+where a later registration would not register a serdev controller (e.g.
+due to registration errors or if the devicetree has been changed in
+between).
+
+Specifically, this can be an issue for any statically defined ports that
+would be registered by 8250 core when an 8250 driver is being unbound.
+
+Fixes: bed35c6dfa6a ("serdev: add a tty port controller driver")
+Cc: stable <stable@vger.kernel.org>     # 4.11
+Reported-by: Loic Poulain <loic.poulain@linaro.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20200210145730.22762-1-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serdev/serdev-ttyport.c |    6 ++----
+ drivers/tty/tty_port.c              |    5 +++--
+ include/linux/tty.h                 |    2 ++
+ 3 files changed, 7 insertions(+), 6 deletions(-)
+
+--- a/drivers/tty/serdev/serdev-ttyport.c
++++ b/drivers/tty/serdev/serdev-ttyport.c
+@@ -238,7 +238,6 @@ struct device *serdev_tty_port_register(
+                                       struct device *parent,
+                                       struct tty_driver *drv, int idx)
+ {
+-      const struct tty_port_client_operations *old_ops;
+       struct serdev_controller *ctrl;
+       struct serport *serport;
+       int ret;
+@@ -257,7 +256,6 @@ struct device *serdev_tty_port_register(
+       ctrl->ops = &ctrl_ops;
+-      old_ops = port->client_ops;
+       port->client_ops = &client_ops;
+       port->client_data = ctrl;
+@@ -270,7 +268,7 @@ struct device *serdev_tty_port_register(
+ err_reset_data:
+       port->client_data = NULL;
+-      port->client_ops = old_ops;
++      port->client_ops = &tty_port_default_client_ops;
+       serdev_controller_put(ctrl);
+       return ERR_PTR(ret);
+@@ -285,8 +283,8 @@ int serdev_tty_port_unregister(struct tt
+               return -ENODEV;
+       serdev_controller_remove(ctrl);
+-      port->client_ops = NULL;
+       port->client_data = NULL;
++      port->client_ops = &tty_port_default_client_ops;
+       serdev_controller_put(ctrl);
+       return 0;
+--- a/drivers/tty/tty_port.c
++++ b/drivers/tty/tty_port.c
+@@ -51,10 +51,11 @@ static void tty_port_default_wakeup(stru
+       }
+ }
+-static const struct tty_port_client_operations default_client_ops = {
++const struct tty_port_client_operations tty_port_default_client_ops = {
+       .receive_buf = tty_port_default_receive_buf,
+       .write_wakeup = tty_port_default_wakeup,
+ };
++EXPORT_SYMBOL_GPL(tty_port_default_client_ops);
+ void tty_port_init(struct tty_port *port)
+ {
+@@ -67,7 +68,7 @@ void tty_port_init(struct tty_port *port
+       spin_lock_init(&port->lock);
+       port->close_delay = (50 * HZ) / 100;
+       port->closing_wait = (3000 * HZ) / 100;
+-      port->client_ops = &default_client_ops;
++      port->client_ops = &tty_port_default_client_ops;
+       kref_init(&port->kref);
+ }
+ EXPORT_SYMBOL(tty_port_init);
+--- a/include/linux/tty.h
++++ b/include/linux/tty.h
+@@ -224,6 +224,8 @@ struct tty_port_client_operations {
+       void (*write_wakeup)(struct tty_port *port);
+ };
++extern const struct tty_port_client_operations tty_port_default_client_ops;
++
+ struct tty_port {
+       struct tty_bufhead      buf;            /* Locked internally */
+       struct tty_struct       *tty;           /* Back pointer */
index 81b07317dde1efb0edb3003be98d8cfe71d646e2..bc41a4f6b1529e81d2a8df5a3c7aece28117e02c 100644 (file)
@@ -187,3 +187,10 @@ staging-rtl8188eu-fix-potential-security-hole.patch
 staging-rtl8188eu-fix-potential-overuse-of-kernel-memory.patch
 staging-rtl8723bs-fix-potential-security-hole.patch
 staging-rtl8723bs-fix-potential-overuse-of-kernel-memory.patch
+x86-mce-amd-publish-the-bank-pointer-only-after-setup-has-succeeded.patch
+x86-mce-amd-fix-kobject-lifetime.patch
+tty-serial-atmel-manage-shutdown-in-case-of-rs485-or-iso7816-mode.patch
+tty-serial-imx-setup-the-correct-sg-entry-for-tx-dma.patch
+serdev-ttyport-restore-client-ops-on-deregistration.patch
+maintainers-update-drm-i915-bug-filing-url.patch
+revert-ipc-sem-remove-uneeded-sem_undo_list-lock-usage-in-exit_sem.patch
diff --git a/queue-4.14/tty-serial-atmel-manage-shutdown-in-case-of-rs485-or-iso7816-mode.patch b/queue-4.14/tty-serial-atmel-manage-shutdown-in-case-of-rs485-or-iso7816-mode.patch
new file mode 100644 (file)
index 0000000..9239083
--- /dev/null
@@ -0,0 +1,36 @@
+From 04b5bfe3dc94e64d0590c54045815cb5183fb095 Mon Sep 17 00:00:00 2001
+From: Nicolas Ferre <nicolas.ferre@microchip.com>
+Date: Mon, 10 Feb 2020 16:20:53 +0100
+Subject: tty/serial: atmel: manage shutdown in case of RS485 or ISO7816 mode
+
+From: Nicolas Ferre <nicolas.ferre@microchip.com>
+
+commit 04b5bfe3dc94e64d0590c54045815cb5183fb095 upstream.
+
+In atmel_shutdown() we call atmel_stop_rx() and atmel_stop_tx() functions.
+Prevent the rx restart that is implemented in RS485 or ISO7816 modes when
+calling atmel_stop_tx() by using the atomic information tasklet_shutdown
+that is already in place for this purpose.
+
+Fixes: 98f2082c3ac4 ("tty/serial: atmel: enforce tasklet init and termination sequences")
+Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200210152053.8289-1-nicolas.ferre@microchip.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/atmel_serial.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/atmel_serial.c
++++ b/drivers/tty/serial/atmel_serial.c
+@@ -498,7 +498,8 @@ static void atmel_stop_tx(struct uart_po
+       atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
+       if (atmel_uart_is_half_duplex(port))
+-              atmel_start_rx(port);
++              if (!atomic_read(&atmel_port->tasklet_shutdown))
++                      atmel_start_rx(port);
+ }
diff --git a/queue-4.14/tty-serial-imx-setup-the-correct-sg-entry-for-tx-dma.patch b/queue-4.14/tty-serial-imx-setup-the-correct-sg-entry-for-tx-dma.patch
new file mode 100644 (file)
index 0000000..9cbe4b4
--- /dev/null
@@ -0,0 +1,110 @@
+From f76707831829530ffdd3888bebc108aecefccaa0 Mon Sep 17 00:00:00 2001
+From: Fugang Duan <fugang.duan@nxp.com>
+Date: Tue, 11 Feb 2020 14:16:01 +0800
+Subject: tty: serial: imx: setup the correct sg entry for tx dma
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fugang Duan <fugang.duan@nxp.com>
+
+commit f76707831829530ffdd3888bebc108aecefccaa0 upstream.
+
+There has oops as below happen on i.MX8MP EVK platform that has
+6G bytes DDR memory.
+
+when (xmit->tail < xmit->head) && (xmit->head == 0),
+it setups one sg entry with sg->length is zero:
+       sg_set_buf(sgl + 1, xmit->buf, xmit->head);
+
+if xmit->buf is allocated from >4G address space, and SDMA only
+support <4G address space, then dma_map_sg() will call swiotlb_map()
+to do bounce buffer copying and mapping.
+
+But swiotlb_map() don't allow sg entry's length is zero, otherwise
+report BUG_ON().
+
+So the patch is to correct the tx DMA scatter list.
+
+Oops:
+[  287.675715] kernel BUG at kernel/dma/swiotlb.c:497!
+[  287.680592] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
+[  287.686075] Modules linked in:
+[  287.689133] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.3-00016-g3fdc4e0-dirty #10
+[  287.696872] Hardware name: FSL i.MX8MP EVK (DT)
+[  287.701402] pstate: 80000085 (Nzcv daIf -PAN -UAO)
+[  287.706199] pc : swiotlb_tbl_map_single+0x1fc/0x310
+[  287.711076] lr : swiotlb_map+0x60/0x148
+[  287.714909] sp : ffff800010003c00
+[  287.718221] x29: ffff800010003c00 x28: 0000000000000000
+[  287.723533] x27: 0000000000000040 x26: ffff800011ae0000
+[  287.728844] x25: ffff800011ae09f8 x24: 0000000000000000
+[  287.734155] x23: 00000001b7af9000 x22: 0000000000000000
+[  287.739465] x21: ffff000176409c10 x20: 00000000001f7ffe
+[  287.744776] x19: ffff000176409c10 x18: 000000000000002e
+[  287.750087] x17: 0000000000000000 x16: 0000000000000000
+[  287.755397] x15: 0000000000000000 x14: 0000000000000000
+[  287.760707] x13: ffff00017f334000 x12: 0000000000000001
+[  287.766018] x11: 00000000001fffff x10: 0000000000000000
+[  287.771328] x9 : 0000000000000003 x8 : 0000000000000000
+[  287.776638] x7 : 0000000000000000 x6 : 0000000000000000
+[  287.781949] x5 : 0000000000200000 x4 : 0000000000000000
+[  287.787259] x3 : 0000000000000001 x2 : 00000001b7af9000
+[  287.792570] x1 : 00000000fbfff000 x0 : 0000000000000000
+[  287.797881] Call trace:
+[  287.800328]  swiotlb_tbl_map_single+0x1fc/0x310
+[  287.804859]  swiotlb_map+0x60/0x148
+[  287.808347]  dma_direct_map_page+0xf0/0x130
+[  287.812530]  dma_direct_map_sg+0x78/0xe0
+[  287.816453]  imx_uart_dma_tx+0x134/0x2f8
+[  287.820374]  imx_uart_dma_tx_callback+0xd8/0x168
+[  287.824992]  vchan_complete+0x194/0x200
+[  287.828828]  tasklet_action_common.isra.0+0x154/0x1a0
+[  287.833879]  tasklet_action+0x24/0x30
+[  287.837540]  __do_softirq+0x120/0x23c
+[  287.841202]  irq_exit+0xb8/0xd8
+[  287.844343]  __handle_domain_irq+0x64/0xb8
+[  287.848438]  gic_handle_irq+0x5c/0x148
+[  287.852185]  el1_irq+0xb8/0x180
+[  287.855327]  cpuidle_enter_state+0x84/0x360
+[  287.859508]  cpuidle_enter+0x34/0x48
+[  287.863083]  call_cpuidle+0x18/0x38
+[  287.866571]  do_idle+0x1e0/0x280
+[  287.869798]  cpu_startup_entry+0x20/0x40
+[  287.873721]  rest_init+0xd4/0xe0
+[  287.876949]  arch_call_rest_init+0xc/0x14
+[  287.880958]  start_kernel+0x420/0x44c
+[  287.884622] Code: 9124c021 9417aff8 a94363f7 17ffffd5 (d4210000)
+[  287.890718] ---[ end trace 5bc44c4ab6b009ce ]---
+[  287.895334] Kernel panic - not syncing: Fatal exception in interrupt
+[  287.901686] SMP: stopping secondary CPUs
+[  288.905607] SMP: failed to stop secondary CPUs 0-1
+[  288.910395] Kernel Offset: disabled
+[  288.913882] CPU features: 0x0002,2000200c
+[  288.917888] Memory Limit: none
+[  288.920944] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---
+
+Reported-by: Eagle Zhou <eagle.zhou@nxp.com>
+Tested-by: Eagle Zhou <eagle.zhou@nxp.com>
+Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
+Cc: stable <stable@vger.kernel.org>
+Fixes: 7942f8577f2a ("serial: imx: TX DMA: clean up sg initialization")
+Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/1581401761-6378-1-git-send-email-fugang.duan@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/imx.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -557,7 +557,7 @@ static void imx_dma_tx(struct imx_port *
+       sport->tx_bytes = uart_circ_chars_pending(xmit);
+-      if (xmit->tail < xmit->head) {
++      if (xmit->tail < xmit->head || xmit->head == 0) {
+               sport->dma_tx_nents = 1;
+               sg_init_one(sgl, xmit->buf + xmit->tail, sport->tx_bytes);
+       } else {
diff --git a/queue-4.14/x86-mce-amd-fix-kobject-lifetime.patch b/queue-4.14/x86-mce-amd-fix-kobject-lifetime.patch
new file mode 100644 (file)
index 0000000..e648910
--- /dev/null
@@ -0,0 +1,87 @@
+From 51dede9c05df2b78acd6dcf6a17d21f0877d2d7b Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Thu, 13 Feb 2020 19:01:34 +0100
+Subject: x86/mce/amd: Fix kobject lifetime
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit 51dede9c05df2b78acd6dcf6a17d21f0877d2d7b upstream.
+
+Accessing the MCA thresholding controls in sysfs concurrently with CPU
+hotplug can lead to a couple of KASAN-reported issues:
+
+  BUG: KASAN: use-after-free in sysfs_file_ops+0x155/0x180
+  Read of size 8 at addr ffff888367578940 by task grep/4019
+
+and
+
+  BUG: KASAN: use-after-free in show_error_count+0x15c/0x180
+  Read of size 2 at addr ffff888368a05514 by task grep/4454
+
+for example. Both result from the fact that the threshold block
+creation/teardown code frees the descriptor memory itself instead of
+defining proper ->release function and leaving it to the driver core to
+take care of that, after all sysfs accesses have completed.
+
+Do that and get rid of the custom freeing code, fixing the above UAFs in
+the process.
+
+  [ bp: write commit message. ]
+
+Fixes: 95268664390b ("[PATCH] x86_64: mce_amd support for family 0x10 processors")
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: <stable@vger.kernel.org>
+Link: https://lkml.kernel.org/r/20200214082801.13836-1-bp@alien8.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/cpu/mcheck/mce_amd.c |   17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
++++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
+@@ -1116,9 +1116,12 @@ static const struct sysfs_ops threshold_
+       .store                  = store,
+ };
++static void threshold_block_release(struct kobject *kobj);
++
+ static struct kobj_type threshold_ktype = {
+       .sysfs_ops              = &threshold_ops,
+       .default_attrs          = default_attrs,
++      .release                = threshold_block_release,
+ };
+ static const char *get_name(unsigned int bank, struct threshold_block *b)
+@@ -1320,8 +1323,12 @@ static int threshold_create_bank(unsigne
+       return err;
+ }
+-static void deallocate_threshold_block(unsigned int cpu,
+-                                               unsigned int bank)
++static void threshold_block_release(struct kobject *kobj)
++{
++      kfree(to_block(kobj));
++}
++
++static void deallocate_threshold_block(unsigned int cpu, unsigned int bank)
+ {
+       struct threshold_block *pos = NULL;
+       struct threshold_block *tmp = NULL;
+@@ -1331,13 +1338,11 @@ static void deallocate_threshold_block(u
+               return;
+       list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) {
+-              kobject_put(&pos->kobj);
+               list_del(&pos->miscj);
+-              kfree(pos);
++              kobject_put(&pos->kobj);
+       }
+-      kfree(per_cpu(threshold_banks, cpu)[bank]->blocks);
+-      per_cpu(threshold_banks, cpu)[bank]->blocks = NULL;
++      kobject_put(&head->blocks->kobj);
+ }
+ static void __threshold_remove_blocks(struct threshold_bank *b)
diff --git a/queue-4.14/x86-mce-amd-publish-the-bank-pointer-only-after-setup-has-succeeded.patch b/queue-4.14/x86-mce-amd-publish-the-bank-pointer-only-after-setup-has-succeeded.patch
new file mode 100644 (file)
index 0000000..1269572
--- /dev/null
@@ -0,0 +1,104 @@
+From 6e5cf31fbe651bed7ba1df768f2e123531132417 Mon Sep 17 00:00:00 2001
+From: Borislav Petkov <bp@suse.de>
+Date: Tue, 4 Feb 2020 13:28:41 +0100
+Subject: x86/mce/amd: Publish the bank pointer only after setup has succeeded
+
+From: Borislav Petkov <bp@suse.de>
+
+commit 6e5cf31fbe651bed7ba1df768f2e123531132417 upstream.
+
+threshold_create_bank() creates a bank descriptor per MCA error
+thresholding counter which can be controlled over sysfs. It publishes
+the pointer to that bank in a per-CPU variable and then goes on to
+create additional thresholding blocks if the bank has such.
+
+However, that creation of additional blocks in
+allocate_threshold_blocks() can fail, leading to a use-after-free
+through the per-CPU pointer.
+
+Therefore, publish that pointer only after all blocks have been setup
+successfully.
+
+Fixes: 019f34fccfd5 ("x86, MCE, AMD: Move shared bank to node descriptor")
+Reported-by: Saar Amar <Saar.Amar@microsoft.com>
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: <stable@vger.kernel.org>
+Link: http://lkml.kernel.org/r/20200128140846.phctkvx5btiexvbx@kili.mountain
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/cpu/mcheck/mce_amd.c |   33 ++++++++++++++++-----------------
+ 1 file changed, 16 insertions(+), 17 deletions(-)
+
+--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
++++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
+@@ -1151,8 +1151,9 @@ static const char *get_name(unsigned int
+       return buf_mcatype;
+ }
+-static int allocate_threshold_blocks(unsigned int cpu, unsigned int bank,
+-                                   unsigned int block, u32 address)
++static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb,
++                                   unsigned int bank, unsigned int block,
++                                   u32 address)
+ {
+       struct threshold_block *b = NULL;
+       u32 low, high;
+@@ -1196,16 +1197,12 @@ static int allocate_threshold_blocks(uns
+       INIT_LIST_HEAD(&b->miscj);
+-      if (per_cpu(threshold_banks, cpu)[bank]->blocks) {
+-              list_add(&b->miscj,
+-                       &per_cpu(threshold_banks, cpu)[bank]->blocks->miscj);
+-      } else {
+-              per_cpu(threshold_banks, cpu)[bank]->blocks = b;
+-      }
++      if (tb->blocks)
++              list_add(&b->miscj, &tb->blocks->miscj);
++      else
++              tb->blocks = b;
+-      err = kobject_init_and_add(&b->kobj, &threshold_ktype,
+-                                 per_cpu(threshold_banks, cpu)[bank]->kobj,
+-                                 get_name(bank, b));
++      err = kobject_init_and_add(&b->kobj, &threshold_ktype, tb->kobj, get_name(bank, b));
+       if (err)
+               goto out_free;
+ recurse:
+@@ -1213,7 +1210,7 @@ recurse:
+       if (!address)
+               return 0;
+-      err = allocate_threshold_blocks(cpu, bank, block, address);
++      err = allocate_threshold_blocks(cpu, tb, bank, block, address);
+       if (err)
+               goto out_free;
+@@ -1298,8 +1295,6 @@ static int threshold_create_bank(unsigne
+               goto out_free;
+       }
+-      per_cpu(threshold_banks, cpu)[bank] = b;
+-
+       if (is_shared_bank(bank)) {
+               refcount_set(&b->cpus, 1);
+@@ -1310,9 +1305,13 @@ static int threshold_create_bank(unsigne
+               }
+       }
+-      err = allocate_threshold_blocks(cpu, bank, 0, msr_ops.misc(bank));
+-      if (!err)
+-              goto out;
++      err = allocate_threshold_blocks(cpu, b, bank, 0, msr_ops.misc(bank));
++      if (err)
++              goto out_free;
++
++      per_cpu(threshold_banks, cpu)[bank] = b;
++
++      return 0;
+  out_free:
+       kfree(b);