drm-amd-display-reset-dmcub-before-hw-init.patch
drm-amd-display-optimize-bandwidth-on-following-fast-update.patch
drm-amd-display-fix-surface-optimization-regression-on-carrizo.patch
+x86-amd-use-ibpb-for-firmware-calls.patch
+x86-alternative-report-missing-return-thunk-details.patch
+watchqueue-make-sure-to-serialize-wqueue-defunct-properly.patch
+tty-drivers-tty-stop-using-tty_schedule_flip.patch
+tty-the-rest-stop-using-tty_schedule_flip.patch
+tty-drop-tty_schedule_flip.patch
+tty-extract-tty_flip_buffer_commit-from-tty_flip_buffer_push.patch
+tty-use-new-tty_insert_flip_string_and_push_buffer-in-pty_write.patch
--- /dev/null
+From 5f6a85158ccacc3f09744b3aafe8b11ab3b6c6f6 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Mon, 22 Nov 2021 12:16:46 +0100
+Subject: tty: drivers/tty/, stop using tty_schedule_flip()
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit 5f6a85158ccacc3f09744b3aafe8b11ab3b6c6f6 upstream.
+
+Since commit a9c3f68f3cd8d (tty: Fix low_latency BUG) in 2014,
+tty_flip_buffer_push() is only a wrapper to tty_schedule_flip(). We are
+going to remove the latter (as it is used less), so call the former in
+drivers/tty/.
+
+Cc: Vladimir Zapolskiy <vz@mleia.com>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Link: https://lore.kernel.org/r/20211122111648.30379-2-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/goldfish.c | 2 +-
+ drivers/tty/moxa.c | 4 ++--
+ drivers/tty/serial/lpc32xx_hs.c | 2 +-
+ drivers/tty/vt/keyboard.c | 6 +++---
+ drivers/tty/vt/vt.c | 2 +-
+ 5 files changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/tty/goldfish.c
++++ b/drivers/tty/goldfish.c
+@@ -151,7 +151,7 @@ static irqreturn_t goldfish_tty_interrup
+ address = (unsigned long)(void *)buf;
+ goldfish_tty_rw(qtty, address, count, 0);
+
+- tty_schedule_flip(&qtty->port);
++ tty_flip_buffer_push(&qtty->port);
+ return IRQ_HANDLED;
+ }
+
+--- a/drivers/tty/moxa.c
++++ b/drivers/tty/moxa.c
+@@ -1383,7 +1383,7 @@ static int moxa_poll_port(struct moxa_po
+ if (inited && !tty_throttled(tty) &&
+ MoxaPortRxQueue(p) > 0) { /* RX */
+ MoxaPortReadData(p);
+- tty_schedule_flip(&p->port);
++ tty_flip_buffer_push(&p->port);
+ }
+ } else {
+ clear_bit(EMPTYWAIT, &p->statusflags);
+@@ -1408,7 +1408,7 @@ static int moxa_poll_port(struct moxa_po
+
+ if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */
+ tty_insert_flip_char(&p->port, 0, TTY_BREAK);
+- tty_schedule_flip(&p->port);
++ tty_flip_buffer_push(&p->port);
+ }
+
+ if (intr & IntrLine)
+--- a/drivers/tty/serial/lpc32xx_hs.c
++++ b/drivers/tty/serial/lpc32xx_hs.c
+@@ -341,7 +341,7 @@ static irqreturn_t serial_lpc32xx_interr
+ LPC32XX_HSUART_IIR(port->membase));
+ port->icount.overrun++;
+ tty_insert_flip_char(tport, 0, TTY_OVERRUN);
+- tty_schedule_flip(tport);
++ tty_flip_buffer_push(tport);
+ }
+
+ /* Data received? */
+--- a/drivers/tty/vt/keyboard.c
++++ b/drivers/tty/vt/keyboard.c
+@@ -324,13 +324,13 @@ int kbd_rate(struct kbd_repeat *rpt)
+ static void put_queue(struct vc_data *vc, int ch)
+ {
+ tty_insert_flip_char(&vc->port, ch, 0);
+- tty_schedule_flip(&vc->port);
++ tty_flip_buffer_push(&vc->port);
+ }
+
+ static void puts_queue(struct vc_data *vc, const char *cp)
+ {
+ tty_insert_flip_string(&vc->port, cp, strlen(cp));
+- tty_schedule_flip(&vc->port);
++ tty_flip_buffer_push(&vc->port);
+ }
+
+ static void applkey(struct vc_data *vc, int key, char mode)
+@@ -584,7 +584,7 @@ static void fn_inc_console(struct vc_dat
+ static void fn_send_intr(struct vc_data *vc)
+ {
+ tty_insert_flip_char(&vc->port, 0, TTY_BREAK);
+- tty_schedule_flip(&vc->port);
++ tty_flip_buffer_push(&vc->port);
+ }
+
+ static void fn_scroll_forw(struct vc_data *vc)
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -1833,7 +1833,7 @@ static void csi_m(struct vc_data *vc)
+ static void respond_string(const char *p, size_t len, struct tty_port *port)
+ {
+ tty_insert_flip_string(port, p, len);
+- tty_schedule_flip(port);
++ tty_flip_buffer_push(port);
+ }
+
+ static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
--- /dev/null
+From 5db96ef23bda6c2a61a51693c85b78b52d03f654 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Mon, 22 Nov 2021 12:16:48 +0100
+Subject: tty: drop tty_schedule_flip()
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit 5db96ef23bda6c2a61a51693c85b78b52d03f654 upstream.
+
+Since commit a9c3f68f3cd8d (tty: Fix low_latency BUG) in 2014,
+tty_flip_buffer_push() is only a wrapper to tty_schedule_flip(). All
+users were converted in the previous patches, so remove
+tty_schedule_flip() completely while inlining its body into
+tty_flip_buffer_push().
+
+One less exported function.
+
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Link: https://lore.kernel.org/r/20211122111648.30379-4-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/tty_buffer.c | 30 ++++++++----------------------
+ include/linux/tty_flip.h | 1 -
+ 2 files changed, 8 insertions(+), 23 deletions(-)
+
+--- a/drivers/tty/tty_buffer.c
++++ b/drivers/tty/tty_buffer.c
+@@ -403,27 +403,6 @@ int __tty_insert_flip_char(struct tty_po
+ EXPORT_SYMBOL(__tty_insert_flip_char);
+
+ /**
+- * tty_schedule_flip - push characters to ldisc
+- * @port: tty port to push from
+- *
+- * Takes any pending buffers and transfers their ownership to the
+- * ldisc side of the queue. It then schedules those characters for
+- * processing by the line discipline.
+- */
+-
+-void tty_schedule_flip(struct tty_port *port)
+-{
+- struct tty_bufhead *buf = &port->buf;
+-
+- /* paired w/ acquire in flush_to_ldisc(); ensures
+- * flush_to_ldisc() sees buffer data.
+- */
+- smp_store_release(&buf->tail->commit, buf->tail->used);
+- queue_work(system_unbound_wq, &buf->work);
+-}
+-EXPORT_SYMBOL(tty_schedule_flip);
+-
+-/**
+ * tty_prepare_flip_string - make room for characters
+ * @port: tty port
+ * @chars: return pointer for character write area
+@@ -567,7 +546,14 @@ static void flush_to_ldisc(struct work_s
+
+ void tty_flip_buffer_push(struct tty_port *port)
+ {
+- tty_schedule_flip(port);
++ struct tty_bufhead *buf = &port->buf;
++
++ /*
++ * Paired w/ acquire in flush_to_ldisc(); ensures flush_to_ldisc() sees
++ * buffer data.
++ */
++ smp_store_release(&buf->tail->commit, buf->tail->used);
++ queue_work(system_unbound_wq, &buf->work);
+ }
+ EXPORT_SYMBOL(tty_flip_buffer_push);
+
+--- a/include/linux/tty_flip.h
++++ b/include/linux/tty_flip.h
+@@ -17,7 +17,6 @@ extern int tty_insert_flip_string_fixed_
+ extern int tty_prepare_flip_string(struct tty_port *port,
+ unsigned char **chars, size_t size);
+ extern void tty_flip_buffer_push(struct tty_port *port);
+-void tty_schedule_flip(struct tty_port *port);
+ int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag);
+
+ static inline int tty_insert_flip_char(struct tty_port *port,
--- /dev/null
+From 716b10580283fda66f2b88140e3964f8a7f9da89 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Thu, 7 Jul 2022 10:25:57 +0200
+Subject: tty: extract tty_flip_buffer_commit() from tty_flip_buffer_push()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit 716b10580283fda66f2b88140e3964f8a7f9da89 upstream.
+
+We will need this new helper in the next patch.
+
+Cc: Hillf Danton <hdanton@sina.com>
+Cc: 一只狗 <chennbnbnb@gmail.com>
+Cc: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Link: https://lore.kernel.org/r/20220707082558.9250-1-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/tty_buffer.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/tty/tty_buffer.c
++++ b/drivers/tty/tty_buffer.c
+@@ -533,6 +533,15 @@ static void flush_to_ldisc(struct work_s
+
+ }
+
++static inline void tty_flip_buffer_commit(struct tty_buffer *tail)
++{
++ /*
++ * Paired w/ acquire in flush_to_ldisc(); ensures flush_to_ldisc() sees
++ * buffer data.
++ */
++ smp_store_release(&tail->commit, tail->used);
++}
++
+ /**
+ * tty_flip_buffer_push - terminal
+ * @port: tty port to push
+@@ -548,11 +557,7 @@ void tty_flip_buffer_push(struct tty_por
+ {
+ struct tty_bufhead *buf = &port->buf;
+
+- /*
+- * Paired w/ acquire in flush_to_ldisc(); ensures flush_to_ldisc() sees
+- * buffer data.
+- */
+- smp_store_release(&buf->tail->commit, buf->tail->used);
++ tty_flip_buffer_commit(buf->tail);
+ queue_work(system_unbound_wq, &buf->work);
+ }
+ EXPORT_SYMBOL(tty_flip_buffer_push);
--- /dev/null
+From b68b914494df4f79b4e9b58953110574af1cb7a2 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Mon, 22 Nov 2021 12:16:47 +0100
+Subject: tty: the rest, stop using tty_schedule_flip()
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit b68b914494df4f79b4e9b58953110574af1cb7a2 upstream.
+
+Since commit a9c3f68f3cd8d (tty: Fix low_latency BUG) in 2014,
+tty_flip_buffer_push() is only a wrapper to tty_schedule_flip(). We are
+going to remove the latter (as it is used less), so call the former in
+the rest of the users.
+
+Cc: Richard Henderson <rth@twiddle.net>
+Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
+Cc: Matt Turner <mattst88@gmail.com>
+Cc: William Hubbs <w.d.hubbs@gmail.com>
+Cc: Chris Brannon <chris@the-brannons.com>
+Cc: Kirk Reiser <kirk@reisers.ca>
+Cc: Samuel Thibault <samuel.thibault@ens-lyon.org>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Cc: Christian Borntraeger <borntraeger@de.ibm.com>
+Cc: Alexander Gordeev <agordeev@linux.ibm.com>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Link: https://lore.kernel.org/r/20211122111648.30379-3-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/alpha/kernel/srmcons.c | 2 +-
+ drivers/accessibility/speakup/spk_ttyio.c | 4 ++--
+ drivers/s390/char/keyboard.h | 4 ++--
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/arch/alpha/kernel/srmcons.c
++++ b/arch/alpha/kernel/srmcons.c
+@@ -59,7 +59,7 @@ srmcons_do_receive_chars(struct tty_port
+ } while((result.bits.status & 1) && (++loops < 10));
+
+ if (count)
+- tty_schedule_flip(port);
++ tty_flip_buffer_push(port);
+
+ return count;
+ }
+--- a/drivers/accessibility/speakup/spk_ttyio.c
++++ b/drivers/accessibility/speakup/spk_ttyio.c
+@@ -88,7 +88,7 @@ static int spk_ttyio_receive_buf2(struct
+ }
+
+ if (!ldisc_data->buf_free)
+- /* ttyio_in will tty_schedule_flip */
++ /* ttyio_in will tty_flip_buffer_push */
+ return 0;
+
+ /* Make sure the consumer has read buf before we have seen
+@@ -312,7 +312,7 @@ static unsigned char ttyio_in(struct spk
+ mb();
+ ldisc_data->buf_free = true;
+ /* Let TTY push more characters */
+- tty_schedule_flip(tty->port);
++ tty_flip_buffer_push(tty->port);
+
+ return rv;
+ }
+--- a/drivers/s390/char/keyboard.h
++++ b/drivers/s390/char/keyboard.h
+@@ -56,7 +56,7 @@ static inline void
+ kbd_put_queue(struct tty_port *port, int ch)
+ {
+ tty_insert_flip_char(port, ch, 0);
+- tty_schedule_flip(port);
++ tty_flip_buffer_push(port);
+ }
+
+ static inline void
+@@ -64,5 +64,5 @@ kbd_puts_queue(struct tty_port *port, ch
+ {
+ while (*cp)
+ tty_insert_flip_char(port, *cp++, 0);
+- tty_schedule_flip(port);
++ tty_flip_buffer_push(port);
+ }
--- /dev/null
+From a501ab75e7624d133a5a3c7ec010687c8b961d23 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Thu, 7 Jul 2022 10:25:58 +0200
+Subject: tty: use new tty_insert_flip_string_and_push_buffer() in pty_write()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit a501ab75e7624d133a5a3c7ec010687c8b961d23 upstream.
+
+There is a race in pty_write(). pty_write() can be called in parallel
+with e.g. ioctl(TIOCSTI) or ioctl(TCXONC) which also inserts chars to
+the buffer. Provided, tty_flip_buffer_push() in pty_write() is called
+outside the lock, it can commit inconsistent tail. This can lead to out
+of bounds writes and other issues. See the Link below.
+
+To fix this, we have to introduce a new helper called
+tty_insert_flip_string_and_push_buffer(). It does both
+tty_insert_flip_string() and tty_flip_buffer_commit() under the port
+lock. It also calls queue_work(), but outside the lock. See
+71a174b39f10 (pty: do tty_flip_buffer_push without port->lock in
+pty_write) for the reasons.
+
+Keep the helper internal-only (in drivers' tty.h). It is not intended to
+be used widely.
+
+Link: https://seclists.org/oss-sec/2022/q2/155
+Fixes: 71a174b39f10 (pty: do tty_flip_buffer_push without port->lock in pty_write)
+Cc: 一只狗 <chennbnbnb@gmail.com>
+Cc: Dan Carpenter <dan.carpenter@oracle.com>
+Suggested-by: Hillf Danton <hdanton@sina.com>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Link: https://lore.kernel.org/r/20220707082558.9250-2-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/pty.c | 14 ++------------
+ drivers/tty/tty.h | 3 +++
+ drivers/tty/tty_buffer.c | 31 +++++++++++++++++++++++++++++++
+ 3 files changed, 36 insertions(+), 12 deletions(-)
+
+--- a/drivers/tty/pty.c
++++ b/drivers/tty/pty.c
+@@ -111,21 +111,11 @@ static void pty_unthrottle(struct tty_st
+ static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
+ {
+ struct tty_struct *to = tty->link;
+- unsigned long flags;
+
+- if (tty->flow.stopped)
++ if (tty->flow.stopped || !c)
+ return 0;
+
+- if (c > 0) {
+- spin_lock_irqsave(&to->port->lock, flags);
+- /* Stuff the data into the input queue of the other end */
+- c = tty_insert_flip_string(to->port, buf, c);
+- spin_unlock_irqrestore(&to->port->lock, flags);
+- /* And shovel */
+- if (c)
+- tty_flip_buffer_push(to->port);
+- }
+- return c;
++ return tty_insert_flip_string_and_push_buffer(to->port, buf, c);
+ }
+
+ /**
+--- a/drivers/tty/tty.h
++++ b/drivers/tty/tty.h
+@@ -111,4 +111,7 @@ static inline void tty_audit_tiocsti(str
+
+ ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *);
+
++int tty_insert_flip_string_and_push_buffer(struct tty_port *port,
++ const unsigned char *chars, size_t cnt);
++
+ #endif
+--- a/drivers/tty/tty_buffer.c
++++ b/drivers/tty/tty_buffer.c
+@@ -563,6 +563,37 @@ void tty_flip_buffer_push(struct tty_por
+ EXPORT_SYMBOL(tty_flip_buffer_push);
+
+ /**
++ * tty_insert_flip_string_and_push_buffer - add characters to the tty buffer and
++ * push
++ * @port: tty port
++ * @chars: characters
++ * @size: size
++ *
++ * The function combines tty_insert_flip_string() and tty_flip_buffer_push()
++ * with the exception of properly holding the @port->lock.
++ *
++ * To be used only internally (by pty currently).
++ *
++ * Returns: the number added.
++ */
++int tty_insert_flip_string_and_push_buffer(struct tty_port *port,
++ const unsigned char *chars, size_t size)
++{
++ struct tty_bufhead *buf = &port->buf;
++ unsigned long flags;
++
++ spin_lock_irqsave(&port->lock, flags);
++ size = tty_insert_flip_string(port, chars, size);
++ if (size)
++ tty_flip_buffer_commit(buf->tail);
++ spin_unlock_irqrestore(&port->lock, flags);
++
++ queue_work(system_unbound_wq, &buf->work);
++
++ return size;
++}
++
++/**
+ * tty_buffer_init - prepare a tty buffer structure
+ * @port: tty port to initialise
+ *
--- /dev/null
+From 353f7988dd8413c47718f7ca79c030b6fb62cfe5 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Tue, 19 Jul 2022 11:09:01 -0700
+Subject: watchqueue: make sure to serialize 'wqueue->defunct' properly
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 353f7988dd8413c47718f7ca79c030b6fb62cfe5 upstream.
+
+When the pipe is closed, we mark the associated watchqueue defunct by
+calling watch_queue_clear(). However, while that is protected by the
+watchqueue lock, new watchqueue entries aren't actually added under that
+lock at all: they use the pipe->rd_wait.lock instead, and looking up
+that pipe happens without any locking.
+
+The watchqueue code uses the RCU read-side section to make sure that the
+wqueue entry itself hasn't disappeared, but that does not protect the
+pipe_info in any way.
+
+So make sure to actually hold the wqueue lock when posting watch events,
+properly serializing against the pipe being torn down.
+
+Reported-by: Noam Rathaus <noamr@ssd-disclosure.com>
+Cc: Greg KH <gregkh@linuxfoundation.org>
+Cc: David Howells <dhowells@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/watch_queue.c | 53 +++++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 37 insertions(+), 16 deletions(-)
+
+--- a/kernel/watch_queue.c
++++ b/kernel/watch_queue.c
+@@ -34,6 +34,27 @@ MODULE_LICENSE("GPL");
+ #define WATCH_QUEUE_NOTE_SIZE 128
+ #define WATCH_QUEUE_NOTES_PER_PAGE (PAGE_SIZE / WATCH_QUEUE_NOTE_SIZE)
+
++/*
++ * This must be called under the RCU read-lock, which makes
++ * sure that the wqueue still exists. It can then take the lock,
++ * and check that the wqueue hasn't been destroyed, which in
++ * turn makes sure that the notification pipe still exists.
++ */
++static inline bool lock_wqueue(struct watch_queue *wqueue)
++{
++ spin_lock_bh(&wqueue->lock);
++ if (unlikely(wqueue->defunct)) {
++ spin_unlock_bh(&wqueue->lock);
++ return false;
++ }
++ return true;
++}
++
++static inline void unlock_wqueue(struct watch_queue *wqueue)
++{
++ spin_unlock_bh(&wqueue->lock);
++}
++
+ static void watch_queue_pipe_buf_release(struct pipe_inode_info *pipe,
+ struct pipe_buffer *buf)
+ {
+@@ -69,6 +90,10 @@ static const struct pipe_buf_operations
+
+ /*
+ * Post a notification to a watch queue.
++ *
++ * Must be called with the RCU lock for reading, and the
++ * watch_queue lock held, which guarantees that the pipe
++ * hasn't been released.
+ */
+ static bool post_one_notification(struct watch_queue *wqueue,
+ struct watch_notification *n)
+@@ -85,9 +110,6 @@ static bool post_one_notification(struct
+
+ spin_lock_irq(&pipe->rd_wait.lock);
+
+- if (wqueue->defunct)
+- goto out;
+-
+ mask = pipe->ring_size - 1;
+ head = pipe->head;
+ tail = pipe->tail;
+@@ -203,7 +225,10 @@ void __post_watch_notification(struct wa
+ if (security_post_notification(watch->cred, cred, n) < 0)
+ continue;
+
+- post_one_notification(wqueue, n);
++ if (lock_wqueue(wqueue)) {
++ post_one_notification(wqueue, n);
++ unlock_wqueue(wqueue);;
++ }
+ }
+
+ rcu_read_unlock();
+@@ -465,11 +490,12 @@ int add_watch_to_object(struct watch *wa
+ return -EAGAIN;
+ }
+
+- spin_lock_bh(&wqueue->lock);
+- kref_get(&wqueue->usage);
+- kref_get(&watch->usage);
+- hlist_add_head(&watch->queue_node, &wqueue->watches);
+- spin_unlock_bh(&wqueue->lock);
++ if (lock_wqueue(wqueue)) {
++ kref_get(&wqueue->usage);
++ kref_get(&watch->usage);
++ hlist_add_head(&watch->queue_node, &wqueue->watches);
++ unlock_wqueue(wqueue);
++ }
+
+ hlist_add_head(&watch->list_node, &wlist->watchers);
+ return 0;
+@@ -523,20 +549,15 @@ found:
+
+ wqueue = rcu_dereference(watch->queue);
+
+- /* We don't need the watch list lock for the next bit as RCU is
+- * protecting *wqueue from deallocation.
+- */
+- if (wqueue) {
++ if (lock_wqueue(wqueue)) {
+ post_one_notification(wqueue, &n.watch);
+
+- spin_lock_bh(&wqueue->lock);
+-
+ if (!hlist_unhashed(&watch->queue_node)) {
+ hlist_del_init_rcu(&watch->queue_node);
+ put_watch(watch);
+ }
+
+- spin_unlock_bh(&wqueue->lock);
++ unlock_wqueue(wqueue);
+ }
+
+ if (wlist->release_watch) {
--- /dev/null
+From 65cdf0d623bedf0e069bb64ed52e8bb20105e2ba Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Wed, 13 Jul 2022 14:38:19 -0700
+Subject: x86/alternative: Report missing return thunk details
+
+From: Kees Cook <keescook@chromium.org>
+
+commit 65cdf0d623bedf0e069bb64ed52e8bb20105e2ba upstream.
+
+Debugging missing return thunks is easier if we can see where they're
+happening.
+
+Suggested-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/lkml/Ys66hwtFcGbYmoiZ@hirez.programming.kicks-ass.net/
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kernel/alternative.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/alternative.c
++++ b/arch/x86/kernel/alternative.c
+@@ -554,7 +554,9 @@ void __init_or_module noinline apply_ret
+ dest = addr + insn.length + insn.immediate.value;
+
+ if (__static_call_fixup(addr, op, dest) ||
+- WARN_ON_ONCE(dest != &__x86_return_thunk))
++ WARN_ONCE(dest != &__x86_return_thunk,
++ "missing return thunk: %pS-%pS: %*ph",
++ addr, dest, 5, addr))
+ continue;
+
+ DPRINTK("return thunk at: %pS (%px) len: %d to: %pS",
--- /dev/null
+From 28a99e95f55c61855983d36a88c05c178d966bb7 Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Mon, 18 Jul 2022 13:41:37 +0200
+Subject: x86/amd: Use IBPB for firmware calls
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+commit 28a99e95f55c61855983d36a88c05c178d966bb7 upstream.
+
+On AMD IBRS does not prevent Retbleed; as such use IBPB before a
+firmware call to flush the branch history state.
+
+And because in order to do an EFI call, the kernel maps a whole lot of
+the kernel page table into the EFI page table, do an IBPB just in case
+in order to prevent the scenario of poisoning the BTB and causing an EFI
+call using the unprotected RET there.
+
+ [ bp: Massage. ]
+
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Link: https://lore.kernel.org/r/20220715194550.793957-1-cascardo@canonical.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/cpufeatures.h | 1 +
+ arch/x86/include/asm/nospec-branch.h | 2 ++
+ arch/x86/kernel/cpu/bugs.c | 11 ++++++++++-
+ 3 files changed, 13 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/include/asm/cpufeatures.h
++++ b/arch/x86/include/asm/cpufeatures.h
+@@ -300,6 +300,7 @@
+ #define X86_FEATURE_RETPOLINE_LFENCE (11*32+13) /* "" Use LFENCE for Spectre variant 2 */
+ #define X86_FEATURE_RETHUNK (11*32+14) /* "" Use REturn THUNK */
+ #define X86_FEATURE_UNRET (11*32+15) /* "" AMD BTB untrain return */
++#define X86_FEATURE_USE_IBPB_FW (11*32+16) /* "" Use IBPB during runtime firmware calls */
+
+ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
+ #define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
+--- a/arch/x86/include/asm/nospec-branch.h
++++ b/arch/x86/include/asm/nospec-branch.h
+@@ -298,6 +298,8 @@ do { \
+ alternative_msr_write(MSR_IA32_SPEC_CTRL, \
+ spec_ctrl_current() | SPEC_CTRL_IBRS, \
+ X86_FEATURE_USE_IBRS_FW); \
++ alternative_msr_write(MSR_IA32_PRED_CMD, PRED_CMD_IBPB, \
++ X86_FEATURE_USE_IBPB_FW); \
+ } while (0)
+
+ #define firmware_restrict_branch_speculation_end() \
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -1512,7 +1512,16 @@ static void __init spectre_v2_select_mit
+ * the CPU supports Enhanced IBRS, kernel might un-intentionally not
+ * enable IBRS around firmware calls.
+ */
+- if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_ibrs_mode(mode)) {
++ if (boot_cpu_has_bug(X86_BUG_RETBLEED) &&
++ (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
++ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)) {
++
++ if (retbleed_cmd != RETBLEED_CMD_IBPB) {
++ setup_force_cpu_cap(X86_FEATURE_USE_IBPB_FW);
++ pr_info("Enabling Speculation Barrier for firmware calls\n");
++ }
++
++ } else if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_ibrs_mode(mode)) {
+ setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW);
+ pr_info("Enabling Restricted Speculation for firmware calls\n");
+ }