From: Sasha Levin Date: Sat, 26 Feb 2022 02:59:31 +0000 (-0500) Subject: Fixes for 5.15 X-Git-Tag: v4.9.304~41 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=266a4c4d08f3d3b64157d4ba800dfdab2c02b7fd;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/bnxt_en-increase-firmware-message-response-dma-wait-.patch b/queue-5.15/bnxt_en-increase-firmware-message-response-dma-wait-.patch new file mode 100644 index 00000000000..18e4e15472b --- /dev/null +++ b/queue-5.15/bnxt_en-increase-firmware-message-response-dma-wait-.patch @@ -0,0 +1,80 @@ +From a4fd7ba748219363b6cbc9155fb66e59b792c376 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 20 Feb 2022 04:05:52 -0500 +Subject: bnxt_en: Increase firmware message response DMA wait time + +From: Michael Chan + +[ Upstream commit b891106da52b2c12dbaf73400f6d225b06a38d80 ] + +When polling for the firmware message response, we first poll for the +response message header. Once the valid length is detected in the +header, we poll for the valid bit at the end of the message which +signals DMA completion. Normally, this poll time for DMA completion +is extremely short (0 to a few usec). But on some devices under some +rare conditions, it can be up to about 20 msec. + +Increase this delay to 50 msec and use udelay() for the first 10 usec +for the common case, and usleep_range() beyond that. + +Also, change the error message to include the above delay time when +printing the timeout value. + +Fixes: 3c8c20db769c ("bnxt_en: move HWRM API implementation into separate file") +Reviewed-by: Vladimir Olovyannikov +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c | 12 +++++++++--- + drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h | 2 +- + 2 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c +index 8171f4912fa01..3a0eeb3737767 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c +@@ -595,18 +595,24 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx) + + /* Last byte of resp contains valid bit */ + valid = ((u8 *)ctx->resp) + len - 1; +- for (j = 0; j < HWRM_VALID_BIT_DELAY_USEC; j++) { ++ for (j = 0; j < HWRM_VALID_BIT_DELAY_USEC; ) { + /* make sure we read from updated DMA memory */ + dma_rmb(); + if (*valid) + break; +- usleep_range(1, 5); ++ if (j < 10) { ++ udelay(1); ++ j++; ++ } else { ++ usleep_range(20, 30); ++ j += 20; ++ } + } + + if (j >= HWRM_VALID_BIT_DELAY_USEC) { + if (!(ctx->flags & BNXT_HWRM_CTX_SILENT)) + netdev_err(bp->dev, "Error (timeout: %u) msg {0x%x 0x%x} len:%d v:%d\n", +- hwrm_total_timeout(i), ++ hwrm_total_timeout(i) + j, + le16_to_cpu(ctx->req->req_type), + le16_to_cpu(ctx->req->seq_id), len, + *valid); +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h +index 9a9fc4e8041b6..380ef69afb51b 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h +@@ -94,7 +94,7 @@ static inline unsigned int hwrm_total_timeout(unsigned int n) + } + + +-#define HWRM_VALID_BIT_DELAY_USEC 150 ++#define HWRM_VALID_BIT_DELAY_USEC 50000 + + static inline bool bnxt_cfa_hwrm_message(u16 req_type) + { +-- +2.34.1 + diff --git a/queue-5.15/configfs-fix-a-race-in-configfs_-un-register_subsyst.patch b/queue-5.15/configfs-fix-a-race-in-configfs_-un-register_subsyst.patch new file mode 100644 index 00000000000..7b2c21b77be --- /dev/null +++ b/queue-5.15/configfs-fix-a-race-in-configfs_-un-register_subsyst.patch @@ -0,0 +1,98 @@ +From 37a5c7486d74ea7038c64affd645aacedee5645c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Feb 2022 15:10:30 +0800 +Subject: configfs: fix a race in configfs_{,un}register_subsystem() + +From: ChenXiaoSong + +[ Upstream commit 84ec758fb2daa236026506868c8796b0500c047d ] + +When configfs_register_subsystem() or configfs_unregister_subsystem() +is executing link_group() or unlink_group(), +it is possible that two processes add or delete list concurrently. +Some unfortunate interleavings of them can cause kernel panic. + +One of cases is: +A --> B --> C --> D +A <-- B <-- C <-- D + + delete list_head *B | delete list_head *C +--------------------------------|----------------------------------- +configfs_unregister_subsystem | configfs_unregister_subsystem + unlink_group | unlink_group + unlink_obj | unlink_obj + list_del_init | list_del_init + __list_del_entry | __list_del_entry + __list_del | __list_del + // next == C | + next->prev = prev | + | next->prev = prev + prev->next = next | + | // prev == B + | prev->next = next + +Fix this by adding mutex when calling link_group() or unlink_group(), +but parent configfs_subsystem is NULL when config_item is root. +So I create a mutex configfs_subsystem_mutex. + +Fixes: 7063fbf22611 ("[PATCH] configfs: User-driven configuration filesystem") +Signed-off-by: ChenXiaoSong +Signed-off-by: Laibin Qiu +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + fs/configfs/dir.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c +index d3cd2a94d1e8c..d1f9d26322027 100644 +--- a/fs/configfs/dir.c ++++ b/fs/configfs/dir.c +@@ -34,6 +34,14 @@ + */ + DEFINE_SPINLOCK(configfs_dirent_lock); + ++/* ++ * All of link_obj/unlink_obj/link_group/unlink_group require that ++ * subsys->su_mutex is held. ++ * But parent configfs_subsystem is NULL when config_item is root. ++ * Use this mutex when config_item is root. ++ */ ++static DEFINE_MUTEX(configfs_subsystem_mutex); ++ + static void configfs_d_iput(struct dentry * dentry, + struct inode * inode) + { +@@ -1859,7 +1867,9 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) + group->cg_item.ci_name = group->cg_item.ci_namebuf; + + sd = root->d_fsdata; ++ mutex_lock(&configfs_subsystem_mutex); + link_group(to_config_group(sd->s_element), group); ++ mutex_unlock(&configfs_subsystem_mutex); + + inode_lock_nested(d_inode(root), I_MUTEX_PARENT); + +@@ -1884,7 +1894,9 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) + inode_unlock(d_inode(root)); + + if (err) { ++ mutex_lock(&configfs_subsystem_mutex); + unlink_group(group); ++ mutex_unlock(&configfs_subsystem_mutex); + configfs_release_fs(); + } + put_fragment(frag); +@@ -1931,7 +1943,9 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) + + dput(dentry); + ++ mutex_lock(&configfs_subsystem_mutex); + unlink_group(group); ++ mutex_unlock(&configfs_subsystem_mutex); + configfs_release_fs(); + } + +-- +2.34.1 + diff --git a/queue-5.15/gpio-rockchip-reset-int_bothedge-when-changing-trigg.patch b/queue-5.15/gpio-rockchip-reset-int_bothedge-when-changing-trigg.patch new file mode 100644 index 00000000000..450224c4ca3 --- /dev/null +++ b/queue-5.15/gpio-rockchip-reset-int_bothedge-when-changing-trigg.patch @@ -0,0 +1,104 @@ +From 8aad70f00d37e5725af1aa1ea34e3b334d67471a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Feb 2022 14:50:48 -0600 +Subject: gpio: rockchip: Reset int_bothedge when changing trigger + +From: Samuel Holland + +[ Upstream commit 7920af5c826cb4a7ada1ae26fdd317642805adc2 ] + +With v2 hardware, an IRQ can be configured to trigger on both edges via +a bit in the int_bothedge register. Currently, the driver sets this bit +when changing the trigger type to IRQ_TYPE_EDGE_BOTH, but fails to reset +this bit if the trigger type is later changed to something else. This +causes spurious IRQs, and when using gpio-keys with wakeup-event-action +set to EV_ACT_(DE)ASSERTED, those IRQs translate into spurious wakeups. + +Fixes: 3bcbd1a85b68 ("gpio/rockchip: support next version gpio controller") +Reported-by: Guillaume Savaton +Tested-by: Guillaume Savaton +Signed-off-by: Samuel Holland +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-rockchip.c | 56 +++++++++++++++++++----------------- + 1 file changed, 29 insertions(+), 27 deletions(-) + +diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c +index ce63cbd14d69a..24155c038f6d0 100644 +--- a/drivers/gpio/gpio-rockchip.c ++++ b/drivers/gpio/gpio-rockchip.c +@@ -410,10 +410,8 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) + level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type); + polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity); + +- switch (type) { +- case IRQ_TYPE_EDGE_BOTH: ++ if (type == IRQ_TYPE_EDGE_BOTH) { + if (bank->gpio_type == GPIO_TYPE_V2) { +- bank->toggle_edge_mode &= ~mask; + rockchip_gpio_writel_bit(bank, d->hwirq, 1, + bank->gpio_regs->int_bothedge); + goto out; +@@ -431,30 +429,34 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) + else + polarity |= mask; + } +- break; +- case IRQ_TYPE_EDGE_RISING: +- bank->toggle_edge_mode &= ~mask; +- level |= mask; +- polarity |= mask; +- break; +- case IRQ_TYPE_EDGE_FALLING: +- bank->toggle_edge_mode &= ~mask; +- level |= mask; +- polarity &= ~mask; +- break; +- case IRQ_TYPE_LEVEL_HIGH: +- bank->toggle_edge_mode &= ~mask; +- level &= ~mask; +- polarity |= mask; +- break; +- case IRQ_TYPE_LEVEL_LOW: +- bank->toggle_edge_mode &= ~mask; +- level &= ~mask; +- polarity &= ~mask; +- break; +- default: +- ret = -EINVAL; +- goto out; ++ } else { ++ if (bank->gpio_type == GPIO_TYPE_V2) { ++ rockchip_gpio_writel_bit(bank, d->hwirq, 0, ++ bank->gpio_regs->int_bothedge); ++ } else { ++ bank->toggle_edge_mode &= ~mask; ++ } ++ switch (type) { ++ case IRQ_TYPE_EDGE_RISING: ++ level |= mask; ++ polarity |= mask; ++ break; ++ case IRQ_TYPE_EDGE_FALLING: ++ level |= mask; ++ polarity &= ~mask; ++ break; ++ case IRQ_TYPE_LEVEL_HIGH: ++ level &= ~mask; ++ polarity |= mask; ++ break; ++ case IRQ_TYPE_LEVEL_LOW: ++ level &= ~mask; ++ polarity &= ~mask; ++ break; ++ default: ++ ret = -EINVAL; ++ goto out; ++ } + } + + rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type); +-- +2.34.1 + diff --git a/queue-5.15/net-timestamp-convert-sk-sk_tskey-to-atomic_t.patch b/queue-5.15/net-timestamp-convert-sk-sk_tskey-to-atomic_t.patch new file mode 100644 index 00000000000..aca0af5dee0 --- /dev/null +++ b/queue-5.15/net-timestamp-convert-sk-sk_tskey-to-atomic_t.patch @@ -0,0 +1,164 @@ +From 13021cc0e06d24e77ef51ac39dddf4b59d255cae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Feb 2022 09:05:02 -0800 +Subject: net-timestamp: convert sk->sk_tskey to atomic_t + +From: Eric Dumazet + +[ Upstream commit a1cdec57e03a1352e92fbbe7974039dda4efcec0 ] + +UDP sendmsg() can be lockless, this is causing all kinds +of data races. + +This patch converts sk->sk_tskey to remove one of these races. + +BUG: KCSAN: data-race in __ip_append_data / __ip_append_data + +read to 0xffff8881035d4b6c of 4 bytes by task 8877 on cpu 1: + __ip_append_data+0x1c1/0x1de0 net/ipv4/ip_output.c:994 + ip_make_skb+0x13f/0x2d0 net/ipv4/ip_output.c:1636 + udp_sendmsg+0x12bd/0x14c0 net/ipv4/udp.c:1249 + inet_sendmsg+0x5f/0x80 net/ipv4/af_inet.c:819 + sock_sendmsg_nosec net/socket.c:705 [inline] + sock_sendmsg net/socket.c:725 [inline] + ____sys_sendmsg+0x39a/0x510 net/socket.c:2413 + ___sys_sendmsg net/socket.c:2467 [inline] + __sys_sendmmsg+0x267/0x4c0 net/socket.c:2553 + __do_sys_sendmmsg net/socket.c:2582 [inline] + __se_sys_sendmmsg net/socket.c:2579 [inline] + __x64_sys_sendmmsg+0x53/0x60 net/socket.c:2579 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x44/0xd0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x44/0xae + +write to 0xffff8881035d4b6c of 4 bytes by task 8880 on cpu 0: + __ip_append_data+0x1d8/0x1de0 net/ipv4/ip_output.c:994 + ip_make_skb+0x13f/0x2d0 net/ipv4/ip_output.c:1636 + udp_sendmsg+0x12bd/0x14c0 net/ipv4/udp.c:1249 + inet_sendmsg+0x5f/0x80 net/ipv4/af_inet.c:819 + sock_sendmsg_nosec net/socket.c:705 [inline] + sock_sendmsg net/socket.c:725 [inline] + ____sys_sendmsg+0x39a/0x510 net/socket.c:2413 + ___sys_sendmsg net/socket.c:2467 [inline] + __sys_sendmmsg+0x267/0x4c0 net/socket.c:2553 + __do_sys_sendmmsg net/socket.c:2582 [inline] + __se_sys_sendmmsg net/socket.c:2579 [inline] + __x64_sys_sendmmsg+0x53/0x60 net/socket.c:2579 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x44/0xd0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x44/0xae + +value changed: 0x0000054d -> 0x0000054e + +Reported by Kernel Concurrency Sanitizer on: +CPU: 0 PID: 8880 Comm: syz-executor.5 Not tainted 5.17.0-rc2-syzkaller-00167-gdcb85f85fa6f-dirty #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 + +Fixes: 09c2d251b707 ("net-timestamp: add key to disambiguate concurrent datagrams") +Signed-off-by: Eric Dumazet +Cc: Willem de Bruijn +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 4 ++-- + net/can/j1939/transport.c | 2 +- + net/core/skbuff.c | 2 +- + net/core/sock.c | 4 ++-- + net/ipv4/ip_output.c | 2 +- + net/ipv6/ip6_output.c | 2 +- + 6 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/include/net/sock.h b/include/net/sock.h +index dfb92f91d5be5..7d49196a3880e 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -506,7 +506,7 @@ struct sock { + u16 sk_tsflags; + int sk_bind_phc; + u8 sk_shutdown; +- u32 sk_tskey; ++ atomic_t sk_tskey; + atomic_t sk_zckey; + + u8 sk_clockid; +@@ -2598,7 +2598,7 @@ static inline void _sock_tx_timestamp(struct sock *sk, __u16 tsflags, + __sock_tx_timestamp(tsflags, tx_flags); + if (tsflags & SOF_TIMESTAMPING_OPT_ID && tskey && + tsflags & SOF_TIMESTAMPING_TX_RECORD_MASK) +- *tskey = sk->sk_tskey++; ++ *tskey = atomic_inc_return(&sk->sk_tskey) - 1; + } + if (unlikely(sock_flag(sk, SOCK_WIFI_STATUS))) + *tx_flags |= SKBTX_WIFI_STATUS; +diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c +index a271688780a2c..307ee1174a6e2 100644 +--- a/net/can/j1939/transport.c ++++ b/net/can/j1939/transport.c +@@ -2006,7 +2006,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv, + /* set the end-packet for broadcast */ + session->pkt.last = session->pkt.total; + +- skcb->tskey = session->sk->sk_tskey++; ++ skcb->tskey = atomic_inc_return(&session->sk->sk_tskey) - 1; + session->tskey = skcb->tskey; + + return session; +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index bb4dce8fd0405..449a96e358ad5 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -4844,7 +4844,7 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb, + serr->ee.ee_data = skb_shinfo(skb)->tskey; + if (sk->sk_protocol == IPPROTO_TCP && + sk->sk_type == SOCK_STREAM) +- serr->ee.ee_data -= sk->sk_tskey; ++ serr->ee.ee_data -= atomic_read(&sk->sk_tskey); + } + + err = sock_queue_err_skb(sk, skb); +diff --git a/net/core/sock.c b/net/core/sock.c +index 6ea317f84edd2..deaed1b206823 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -866,9 +866,9 @@ int sock_set_timestamping(struct sock *sk, int optname, + if ((1 << sk->sk_state) & + (TCPF_CLOSE | TCPF_LISTEN)) + return -EINVAL; +- sk->sk_tskey = tcp_sk(sk)->snd_una; ++ atomic_set(&sk->sk_tskey, tcp_sk(sk)->snd_una); + } else { +- sk->sk_tskey = 0; ++ atomic_set(&sk->sk_tskey, 0); + } + } + +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c +index a4d2eb691cbc1..131066d0319a2 100644 +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -992,7 +992,7 @@ static int __ip_append_data(struct sock *sk, + + if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP && + sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) +- tskey = sk->sk_tskey++; ++ tskey = atomic_inc_return(&sk->sk_tskey) - 1; + + hh_len = LL_RESERVED_SPACE(rt->dst.dev); + +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index ff4e83e2a5068..22bf8fb617165 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1465,7 +1465,7 @@ static int __ip6_append_data(struct sock *sk, + + if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP && + sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) +- tskey = sk->sk_tskey++; ++ tskey = atomic_inc_return(&sk->sk_tskey) - 1; + + hh_len = LL_RESERVED_SPACE(rt->dst.dev); + +-- +2.34.1 + diff --git a/queue-5.15/rdma-ib_srp-fix-a-deadlock.patch b/queue-5.15/rdma-ib_srp-fix-a-deadlock.patch new file mode 100644 index 00000000000..3465a108da0 --- /dev/null +++ b/queue-5.15/rdma-ib_srp-fix-a-deadlock.patch @@ -0,0 +1,45 @@ +From f28c24728a2f61122c81004859d2f12ada6ff1e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Feb 2022 13:05:11 -0800 +Subject: RDMA/ib_srp: Fix a deadlock + +From: Bart Van Assche + +[ Upstream commit 081bdc9fe05bb23248f5effb6f811da3da4b8252 ] + +Remove the flush_workqueue(system_long_wq) call since flushing +system_long_wq is deadlock-prone and since that call is redundant with a +preceding cancel_work_sync() + +Link: https://lore.kernel.org/r/20220215210511.28303-3-bvanassche@acm.org +Fixes: ef6c49d87c34 ("IB/srp: Eliminate state SRP_TARGET_DEAD") +Reported-by: syzbot+831661966588c802aae9@syzkaller.appspotmail.com +Signed-off-by: Bart Van Assche +Reviewed-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/srp/ib_srp.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c +index 71eda91e810cf..5d416ec228717 100644 +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -4038,9 +4038,11 @@ static void srp_remove_one(struct ib_device *device, void *client_data) + spin_unlock(&host->target_lock); + + /* +- * Wait for tl_err and target port removal tasks. ++ * srp_queue_remove_work() queues a call to ++ * srp_remove_target(). The latter function cancels ++ * target->tl_err_work so waiting for the remove works to ++ * finish is sufficient. + */ +- flush_workqueue(system_long_wq); + flush_workqueue(srp_remove_wq); + + kfree(host); +-- +2.34.1 + diff --git a/queue-5.15/rdma-rtrs-clt-fix-possible-double-free-in-error-case.patch b/queue-5.15/rdma-rtrs-clt-fix-possible-double-free-in-error-case.patch new file mode 100644 index 00000000000..0738a47d178 --- /dev/null +++ b/queue-5.15/rdma-rtrs-clt-fix-possible-double-free-in-error-case.patch @@ -0,0 +1,125 @@ +From ecf88a18041ee3fe2d96497b384a9a1292dfc4a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Feb 2022 04:09:28 +0100 +Subject: RDMA/rtrs-clt: Fix possible double free in error case + +From: Md Haris Iqbal + +[ Upstream commit 8700af2cc18c919b2a83e74e0479038fd113c15d ] + +Callback function rtrs_clt_dev_release() for put_device() calls kfree(clt) +to free memory. We shouldn't call kfree(clt) again, and we can't use the +clt after kfree too. + +Replace device_register() with device_initialize() and device_add() so that +dev_set_name can() be used appropriately. + +Move mutex_destroy() to the release function so it can be called in +the alloc_clt err path. + +Fixes: eab098246625 ("RDMA/rtrs-clt: Refactor the failure cases in alloc_clt") +Link: https://lore.kernel.org/r/20220217030929.323849-1-haris.iqbal@ionos.com +Reported-by: Miaoqian Lin +Signed-off-by: Md Haris Iqbal +Reviewed-by: Jack Wang +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/rtrs/rtrs-clt.c | 37 ++++++++++++++------------ + 1 file changed, 20 insertions(+), 17 deletions(-) + +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c +index 55ebe01ec9951..3272514f05405 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c +@@ -2664,6 +2664,8 @@ static void rtrs_clt_dev_release(struct device *dev) + { + struct rtrs_clt *clt = container_of(dev, struct rtrs_clt, dev); + ++ mutex_destroy(&clt->paths_ev_mutex); ++ mutex_destroy(&clt->paths_mutex); + kfree(clt); + } + +@@ -2693,6 +2695,8 @@ static struct rtrs_clt *alloc_clt(const char *sessname, size_t paths_num, + return ERR_PTR(-ENOMEM); + } + ++ clt->dev.class = rtrs_clt_dev_class; ++ clt->dev.release = rtrs_clt_dev_release; + uuid_gen(&clt->paths_uuid); + INIT_LIST_HEAD_RCU(&clt->paths_list); + clt->paths_num = paths_num; +@@ -2709,43 +2713,41 @@ static struct rtrs_clt *alloc_clt(const char *sessname, size_t paths_num, + init_waitqueue_head(&clt->permits_wait); + mutex_init(&clt->paths_ev_mutex); + mutex_init(&clt->paths_mutex); ++ device_initialize(&clt->dev); + +- clt->dev.class = rtrs_clt_dev_class; +- clt->dev.release = rtrs_clt_dev_release; + err = dev_set_name(&clt->dev, "%s", sessname); + if (err) +- goto err; ++ goto err_put; ++ + /* + * Suppress user space notification until + * sysfs files are created + */ + dev_set_uevent_suppress(&clt->dev, true); +- err = device_register(&clt->dev); +- if (err) { +- put_device(&clt->dev); +- goto err; +- } ++ err = device_add(&clt->dev); ++ if (err) ++ goto err_put; + + clt->kobj_paths = kobject_create_and_add("paths", &clt->dev.kobj); + if (!clt->kobj_paths) { + err = -ENOMEM; +- goto err_dev; ++ goto err_del; + } + err = rtrs_clt_create_sysfs_root_files(clt); + if (err) { + kobject_del(clt->kobj_paths); + kobject_put(clt->kobj_paths); +- goto err_dev; ++ goto err_del; + } + dev_set_uevent_suppress(&clt->dev, false); + kobject_uevent(&clt->dev.kobj, KOBJ_ADD); + + return clt; +-err_dev: +- device_unregister(&clt->dev); +-err: ++err_del: ++ device_del(&clt->dev); ++err_put: + free_percpu(clt->pcpu_path); +- kfree(clt); ++ put_device(&clt->dev); + return ERR_PTR(err); + } + +@@ -2753,9 +2755,10 @@ static void free_clt(struct rtrs_clt *clt) + { + free_permits(clt); + free_percpu(clt->pcpu_path); +- mutex_destroy(&clt->paths_ev_mutex); +- mutex_destroy(&clt->paths_mutex); +- /* release callback will free clt in last put */ ++ ++ /* ++ * release callback will free clt and destroy mutexes in last put ++ */ + device_unregister(&clt->dev); + } + +-- +2.34.1 + diff --git a/queue-5.15/rdma-rtrs-clt-move-free_permit-from-free_clt-to-rtrs.patch b/queue-5.15/rdma-rtrs-clt-move-free_permit-from-free_clt-to-rtrs.patch new file mode 100644 index 00000000000..aae83dba25c --- /dev/null +++ b/queue-5.15/rdma-rtrs-clt-move-free_permit-from-free_clt-to-rtrs.patch @@ -0,0 +1,49 @@ +From e1792721d8a4907eefde3f87fd25382305d116df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Feb 2022 04:09:29 +0100 +Subject: RDMA/rtrs-clt: Move free_permit from free_clt to rtrs_clt_close + +From: Md Haris Iqbal + +[ Upstream commit c46fa8911b17e3f808679061a8af8bee219f4602 ] + +Error path of rtrs_clt_open() calls free_clt(), where free_permit is +called. This is wrong since error path of rtrs_clt_open() does not need +to call free_permit(). + +Also, moving free_permits() call to rtrs_clt_close(), makes it more +aligned with the call to alloc_permit() in rtrs_clt_open(). + +Fixes: 6a98d71daea1 ("RDMA/rtrs: client: main functionality") +Link: https://lore.kernel.org/r/20220217030929.323849-2-haris.iqbal@ionos.com +Signed-off-by: Md Haris Iqbal +Reviewed-by: Jack Wang +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/rtrs/rtrs-clt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c +index 3272514f05405..a23438bacf12c 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c +@@ -2753,7 +2753,6 @@ static struct rtrs_clt *alloc_clt(const char *sessname, size_t paths_num, + + static void free_clt(struct rtrs_clt *clt) + { +- free_permits(clt); + free_percpu(clt->pcpu_path); + + /* +@@ -2869,6 +2868,7 @@ void rtrs_clt_close(struct rtrs_clt *clt) + rtrs_clt_destroy_sess_files(sess, NULL); + kobject_put(&sess->kobj); + } ++ free_permits(clt); + free_clt(clt); + } + EXPORT_SYMBOL(rtrs_clt_close); +-- +2.34.1 + diff --git a/queue-5.15/regmap-irq-update-interrupt-clear-register-for-prope.patch b/queue-5.15/regmap-irq-update-interrupt-clear-register-for-prope.patch new file mode 100644 index 00000000000..e57fc371d2e --- /dev/null +++ b/queue-5.15/regmap-irq-update-interrupt-clear-register-for-prope.patch @@ -0,0 +1,105 @@ +From 239f2244b493da50a811d97cfff0978b0098d3ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Feb 2022 14:20:07 +0530 +Subject: regmap-irq: Update interrupt clear register for proper reset +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Prasad Kumpatla + +[ Upstream commit d04ad245d67a3991dfea5e108e4c452c2ab39bac ] + +With the existing logic where clear_ack is true (HW doesn’t support +auto clear for ICR), interrupt clear register reset is not handled +properly. Due to this only the first interrupts get processed properly +and further interrupts are blocked due to not resetting interrupt +clear register. + +Example for issue case where Invert_ack is false and clear_ack is true: + + Say Default ISR=0x00 & ICR=0x00 and ISR is triggered with 2 + interrupts making ISR = 0x11. + + Step 1: Say ISR is set 0x11 (store status_buff = ISR). ISR needs to + be cleared with the help of ICR once the Interrupt is processed. + + Step 2: Write ICR = 0x11 (status_buff), this will clear the ISR to 0x00. + + Step 3: Issue - In the existing code, ICR is written with ICR = + ~(status_buff) i.e ICR = 0xEE -> This will block all the interrupts + from raising except for interrupts 0 and 4. So expectation here is to + reset ICR, which will unblock all the interrupts. + + if (chip->clear_ack) { + if (chip->ack_invert && !ret) + ........ + else if (!ret) + ret = regmap_write(map, reg, + ~data->status_buf[i]); + +So writing 0 and 0xff (when ack_invert is true) should have no effect, other +than clearing the ACKs just set. + +Fixes: 3a6f0fb7b8eb ("regmap: irq: Add support to clear ack registers") +Signed-off-by: Prasad Kumpatla +Reviewed-by: Charles Keepax +Tested-by: Marek Szyprowski +Link: https://lore.kernel.org/r/20220217085007.30218-1-quic_pkumpatl@quicinc.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/base/regmap/regmap-irq.c | 20 ++++++-------------- + 1 file changed, 6 insertions(+), 14 deletions(-) + +diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c +index d2656581a6085..4a446259a184e 100644 +--- a/drivers/base/regmap/regmap-irq.c ++++ b/drivers/base/regmap/regmap-irq.c +@@ -189,11 +189,9 @@ static void regmap_irq_sync_unlock(struct irq_data *data) + ret = regmap_write(map, reg, d->mask_buf[i]); + if (d->chip->clear_ack) { + if (d->chip->ack_invert && !ret) +- ret = regmap_write(map, reg, +- d->mask_buf[i]); ++ ret = regmap_write(map, reg, UINT_MAX); + else if (!ret) +- ret = regmap_write(map, reg, +- ~d->mask_buf[i]); ++ ret = regmap_write(map, reg, 0); + } + if (ret != 0) + dev_err(d->map->dev, "Failed to ack 0x%x: %d\n", +@@ -556,11 +554,9 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) + data->status_buf[i]); + if (chip->clear_ack) { + if (chip->ack_invert && !ret) +- ret = regmap_write(map, reg, +- data->status_buf[i]); ++ ret = regmap_write(map, reg, UINT_MAX); + else if (!ret) +- ret = regmap_write(map, reg, +- ~data->status_buf[i]); ++ ret = regmap_write(map, reg, 0); + } + if (ret != 0) + dev_err(map->dev, "Failed to ack 0x%x: %d\n", +@@ -817,13 +813,9 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, + d->status_buf[i] & d->mask_buf[i]); + if (chip->clear_ack) { + if (chip->ack_invert && !ret) +- ret = regmap_write(map, reg, +- (d->status_buf[i] & +- d->mask_buf[i])); ++ ret = regmap_write(map, reg, UINT_MAX); + else if (!ret) +- ret = regmap_write(map, reg, +- ~(d->status_buf[i] & +- d->mask_buf[i])); ++ ret = regmap_write(map, reg, 0); + } + if (ret != 0) { + dev_err(map->dev, "Failed to ack 0x%x: %d\n", +-- +2.34.1 + diff --git a/queue-5.15/series b/queue-5.15/series index add0e0b4003..a9c10cee538 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -82,3 +82,12 @@ net-mlx5-dr-fix-the-threshold-that-defines-when-pool-sync-is-initiated.patch net-mlx5e-mplsoudp-decap-fix-check-for-unsupported-matches.patch net-mlx5e-ktls-use-checksum_unnecessary-for-device-offloaded-packets.patch net-mlx5-update-log_max_qp-value-to-be-17-at-most.patch +spi-spi-zynq-qspi-fix-a-null-pointer-dereference-in-.patch +gpio-rockchip-reset-int_bothedge-when-changing-trigg.patch +regmap-irq-update-interrupt-clear-register-for-prope.patch +net-timestamp-convert-sk-sk_tskey-to-atomic_t.patch +rdma-rtrs-clt-fix-possible-double-free-in-error-case.patch +rdma-rtrs-clt-move-free_permit-from-free_clt-to-rtrs.patch +bnxt_en-increase-firmware-message-response-dma-wait-.patch +configfs-fix-a-race-in-configfs_-un-register_subsyst.patch +rdma-ib_srp-fix-a-deadlock.patch diff --git a/queue-5.15/spi-spi-zynq-qspi-fix-a-null-pointer-dereference-in-.patch b/queue-5.15/spi-spi-zynq-qspi-fix-a-null-pointer-dereference-in-.patch new file mode 100644 index 00000000000..3ea7a8ba853 --- /dev/null +++ b/queue-5.15/spi-spi-zynq-qspi-fix-a-null-pointer-dereference-in-.patch @@ -0,0 +1,55 @@ +From dac1bcce43d2c8056edf30966178de169bcbd198 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Dec 2021 01:22:53 +0800 +Subject: spi: spi-zynq-qspi: Fix a NULL pointer dereference in + zynq_qspi_exec_mem_op() + +From: Zhou Qingyang + +[ Upstream commit ab3824427b848da10e9fe2727f035bbeecae6ff4 ] + +In zynq_qspi_exec_mem_op(), kzalloc() is directly used in memset(), +which could lead to a NULL pointer dereference on failure of +kzalloc(). + +Fix this bug by adding a check of tmpbuf. + +This bug was found by a static analyzer. The analysis employs +differential checking to identify inconsistent security operations +(e.g., checks or kfrees) between two code paths and confirms that the +inconsistent operations are not recovered in the current function or +the callers, so they constitute bugs. + +Note that, as a bug found by static analysis, it can be a false +positive or hard to trigger. Multiple researchers have cross-reviewed +the bug. + +Builds with CONFIG_SPI_ZYNQ_QSPI=m show no new warnings, +and our static analyzer no longer warns about this code. + +Fixes: 67dca5e580f1 ("spi: spi-mem: Add support for Zynq QSPI controller") +Signed-off-by: Zhou Qingyang +Link: https://lore.kernel.org/r/20211130172253.203700-1-zhou1615@umn.edu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-zynq-qspi.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c +index cfa222c9bd5e7..78f31b61a2aac 100644 +--- a/drivers/spi/spi-zynq-qspi.c ++++ b/drivers/spi/spi-zynq-qspi.c +@@ -570,6 +570,9 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem, + + if (op->dummy.nbytes) { + tmpbuf = kzalloc(op->dummy.nbytes, GFP_KERNEL); ++ if (!tmpbuf) ++ return -ENOMEM; ++ + memset(tmpbuf, 0xff, op->dummy.nbytes); + reinit_completion(&xqspi->data_completion); + xqspi->txbuf = tmpbuf; +-- +2.34.1 +