--- /dev/null
+From fdf87a0dc26d0550c60edc911cda42f9afec3557 Mon Sep 17 00:00:00 2001
+From: Nikita Shubin <nikita.shubin@maquefel.me>
+Date: Mon, 5 Feb 2024 11:23:34 +0100
+Subject: ARM: ep93xx: Add terminator to gpiod_lookup_table
+
+From: Nikita Shubin <nikita.shubin@maquefel.me>
+
+commit fdf87a0dc26d0550c60edc911cda42f9afec3557 upstream.
+
+Without the terminator, if a con_id is passed to gpio_find() that
+does not exist in the lookup table the function will not stop looping
+correctly, and eventually cause an oops.
+
+Cc: stable@vger.kernel.org
+Fixes: b2e63555592f ("i2c: gpio: Convert to use descriptors")
+Reported-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Acked-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
+Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
+Link: https://lore.kernel.org/r/20240205102337.439002-1-alexander.sverdlin@gmail.com
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm/mach-ep93xx/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm/mach-ep93xx/core.c
++++ b/arch/arm/mach-ep93xx/core.c
+@@ -339,6 +339,7 @@ static struct gpiod_lookup_table ep93xx_
+ GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
+ GPIO_LOOKUP_IDX("G", 0, NULL, 1,
+ GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
++ { }
+ },
+ };
+
--- /dev/null
+From 66ad2fbcdbeab0edfd40c5d94f32f053b98c2320 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Sat, 24 Feb 2024 14:48:03 +0100
+Subject: dm-integrity, dm-verity: reduce stack usage for recheck
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 66ad2fbcdbeab0edfd40c5d94f32f053b98c2320 upstream.
+
+The newly added integrity_recheck() function has another larger stack
+allocation, just like its caller integrity_metadata(). When it gets
+inlined, the combination of the two exceeds the warning limit for 32-bit
+architectures and possibly risks an overflow when this is called from
+a deep call chain through a file system:
+
+drivers/md/dm-integrity.c:1767:13: error: stack frame size (1048) exceeds limit (1024) in 'integrity_metadata' [-Werror,-Wframe-larger-than]
+ 1767 | static void integrity_metadata(struct work_struct *w)
+
+Since the caller at this point is done using its checksum buffer,
+just reuse the same buffer in the new function to avoid the double
+allocation.
+
+[Mikulas: add "noinline" to integrity_recheck and verity_recheck.
+These functions are only called on error, so they shouldn't bloat the
+stack frame or code size of the caller.]
+
+Fixes: c88f5e553fe3 ("dm-integrity: recheck the integrity tag after a failure")
+Fixes: 9177f3c0dea6 ("dm-verity: recheck the hash after a failure")
+Cc: stable@vger.kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/md/dm-integrity.c | 10 ++++------
+ drivers/md/dm-verity-target.c | 4 ++--
+ 2 files changed, 6 insertions(+), 8 deletions(-)
+
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -1701,14 +1701,13 @@ failed:
+ get_random_bytes(result, ic->tag_size);
+ }
+
+-static void integrity_recheck(struct dm_integrity_io *dio)
++static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checksum)
+ {
+ struct bio *bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io));
+ struct dm_integrity_c *ic = dio->ic;
+ struct bvec_iter iter;
+ struct bio_vec bv;
+ sector_t sector, logical_sector, area, offset;
+- char checksum_onstack[max_t(size_t, HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)];
+ struct page *page;
+ void *buffer;
+
+@@ -1744,9 +1743,8 @@ static void integrity_recheck(struct dm_
+ goto free_ret;
+ }
+
+- integrity_sector_checksum(ic, logical_sector, buffer,
+- checksum_onstack);
+- r = dm_integrity_rw_tag(ic, checksum_onstack, &dio->metadata_block,
++ integrity_sector_checksum(ic, logical_sector, buffer, checksum);
++ r = dm_integrity_rw_tag(ic, checksum, &dio->metadata_block,
+ &dio->metadata_offset, ic->tag_size, TAG_CMP);
+ if (r) {
+ if (r > 0) {
+@@ -1859,7 +1857,7 @@ again:
+ checksums_ptr - checksums, dio->op == REQ_OP_READ ? TAG_CMP : TAG_WRITE);
+ if (unlikely(r)) {
+ if (r > 0) {
+- integrity_recheck(dio);
++ integrity_recheck(dio, checksums);
+ goto skip_io;
+ }
+ if (likely(checksums != checksums_onstack))
+--- a/drivers/md/dm-verity-target.c
++++ b/drivers/md/dm-verity-target.c
+@@ -483,8 +483,8 @@ static int verity_recheck_copy(struct dm
+ return 0;
+ }
+
+-static int verity_recheck(struct dm_verity *v, struct dm_verity_io *io,
+- struct bvec_iter start, sector_t cur_block)
++static noinline int verity_recheck(struct dm_verity *v, struct dm_verity_io *io,
++ struct bvec_iter start, sector_t cur_block)
+ {
+ struct page *page;
+ void *buffer;
--- /dev/null
+From 56ee7db31187dc36d501622cb5f1415e88e01c2a Mon Sep 17 00:00:00 2001
+From: Sandeep Dhavale <dhavale@google.com>
+Date: Wed, 21 Feb 2024 13:03:47 -0800
+Subject: erofs: fix refcount on the metabuf used for inode lookup
+
+From: Sandeep Dhavale <dhavale@google.com>
+
+commit 56ee7db31187dc36d501622cb5f1415e88e01c2a upstream.
+
+In erofs_find_target_block() when erofs_dirnamecmp() returns 0,
+we do not assign the target metabuf. This causes the caller
+erofs_namei()'s erofs_put_metabuf() at the end to be not effective
+leaving the refcount on the page.
+As the page from metabuf (buf->page) is never put, such page cannot be
+migrated or reclaimed. Fix it now by putting the metabuf from
+previous loop and assigning the current metabuf to target before
+returning so caller erofs_namei() can do the final put as it was
+intended.
+
+Fixes: 500edd095648 ("erofs: use meta buffers for inode lookup")
+Cc: <stable@vger.kernel.org> # 5.18+
+Signed-off-by: Sandeep Dhavale <dhavale@google.com>
+Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Link: https://lore.kernel.org/r/20240221210348.3667795-1-dhavale@google.com
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/erofs/namei.c | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+--- a/fs/erofs/namei.c
++++ b/fs/erofs/namei.c
+@@ -137,24 +137,24 @@ static void *find_target_block_classic(s
+ /* string comparison without already matched prefix */
+ diff = erofs_dirnamecmp(name, &dname, &matched);
+
+- if (!diff) {
+- *_ndirents = 0;
+- goto out;
+- } else if (diff > 0) {
+- head = mid + 1;
+- startprfx = matched;
+-
+- if (!IS_ERR(candidate))
+- erofs_put_metabuf(target);
+- *target = buf;
+- candidate = de;
+- *_ndirents = ndirents;
+- } else {
++ if (diff < 0) {
+ erofs_put_metabuf(&buf);
+-
+ back = mid - 1;
+ endprfx = matched;
++ continue;
++ }
++
++ if (!IS_ERR(candidate))
++ erofs_put_metabuf(target);
++ *target = buf;
++ if (!diff) {
++ *_ndirents = 0;
++ return de;
+ }
++ head = mid + 1;
++ startprfx = matched;
++ candidate = de;
++ *_ndirents = ndirents;
+ continue;
+ }
+ out: /* free if the candidate is valid */
--- /dev/null
+From 6c347be62ae963b301ead8e7fa7b9973e6e0d6e1 Mon Sep 17 00:00:00 2001
+From: Geliang Tang <tanggeliang@kylinos.cn>
+Date: Thu, 15 Feb 2024 19:25:28 +0100
+Subject: mptcp: add needs_id for userspace appending addr
+
+From: Geliang Tang <tanggeliang@kylinos.cn>
+
+commit 6c347be62ae963b301ead8e7fa7b9973e6e0d6e1 upstream.
+
+When userspace PM requires to create an ID 0 subflow in "userspace pm
+create id 0 subflow" test like this:
+
+ userspace_pm_add_sf $ns2 10.0.3.2 0
+
+An ID 1 subflow, in fact, is created.
+
+Since in mptcp_pm_nl_append_new_local_addr(), 'id 0' will be treated as
+no ID is set by userspace, and will allocate a new ID immediately:
+
+ if (!e->addr.id)
+ e->addr.id = find_next_zero_bit(pernet->id_bitmap,
+ MPTCP_PM_MAX_ADDR_ID + 1,
+ 1);
+
+To solve this issue, a new parameter needs_id is added for
+mptcp_userspace_pm_append_new_local_addr() to distinguish between
+whether userspace PM has set an ID 0 or whether userspace PM has
+not set any address.
+
+needs_id is true in mptcp_userspace_pm_get_local_id(), but false in
+mptcp_pm_nl_announce_doit() and mptcp_pm_nl_subflow_create_doit().
+
+Fixes: e5ed101a6028 ("mptcp: userspace pm allow creating id 0 subflow")
+Cc: stable@vger.kernel.org
+Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_userspace.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+--- a/net/mptcp/pm_userspace.c
++++ b/net/mptcp/pm_userspace.c
+@@ -26,7 +26,8 @@ void mptcp_free_local_addr_list(struct m
+ }
+
+ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
+- struct mptcp_pm_addr_entry *entry)
++ struct mptcp_pm_addr_entry *entry,
++ bool needs_id)
+ {
+ DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
+ struct mptcp_pm_addr_entry *match = NULL;
+@@ -41,7 +42,7 @@ static int mptcp_userspace_pm_append_new
+ spin_lock_bh(&msk->pm.lock);
+ list_for_each_entry(e, &msk->pm.userspace_pm_local_addr_list, list) {
+ addr_match = mptcp_addresses_equal(&e->addr, &entry->addr, true);
+- if (addr_match && entry->addr.id == 0)
++ if (addr_match && entry->addr.id == 0 && needs_id)
+ entry->addr.id = e->addr.id;
+ id_match = (e->addr.id == entry->addr.id);
+ if (addr_match && id_match) {
+@@ -64,7 +65,7 @@ static int mptcp_userspace_pm_append_new
+ }
+
+ *e = *entry;
+- if (!e->addr.id)
++ if (!e->addr.id && needs_id)
+ e->addr.id = find_next_zero_bit(id_bitmap,
+ MPTCP_PM_MAX_ADDR_ID + 1,
+ 1);
+@@ -155,7 +156,7 @@ int mptcp_userspace_pm_get_local_id(stru
+ if (new_entry.addr.port == msk_sport)
+ new_entry.addr.port = 0;
+
+- return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry);
++ return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry, true);
+ }
+
+ int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info)
+@@ -197,7 +198,7 @@ int mptcp_nl_cmd_announce(struct sk_buff
+ goto announce_err;
+ }
+
+- err = mptcp_userspace_pm_append_new_local_addr(msk, &addr_val);
++ err = mptcp_userspace_pm_append_new_local_addr(msk, &addr_val, false);
+ if (err < 0) {
+ GENL_SET_ERR_MSG(info, "did not match address and id");
+ goto announce_err;
+@@ -335,7 +336,7 @@ int mptcp_nl_cmd_sf_create(struct sk_buf
+ }
+
+ local.addr = addr_l;
+- err = mptcp_userspace_pm_append_new_local_addr(msk, &local);
++ err = mptcp_userspace_pm_append_new_local_addr(msk, &local, false);
+ if (err < 0) {
+ GENL_SET_ERR_MSG(info, "did not match address and id");
+ goto create_err;
--- /dev/null
+From aa5887dca2d236fc50000e27023d4d78dce3af30 Mon Sep 17 00:00:00 2001
+From: Geliang Tang <geliang.tang@suse.com>
+Date: Fri, 14 Apr 2023 17:47:06 +0200
+Subject: mptcp: make userspace_pm_append_new_local_addr static
+
+From: Geliang Tang <geliang.tang@suse.com>
+
+commit aa5887dca2d236fc50000e27023d4d78dce3af30 upstream.
+
+mptcp_userspace_pm_append_new_local_addr() has always exclusively been
+used in pm_userspace.c since its introduction in
+commit 4638de5aefe5 ("mptcp: handle local addrs announced by userspace PMs").
+
+So make it static.
+
+Signed-off-by: Geliang Tang <geliang.tang@suse.com>
+Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_userspace.c | 4 ++--
+ net/mptcp/protocol.h | 2 --
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+--- a/net/mptcp/pm_userspace.c
++++ b/net/mptcp/pm_userspace.c
+@@ -25,8 +25,8 @@ void mptcp_free_local_addr_list(struct m
+ }
+ }
+
+-int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
+- struct mptcp_pm_addr_entry *entry)
++static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
++ struct mptcp_pm_addr_entry *entry)
+ {
+ DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
+ struct mptcp_pm_addr_entry *match = NULL;
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -834,8 +834,6 @@ void mptcp_pm_remove_addrs(struct mptcp_
+ void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
+ struct list_head *rm_list);
+
+-int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
+- struct mptcp_pm_addr_entry *entry);
+ void mptcp_free_local_addr_list(struct mptcp_sock *msk);
+ int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info);
+ int mptcp_nl_cmd_remove(struct sk_buff *skb, struct genl_info *info);
--- /dev/null
+From 04530345532fbc0e74ecdedbd537bf3f0329339c Mon Sep 17 00:00:00 2001
+From: "Borislav Petkov (AMD)" <bp@alien8.de>
+Date: Sat, 24 Feb 2024 12:01:34 +0100
+Subject: Revert "x86/alternative: Make custom return thunk unconditional"
+
+From: "Borislav Petkov (AMD)" <bp@alien8.de>
+
+This reverts commit 53ebbe1c8c02aa7b7f072dd2f96bca4faa1daa59.
+
+Revert the backport of upstream commit:
+
+ 095b8303f383 ("x86/alternative: Make custom return thunk unconditional")
+
+in order to backport the full version now that
+
+ 770ae1b70952 ("x86/returnthunk: Allow different return thunks")
+
+has been backported.
+
+Revert it here so that the build breakage is kept at minimum.
+
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/nospec-branch.h | 4 ----
+ arch/x86/kernel/cpu/bugs.c | 2 --
+ 2 files changed, 6 deletions(-)
+
+--- a/arch/x86/include/asm/nospec-branch.h
++++ b/arch/x86/include/asm/nospec-branch.h
+@@ -205,11 +205,7 @@
+ typedef u8 retpoline_thunk_t[RETPOLINE_THUNK_SIZE];
+ extern retpoline_thunk_t __x86_indirect_thunk_array[];
+
+-#ifdef CONFIG_RETHUNK
+ extern void __x86_return_thunk(void);
+-#else
+-static inline void __x86_return_thunk(void) {}
+-#endif
+
+ extern void retbleed_return_thunk(void);
+ extern void srso_return_thunk(void);
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -62,8 +62,6 @@ EXPORT_SYMBOL_GPL(x86_pred_cmd);
+
+ static DEFINE_MUTEX(spec_ctrl_mutex);
+
+-void (*x86_return_thunk)(void) __ro_after_init = &__x86_return_thunk;
+-
+ /* Update SPEC_CTRL MSR and its cached copy unconditionally */
+ static void update_spec_ctrl(u64 val)
+ {
--- /dev/null
+From 3b69e32e151bc4a4e3c785cbdb1f918d5ee337ed Mon Sep 17 00:00:00 2001
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Date: Fri, 16 Feb 2024 23:47:08 +0100
+Subject: serial: amba-pl011: Fix DMA transmission in RS485 mode
+
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+
+commit 3b69e32e151bc4a4e3c785cbdb1f918d5ee337ed upstream.
+
+When DMA is used in RS485 mode make sure that the UARTs tx section is
+enabled before the DMA buffers are queued for transmission.
+
+Cc: stable@vger.kernel.org
+Fixes: 8d479237727c ("serial: amba-pl011: add RS485 support")
+Signed-off-by: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Link: https://lore.kernel.org/r/20240216224709.9928-2-l.sanfilippo@kunbus.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/amba-pl011.c | 60 ++++++++++++++++++++--------------------
+ 1 file changed, 30 insertions(+), 30 deletions(-)
+
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -1345,11 +1345,41 @@ static void pl011_start_tx_pio(struct ua
+ }
+ }
+
++static void pl011_rs485_tx_start(struct uart_amba_port *uap)
++{
++ struct uart_port *port = &uap->port;
++ u32 cr;
++
++ /* Enable transmitter */
++ cr = pl011_read(uap, REG_CR);
++ cr |= UART011_CR_TXE;
++
++ /* Disable receiver if half-duplex */
++ if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
++ cr &= ~UART011_CR_RXE;
++
++ if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
++ cr &= ~UART011_CR_RTS;
++ else
++ cr |= UART011_CR_RTS;
++
++ pl011_write(cr, uap, REG_CR);
++
++ if (port->rs485.delay_rts_before_send)
++ mdelay(port->rs485.delay_rts_before_send);
++
++ uap->rs485_tx_started = true;
++}
++
+ static void pl011_start_tx(struct uart_port *port)
+ {
+ struct uart_amba_port *uap =
+ container_of(port, struct uart_amba_port, port);
+
++ if ((uap->port.rs485.flags & SER_RS485_ENABLED) &&
++ !uap->rs485_tx_started)
++ pl011_rs485_tx_start(uap);
++
+ if (!pl011_dma_tx_start(uap))
+ pl011_start_tx_pio(uap);
+ }
+@@ -1431,42 +1461,12 @@ static bool pl011_tx_char(struct uart_am
+ return true;
+ }
+
+-static void pl011_rs485_tx_start(struct uart_amba_port *uap)
+-{
+- struct uart_port *port = &uap->port;
+- u32 cr;
+-
+- /* Enable transmitter */
+- cr = pl011_read(uap, REG_CR);
+- cr |= UART011_CR_TXE;
+-
+- /* Disable receiver if half-duplex */
+- if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
+- cr &= ~UART011_CR_RXE;
+-
+- if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
+- cr &= ~UART011_CR_RTS;
+- else
+- cr |= UART011_CR_RTS;
+-
+- pl011_write(cr, uap, REG_CR);
+-
+- if (port->rs485.delay_rts_before_send)
+- mdelay(port->rs485.delay_rts_before_send);
+-
+- uap->rs485_tx_started = true;
+-}
+-
+ /* Returns true if tx interrupts have to be (kept) enabled */
+ static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq)
+ {
+ struct circ_buf *xmit = &uap->port.state->xmit;
+ int count = uap->fifosize >> 1;
+
+- if ((uap->port.rs485.flags & SER_RS485_ENABLED) &&
+- !uap->rs485_tx_started)
+- pl011_rs485_tx_start(uap);
+-
+ if (uap->port.x_char) {
+ if (!pl011_tx_char(uap, uap->port.x_char, from_irq))
+ return true;
irqchip-sifive-plic-enable-interrupt-if-needed-before-eoi.patch
pci-msi-prevent-msi-hardware-interrupt-number-truncation.patch
l2tp-pass-correct-message-length-to-ip6_append_data.patch
+arm-ep93xx-add-terminator-to-gpiod_lookup_table.patch
+x86-returnthunk-allow-different-return-thunks.patch
+revert-x86-alternative-make-custom-return-thunk-unconditional.patch
+x86-alternative-make-custom-return-thunk-unconditional.patch
+dm-integrity-dm-verity-reduce-stack-usage-for-recheck.patch
+erofs-fix-refcount-on-the-metabuf-used-for-inode-lookup.patch
+serial-amba-pl011-fix-dma-transmission-in-rs485-mode.patch
+usb-dwc3-gadget-don-t-disconnect-if-not-started.patch
+usb-cdnsp-blocked-some-cdns3-specific-code.patch
+usb-cdnsp-fixed-issue-with-incorrect-detecting-cdnsp-family-controllers.patch
+usb-cdns3-fixed-memory-use-after-free-at-cdns3_gadget_ep_disable.patch
+usb-cdns3-fix-memory-double-free-when-handle-zero-packet.patch
+usb-gadget-ncm-avoid-dropping-datagrams-of-properly-parsed-ntbs.patch
+usb-roles-fix-null-pointer-issue-when-put-module-s-reference.patch
+usb-roles-don-t-get-set_role-when-usb_role_switch-is-unregistered.patch
+mptcp-make-userspace_pm_append_new_local_addr-static.patch
+mptcp-add-needs_id-for-userspace-appending-addr.patch
--- /dev/null
+From 5fd9e45f1ebcd57181358af28506e8a661a260b3 Mon Sep 17 00:00:00 2001
+From: Frank Li <Frank.Li@nxp.com>
+Date: Fri, 2 Feb 2024 10:42:17 -0500
+Subject: usb: cdns3: fix memory double free when handle zero packet
+
+From: Frank Li <Frank.Li@nxp.com>
+
+commit 5fd9e45f1ebcd57181358af28506e8a661a260b3 upstream.
+
+829 if (request->complete) {
+830 spin_unlock(&priv_dev->lock);
+831 usb_gadget_giveback_request(&priv_ep->endpoint,
+832 request);
+833 spin_lock(&priv_dev->lock);
+834 }
+835
+836 if (request->buf == priv_dev->zlp_buf)
+837 cdns3_gadget_ep_free_request(&priv_ep->endpoint, request);
+
+Driver append an additional zero packet request when queue a packet, which
+length mod max packet size is 0. When transfer complete, run to line 831,
+usb_gadget_giveback_request() will free this requestion. 836 condition is
+true, so cdns3_gadget_ep_free_request() free this request again.
+
+Log:
+
+[ 1920.140696][ T150] BUG: KFENCE: use-after-free read in cdns3_gadget_giveback+0x134/0x2c0 [cdns3]
+[ 1920.140696][ T150]
+[ 1920.151837][ T150] Use-after-free read at 0x000000003d1cd10b (in kfence-#36):
+[ 1920.159082][ T150] cdns3_gadget_giveback+0x134/0x2c0 [cdns3]
+[ 1920.164988][ T150] cdns3_transfer_completed+0x438/0x5f8 [cdns3]
+
+Add check at line 829, skip call usb_gadget_giveback_request() if it is
+additional zero length packet request. Needn't call
+usb_gadget_giveback_request() because it is allocated in this driver.
+
+Cc: stable@vger.kernel.org
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Reviewed-by: Roger Quadros <rogerq@kernel.org>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Link: https://lore.kernel.org/r/20240202154217.661867-2-Frank.Li@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/cdns3-gadget.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/cdns3/cdns3-gadget.c
++++ b/drivers/usb/cdns3/cdns3-gadget.c
+@@ -826,7 +826,11 @@ void cdns3_gadget_giveback(struct cdns3_
+ return;
+ }
+
+- if (request->complete) {
++ /*
++ * zlp request is appended by driver, needn't call usb_gadget_giveback_request() to notify
++ * gadget composite driver.
++ */
++ if (request->complete && request->buf != priv_dev->zlp_buf) {
+ spin_unlock(&priv_dev->lock);
+ usb_gadget_giveback_request(&priv_ep->endpoint,
+ request);
--- /dev/null
+From cd45f99034b0c8c9cb346dd0d6407a95ca3d36f6 Mon Sep 17 00:00:00 2001
+From: Frank Li <Frank.Li@nxp.com>
+Date: Fri, 2 Feb 2024 10:42:16 -0500
+Subject: usb: cdns3: fixed memory use after free at cdns3_gadget_ep_disable()
+
+From: Frank Li <Frank.Li@nxp.com>
+
+commit cd45f99034b0c8c9cb346dd0d6407a95ca3d36f6 upstream.
+
+ ...
+ cdns3_gadget_ep_free_request(&priv_ep->endpoint, &priv_req->request);
+ list_del_init(&priv_req->list);
+ ...
+
+'priv_req' actually free at cdns3_gadget_ep_free_request(). But
+list_del_init() use priv_req->list after it.
+
+[ 1542.642868][ T534] BUG: KFENCE: use-after-free read in __list_del_entry_valid+0x10/0xd4
+[ 1542.642868][ T534]
+[ 1542.653162][ T534] Use-after-free read at 0x000000009ed0ba99 (in kfence-#3):
+[ 1542.660311][ T534] __list_del_entry_valid+0x10/0xd4
+[ 1542.665375][ T534] cdns3_gadget_ep_disable+0x1f8/0x388 [cdns3]
+[ 1542.671571][ T534] usb_ep_disable+0x44/0xe4
+[ 1542.675948][ T534] ffs_func_eps_disable+0x64/0xc8
+[ 1542.680839][ T534] ffs_func_set_alt+0x74/0x368
+[ 1542.685478][ T534] ffs_func_disable+0x18/0x28
+
+Move list_del_init() before cdns3_gadget_ep_free_request() to resolve this
+problem.
+
+Cc: stable@vger.kernel.org
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Reviewed-by: Roger Quadros <rogerq@kernel.org>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Link: https://lore.kernel.org/r/20240202154217.661867-1-Frank.Li@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/cdns3-gadget.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/cdns3/cdns3-gadget.c
++++ b/drivers/usb/cdns3/cdns3-gadget.c
+@@ -2537,11 +2537,11 @@ static int cdns3_gadget_ep_disable(struc
+
+ while (!list_empty(&priv_ep->wa2_descmiss_req_list)) {
+ priv_req = cdns3_next_priv_request(&priv_ep->wa2_descmiss_req_list);
++ list_del_init(&priv_req->list);
+
+ kfree(priv_req->request.buf);
+ cdns3_gadget_ep_free_request(&priv_ep->endpoint,
+ &priv_req->request);
+- list_del_init(&priv_req->list);
+ --priv_ep->wa2_counter;
+ }
+
--- /dev/null
+From 18a6be674306c9acb05c08e5c3fd376ef50a917c Mon Sep 17 00:00:00 2001
+From: Pawel Laszczak <pawell@cadence.com>
+Date: Tue, 6 Feb 2024 11:40:18 +0100
+Subject: usb: cdnsp: blocked some cdns3 specific code
+
+From: Pawel Laszczak <pawell@cadence.com>
+
+commit 18a6be674306c9acb05c08e5c3fd376ef50a917c upstream.
+
+host.c file has some parts of code that were introduced for CDNS3 driver
+and should not be used with CDNSP driver.
+This patch blocks using these parts of codes by CDNSP driver.
+These elements include:
+- xhci_plat_cdns3_xhci object
+- cdns3 specific XECP_PORT_CAP_REG register
+- cdns3 specific XECP_AUX_CTRL_REG1 register
+
+cc: stable@vger.kernel.org
+Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver")
+Signed-off-by: Pawel Laszczak <pawell@cadence.com>
+Link: https://lore.kernel.org/r/20240206104018.48272-1-pawell@cadence.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/host.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/cdns3/host.c
++++ b/drivers/usb/cdns3/host.c
+@@ -18,6 +18,11 @@
+ #include "../host/xhci.h"
+ #include "../host/xhci-plat.h"
+
++/*
++ * The XECP_PORT_CAP_REG and XECP_AUX_CTRL_REG1 exist only
++ * in Cadence USB3 dual-role controller, so it can't be used
++ * with Cadence CDNSP dual-role controller.
++ */
+ #define XECP_PORT_CAP_REG 0x8000
+ #define XECP_AUX_CTRL_REG1 0x8120
+
+@@ -57,6 +62,8 @@ static const struct xhci_plat_priv xhci_
+ .resume_quirk = xhci_cdns3_resume_quirk,
+ };
+
++static const struct xhci_plat_priv xhci_plat_cdnsp_xhci;
++
+ static int __cdns_host_init(struct cdns *cdns)
+ {
+ struct platform_device *xhci;
+@@ -81,8 +88,13 @@ static int __cdns_host_init(struct cdns
+ goto err1;
+ }
+
+- cdns->xhci_plat_data = kmemdup(&xhci_plat_cdns3_xhci,
+- sizeof(struct xhci_plat_priv), GFP_KERNEL);
++ if (cdns->version < CDNSP_CONTROLLER_V2)
++ cdns->xhci_plat_data = kmemdup(&xhci_plat_cdns3_xhci,
++ sizeof(struct xhci_plat_priv), GFP_KERNEL);
++ else
++ cdns->xhci_plat_data = kmemdup(&xhci_plat_cdnsp_xhci,
++ sizeof(struct xhci_plat_priv), GFP_KERNEL);
++
+ if (!cdns->xhci_plat_data) {
+ ret = -ENOMEM;
+ goto err1;
--- /dev/null
+From 47625b018c6bc788bc10dd654c82696eb0a5ef11 Mon Sep 17 00:00:00 2001
+From: Pawel Laszczak <pawell@cadence.com>
+Date: Thu, 15 Feb 2024 13:16:09 +0100
+Subject: usb: cdnsp: fixed issue with incorrect detecting CDNSP family controllers
+
+From: Pawel Laszczak <pawell@cadence.com>
+
+commit 47625b018c6bc788bc10dd654c82696eb0a5ef11 upstream.
+
+Cadence have several controllers from 0x000403xx family but current
+driver suuport detecting only one with DID equal 0x0004034E.
+It causes that if someone uses different CDNSP controller then driver
+will use incorrect version and register space.
+Patch fix this issue.
+
+cc: stable@vger.kernel.org
+Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver")
+Signed-off-by: Pawel Laszczak <pawell@cadence.com>
+Link: https://lore.kernel.org/r/20240215121609.259772-1-pawell@cadence.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/core.c | 1 -
+ drivers/usb/cdns3/drd.c | 13 +++++++++----
+ drivers/usb/cdns3/drd.h | 6 +++++-
+ 3 files changed, 14 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/cdns3/core.c
++++ b/drivers/usb/cdns3/core.c
+@@ -394,7 +394,6 @@ pm_put:
+ return ret;
+ }
+
+-
+ /**
+ * cdns_wakeup_irq - interrupt handler for wakeup events
+ * @irq: irq number for cdns3/cdnsp core device
+--- a/drivers/usb/cdns3/drd.c
++++ b/drivers/usb/cdns3/drd.c
+@@ -156,7 +156,8 @@ bool cdns_is_device(struct cdns *cdns)
+ */
+ static void cdns_otg_disable_irq(struct cdns *cdns)
+ {
+- writel(0, &cdns->otg_irq_regs->ien);
++ if (cdns->version)
++ writel(0, &cdns->otg_irq_regs->ien);
+ }
+
+ /**
+@@ -418,15 +419,20 @@ int cdns_drd_init(struct cdns *cdns)
+
+ cdns->otg_regs = (void __iomem *)&cdns->otg_v1_regs->cmd;
+
+- if (readl(&cdns->otg_cdnsp_regs->did) == OTG_CDNSP_DID) {
++ state = readl(&cdns->otg_cdnsp_regs->did);
++
++ if (OTG_CDNSP_CHECK_DID(state)) {
+ cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *)
+ &cdns->otg_cdnsp_regs->ien;
+ cdns->version = CDNSP_CONTROLLER_V2;
+- } else {
++ } else if (OTG_CDNS3_CHECK_DID(state)) {
+ cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *)
+ &cdns->otg_v1_regs->ien;
+ writel(1, &cdns->otg_v1_regs->simulate);
+ cdns->version = CDNS3_CONTROLLER_V1;
++ } else {
++ dev_err(cdns->dev, "not supporte DID=0x%08x\n", state);
++ return -EINVAL;
+ }
+
+ dev_dbg(cdns->dev, "DRD version v1 (ID: %08x, rev: %08x)\n",
+@@ -479,7 +485,6 @@ int cdns_drd_exit(struct cdns *cdns)
+ return 0;
+ }
+
+-
+ /* Indicate the cdns3 core was power lost before */
+ bool cdns_power_is_lost(struct cdns *cdns)
+ {
+--- a/drivers/usb/cdns3/drd.h
++++ b/drivers/usb/cdns3/drd.h
+@@ -79,7 +79,11 @@ struct cdnsp_otg_regs {
+ __le32 susp_timing_ctrl;
+ };
+
+-#define OTG_CDNSP_DID 0x0004034E
++/* CDNSP driver supports 0x000403xx Cadence USB controller family. */
++#define OTG_CDNSP_CHECK_DID(did) (((did) & GENMASK(31, 8)) == 0x00040300)
++
++/* CDNS3 driver supports 0x000402xx Cadence USB controller family. */
++#define OTG_CDNS3_CHECK_DID(did) (((did) & GENMASK(31, 8)) == 0x00040200)
+
+ /*
+ * Common registers interface for both CDNS3 and CDNSP version of DRD.
--- /dev/null
+From b191a18cb5c47109ca696370a74a5062a70adfd0 Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Fri, 16 Feb 2024 00:41:02 +0000
+Subject: usb: dwc3: gadget: Don't disconnect if not started
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit b191a18cb5c47109ca696370a74a5062a70adfd0 upstream.
+
+Don't go through soft-disconnection sequence if the controller hasn't
+started. Otherwise, there will be timeout and warning reports from the
+soft-disconnection flow.
+
+Cc: stable@vger.kernel.org
+Fixes: 61a348857e86 ("usb: dwc3: gadget: Fix NULL pointer dereference in dwc3_gadget_suspend")
+Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Closes: https://lore.kernel.org/linux-usb/20240215233536.7yejlj3zzkl23vjd@synopsys.com/T/#mb0661cd5f9272602af390c18392b9a36da4f96e6
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/e3be9b929934e0680a6f4b8f6eb11b18ae9c7e07.1708043922.git.Thinh.Nguyen@synopsys.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/gadget.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2548,6 +2548,11 @@ static int dwc3_gadget_soft_disconnect(s
+ int ret;
+
+ spin_lock_irqsave(&dwc->lock, flags);
++ if (!dwc->pullups_connected) {
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ return 0;
++ }
++
+ dwc->connected = false;
+
+ /*
--- /dev/null
+From 76c51146820c5dac629f21deafab0a7039bc3ccd Mon Sep 17 00:00:00 2001
+From: Krishna Kurapati <quic_kriskura@quicinc.com>
+Date: Mon, 5 Feb 2024 13:16:50 +0530
+Subject: usb: gadget: ncm: Avoid dropping datagrams of properly parsed NTBs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Krishna Kurapati <quic_kriskura@quicinc.com>
+
+commit 76c51146820c5dac629f21deafab0a7039bc3ccd upstream.
+
+It is observed sometimes when tethering is used over NCM with Windows 11
+as host, at some instances, the gadget_giveback has one byte appended at
+the end of a proper NTB. When the NTB is parsed, unwrap call looks for
+any leftover bytes in SKB provided by u_ether and if there are any pending
+bytes, it treats them as a separate NTB and parses it. But in case the
+second NTB (as per unwrap call) is faulty/corrupt, all the datagrams that
+were parsed properly in the first NTB and saved in rx_list are dropped.
+
+Adding a few custom traces showed the following:
+[002] d..1 7828.532866: dwc3_gadget_giveback: ep1out:
+req 000000003868811a length 1025/16384 zsI ==> 0
+[002] d..1 7828.532867: ncm_unwrap_ntb: K: ncm_unwrap_ntb toprocess: 1025
+[002] d..1 7828.532867: ncm_unwrap_ntb: K: ncm_unwrap_ntb nth: 1751999342
+[002] d..1 7828.532868: ncm_unwrap_ntb: K: ncm_unwrap_ntb seq: 0xce67
+[002] d..1 7828.532868: ncm_unwrap_ntb: K: ncm_unwrap_ntb blk_len: 0x400
+[002] d..1 7828.532868: ncm_unwrap_ntb: K: ncm_unwrap_ntb ndp_len: 0x10
+[002] d..1 7828.532869: ncm_unwrap_ntb: K: Parsed NTB with 1 frames
+
+In this case, the giveback is of 1025 bytes and block length is 1024.
+The rest 1 byte (which is 0x00) won't be parsed resulting in drop of
+all datagrams in rx_list.
+
+Same is case with packets of size 2048:
+[002] d..1 7828.557948: dwc3_gadget_giveback: ep1out:
+req 0000000011dfd96e length 2049/16384 zsI ==> 0
+[002] d..1 7828.557949: ncm_unwrap_ntb: K: ncm_unwrap_ntb nth: 1751999342
+[002] d..1 7828.557950: ncm_unwrap_ntb: K: ncm_unwrap_ntb blk_len: 0x800
+
+Lecroy shows one byte coming in extra confirming that the byte is coming
+in from PC:
+
+ Transfer 2959 - Bytes Transferred(1025) Timestamp((18.524 843 590)
+ - Transaction 8391 - Data(1025 bytes) Timestamp(18.524 843 590)
+ --- Packet 4063861
+ Data(1024 bytes)
+ Duration(2.117us) Idle(14.700ns) Timestamp(18.524 843 590)
+ --- Packet 4063863
+ Data(1 byte)
+ Duration(66.160ns) Time(282.000ns) Timestamp(18.524 845 722)
+
+According to Windows driver, no ZLP is needed if wBlockLength is non-zero,
+because the non-zero wBlockLength has already told the function side the
+size of transfer to be expected. However, there are in-market NCM devices
+that rely on ZLP as long as the wBlockLength is multiple of wMaxPacketSize.
+To deal with such devices, it pads an extra 0 at end so the transfer is no
+longer multiple of wMaxPacketSize.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 9f6ce4240a2b ("usb: gadget: f_ncm.c added")
+Signed-off-by: Krishna Kurapati <quic_kriskura@quicinc.com>
+Reviewed-by: Maciej Żenczykowski <maze@google.com>
+Link: https://lore.kernel.org/r/20240205074650.200304-1-quic_kriskura@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_ncm.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/function/f_ncm.c
++++ b/drivers/usb/gadget/function/f_ncm.c
+@@ -1340,7 +1340,15 @@ parse_ntb:
+ "Parsed NTB with %d frames\n", dgram_counter);
+
+ to_process -= block_len;
+- if (to_process != 0) {
++
++ /*
++ * Windows NCM driver avoids USB ZLPs by adding a 1-byte
++ * zero pad as needed.
++ */
++ if (to_process == 1 &&
++ (*(unsigned char *)(ntb_ptr + block_len) == 0x00)) {
++ to_process--;
++ } else if (to_process > 0) {
+ ntb_ptr = (unsigned char *)(ntb_ptr + block_len);
+ goto parse_ntb;
+ }
--- /dev/null
+From b787a3e781759026a6212736ef8e52cf83d1821a Mon Sep 17 00:00:00 2001
+From: Xu Yang <xu.yang_2@nxp.com>
+Date: Mon, 29 Jan 2024 17:37:39 +0800
+Subject: usb: roles: don't get/set_role() when usb_role_switch is unregistered
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+commit b787a3e781759026a6212736ef8e52cf83d1821a upstream.
+
+There is a possibility that usb_role_switch device is unregistered before
+the user put usb_role_switch. In this case, the user may still want to
+get/set_role() since the user can't sense the changes of usb_role_switch.
+
+This will add a flag to show if usb_role_switch is already registered and
+avoid unwanted behaviors.
+
+Fixes: fde0aa6c175a ("usb: common: Small class for USB role switches")
+cc: stable@vger.kernel.org
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20240129093739.2371530-2-xu.yang_2@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/roles/class.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/roles/class.c
++++ b/drivers/usb/roles/class.c
+@@ -21,6 +21,7 @@ struct usb_role_switch {
+ struct mutex lock; /* device lock*/
+ struct module *module; /* the module this device depends on */
+ enum usb_role role;
++ bool registered;
+
+ /* From descriptor */
+ struct device *usb2_port;
+@@ -47,6 +48,9 @@ int usb_role_switch_set_role(struct usb_
+ if (IS_ERR_OR_NULL(sw))
+ return 0;
+
++ if (!sw->registered)
++ return -EOPNOTSUPP;
++
+ mutex_lock(&sw->lock);
+
+ ret = sw->set(sw, role);
+@@ -72,7 +76,7 @@ enum usb_role usb_role_switch_get_role(s
+ {
+ enum usb_role role;
+
+- if (IS_ERR_OR_NULL(sw))
++ if (IS_ERR_OR_NULL(sw) || !sw->registered)
+ return USB_ROLE_NONE;
+
+ mutex_lock(&sw->lock);
+@@ -356,6 +360,8 @@ usb_role_switch_register(struct device *
+ return ERR_PTR(ret);
+ }
+
++ sw->registered = true;
++
+ /* TODO: Symlinks for the host port and the device controller. */
+
+ return sw;
+@@ -370,8 +376,10 @@ EXPORT_SYMBOL_GPL(usb_role_switch_regist
+ */
+ void usb_role_switch_unregister(struct usb_role_switch *sw)
+ {
+- if (!IS_ERR_OR_NULL(sw))
++ if (!IS_ERR_OR_NULL(sw)) {
++ sw->registered = false;
+ device_unregister(&sw->dev);
++ }
+ }
+ EXPORT_SYMBOL_GPL(usb_role_switch_unregister);
+
--- /dev/null
+From 1c9be13846c0b2abc2480602f8ef421360e1ad9e Mon Sep 17 00:00:00 2001
+From: Xu Yang <xu.yang_2@nxp.com>
+Date: Mon, 29 Jan 2024 17:37:38 +0800
+Subject: usb: roles: fix NULL pointer issue when put module's reference
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+commit 1c9be13846c0b2abc2480602f8ef421360e1ad9e upstream.
+
+In current design, usb role class driver will get usb_role_switch parent's
+module reference after the user get usb_role_switch device and put the
+reference after the user put the usb_role_switch device. However, the
+parent device of usb_role_switch may be removed before the user put the
+usb_role_switch. If so, then, NULL pointer issue will be met when the user
+put the parent module's reference.
+
+This will save the module pointer in structure of usb_role_switch. Then,
+we don't need to find module by iterating long relations.
+
+Fixes: 5c54fcac9a9d ("usb: roles: Take care of driver module reference counting")
+cc: stable@vger.kernel.org
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20240129093739.2371530-1-xu.yang_2@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/roles/class.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/roles/class.c
++++ b/drivers/usb/roles/class.c
+@@ -19,6 +19,7 @@ static struct class *role_class;
+ struct usb_role_switch {
+ struct device dev;
+ struct mutex lock; /* device lock*/
++ struct module *module; /* the module this device depends on */
+ enum usb_role role;
+
+ /* From descriptor */
+@@ -133,7 +134,7 @@ struct usb_role_switch *usb_role_switch_
+ usb_role_switch_match);
+
+ if (!IS_ERR_OR_NULL(sw))
+- WARN_ON(!try_module_get(sw->dev.parent->driver->owner));
++ WARN_ON(!try_module_get(sw->module));
+
+ return sw;
+ }
+@@ -155,7 +156,7 @@ struct usb_role_switch *fwnode_usb_role_
+ sw = fwnode_connection_find_match(fwnode, "usb-role-switch",
+ NULL, usb_role_switch_match);
+ if (!IS_ERR_OR_NULL(sw))
+- WARN_ON(!try_module_get(sw->dev.parent->driver->owner));
++ WARN_ON(!try_module_get(sw->module));
+
+ return sw;
+ }
+@@ -170,7 +171,7 @@ EXPORT_SYMBOL_GPL(fwnode_usb_role_switch
+ void usb_role_switch_put(struct usb_role_switch *sw)
+ {
+ if (!IS_ERR_OR_NULL(sw)) {
+- module_put(sw->dev.parent->driver->owner);
++ module_put(sw->module);
+ put_device(&sw->dev);
+ }
+ }
+@@ -187,15 +188,18 @@ struct usb_role_switch *
+ usb_role_switch_find_by_fwnode(const struct fwnode_handle *fwnode)
+ {
+ struct device *dev;
++ struct usb_role_switch *sw = NULL;
+
+ if (!fwnode)
+ return NULL;
+
+ dev = class_find_device_by_fwnode(role_class, fwnode);
+- if (dev)
+- WARN_ON(!try_module_get(dev->parent->driver->owner));
++ if (dev) {
++ sw = to_role_switch(dev);
++ WARN_ON(!try_module_get(sw->module));
++ }
+
+- return dev ? to_role_switch(dev) : NULL;
++ return sw;
+ }
+ EXPORT_SYMBOL_GPL(usb_role_switch_find_by_fwnode);
+
+@@ -337,6 +341,7 @@ usb_role_switch_register(struct device *
+ sw->set = desc->set;
+ sw->get = desc->get;
+
++ sw->module = parent->driver->owner;
+ sw->dev.parent = parent;
+ sw->dev.fwnode = desc->fwnode;
+ sw->dev.class = role_class;
--- /dev/null
+From c203b857ba7dedefdf9924a56be434b46a73765a Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Mon, 14 Aug 2023 13:44:30 +0200
+Subject: x86/alternative: Make custom return thunk unconditional
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+Upstream commit: 095b8303f3835c68ac4a8b6d754ca1c3b6230711
+
+There is infrastructure to rewrite return thunks to point to any
+random thunk one desires, unwrap that from CALL_THUNKS, which up to
+now was the sole user of that.
+
+ [ bp: Make the thunks visible on 32-bit and add ifdeffery for the
+ 32-bit builds. ]
+
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/20230814121148.775293785@infradead.org
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/nospec-branch.h | 8 ++++----
+ arch/x86/kernel/alternative.c | 4 ----
+ arch/x86/kernel/cpu/bugs.c | 2 ++
+ 3 files changed, 6 insertions(+), 8 deletions(-)
+
+--- a/arch/x86/include/asm/nospec-branch.h
++++ b/arch/x86/include/asm/nospec-branch.h
+@@ -205,7 +205,11 @@
+ typedef u8 retpoline_thunk_t[RETPOLINE_THUNK_SIZE];
+ extern retpoline_thunk_t __x86_indirect_thunk_array[];
+
++#ifdef CONFIG_RETHUNK
+ extern void __x86_return_thunk(void);
++#else
++static inline void __x86_return_thunk(void) {}
++#endif
+
+ extern void retbleed_return_thunk(void);
+ extern void srso_return_thunk(void);
+@@ -218,11 +222,7 @@ extern void srso_alias_untrain_ret(void)
+ extern void entry_untrain_ret(void);
+ extern void entry_ibpb(void);
+
+-#ifdef CONFIG_CALL_THUNKS
+ extern void (*x86_return_thunk)(void);
+-#else
+-#define x86_return_thunk (&__x86_return_thunk)
+-#endif
+
+ #ifdef CONFIG_RETPOLINE
+
+--- a/arch/x86/kernel/alternative.c
++++ b/arch/x86/kernel/alternative.c
+@@ -537,10 +537,6 @@ void __init_or_module noinline apply_ret
+
+ #ifdef CONFIG_RETHUNK
+
+-#ifdef CONFIG_CALL_THUNKS
+-void (*x86_return_thunk)(void) __ro_after_init = &__x86_return_thunk;
+-#endif
+-
+ /*
+ * Rewrite the compiler generated return thunk tail-calls.
+ *
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -62,6 +62,8 @@ EXPORT_SYMBOL_GPL(x86_pred_cmd);
+
+ static DEFINE_MUTEX(spec_ctrl_mutex);
+
++void (*x86_return_thunk)(void) __ro_after_init = &__x86_return_thunk;
++
+ /* Update SPEC_CTRL MSR and its cached copy unconditionally */
+ static void update_spec_ctrl(u64 val)
+ {
--- /dev/null
+From f169c7403c60b56e66c136af415076558a563d6e Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Thu, 15 Sep 2022 13:11:25 +0200
+Subject: x86/returnthunk: Allow different return thunks
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+Upstream commit: 770ae1b709528a6a173b5c7b183818ee9b45e376
+
+In preparation for call depth tracking on Intel SKL CPUs, make it possible
+to patch in a SKL specific return thunk.
+
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20220915111147.680469665@infradead.org
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/nospec-branch.h | 6 ++++++
+ arch/x86/kernel/alternative.c | 19 ++++++++++++++-----
+ arch/x86/kernel/ftrace.c | 2 +-
+ arch/x86/kernel/static_call.c | 2 +-
+ arch/x86/net/bpf_jit_comp.c | 2 +-
+ 5 files changed, 23 insertions(+), 8 deletions(-)
+
+--- a/arch/x86/include/asm/nospec-branch.h
++++ b/arch/x86/include/asm/nospec-branch.h
+@@ -222,6 +222,12 @@ extern void srso_alias_untrain_ret(void)
+ extern void entry_untrain_ret(void);
+ extern void entry_ibpb(void);
+
++#ifdef CONFIG_CALL_THUNKS
++extern void (*x86_return_thunk)(void);
++#else
++#define x86_return_thunk (&__x86_return_thunk)
++#endif
++
+ #ifdef CONFIG_RETPOLINE
+
+ #define GEN(reg) \
+--- a/arch/x86/kernel/alternative.c
++++ b/arch/x86/kernel/alternative.c
+@@ -536,6 +536,11 @@ void __init_or_module noinline apply_ret
+ }
+
+ #ifdef CONFIG_RETHUNK
++
++#ifdef CONFIG_CALL_THUNKS
++void (*x86_return_thunk)(void) __ro_after_init = &__x86_return_thunk;
++#endif
++
+ /*
+ * Rewrite the compiler generated return thunk tail-calls.
+ *
+@@ -551,14 +556,18 @@ static int patch_return(void *addr, stru
+ {
+ int i = 0;
+
+- if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
+- return -1;
+-
+- bytes[i++] = RET_INSN_OPCODE;
++ if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) {
++ if (x86_return_thunk == __x86_return_thunk)
++ return -1;
++
++ i = JMP32_INSN_SIZE;
++ __text_gen_insn(bytes, JMP32_INSN_OPCODE, addr, x86_return_thunk, i);
++ } else {
++ bytes[i++] = RET_INSN_OPCODE;
++ }
+
+ for (; i < insn->length;)
+ bytes[i++] = INT3_INSN_OPCODE;
+-
+ return i;
+ }
+
+--- a/arch/x86/kernel/ftrace.c
++++ b/arch/x86/kernel/ftrace.c
+@@ -361,7 +361,7 @@ create_trampoline(struct ftrace_ops *ops
+
+ ip = trampoline + size;
+ if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
+- __text_gen_insn(ip, JMP32_INSN_OPCODE, ip, &__x86_return_thunk, JMP32_INSN_SIZE);
++ __text_gen_insn(ip, JMP32_INSN_OPCODE, ip, x86_return_thunk, JMP32_INSN_SIZE);
+ else
+ memcpy(ip, retq, sizeof(retq));
+
+--- a/arch/x86/kernel/static_call.c
++++ b/arch/x86/kernel/static_call.c
+@@ -80,7 +80,7 @@ static void __ref __static_call_transfor
+
+ case RET:
+ if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
+- code = text_gen_insn(JMP32_INSN_OPCODE, insn, &__x86_return_thunk);
++ code = text_gen_insn(JMP32_INSN_OPCODE, insn, x86_return_thunk);
+ else
+ code = &retinsn;
+ break;
+--- a/arch/x86/net/bpf_jit_comp.c
++++ b/arch/x86/net/bpf_jit_comp.c
+@@ -432,7 +432,7 @@ static void emit_return(u8 **pprog, u8 *
+ u8 *prog = *pprog;
+
+ if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) {
+- emit_jump(&prog, &__x86_return_thunk, ip);
++ emit_jump(&prog, x86_return_thunk, ip);
+ } else {
+ EMIT1(0xC3); /* ret */
+ if (IS_ENABLED(CONFIG_SLS))