--- /dev/null
+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
--- /dev/null
+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++) {
--- /dev/null
+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 */
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
--- /dev/null
+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);
+
+ }
+
--- /dev/null
+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 {
--- /dev/null
+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)
--- /dev/null
+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);