From: Sasha Levin Date: Mon, 5 Jun 2023 11:26:32 +0000 (-0400) Subject: Fixes for 5.4 X-Git-Tag: v4.14.317~94 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=db5360d095457b637e306a5a4a9d96280725d2cb;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/af_packet-do-not-use-read_once-in-packet_bind.patch b/queue-5.4/af_packet-do-not-use-read_once-in-packet_bind.patch new file mode 100644 index 00000000000..520ad274aad --- /dev/null +++ b/queue-5.4/af_packet-do-not-use-read_once-in-packet_bind.patch @@ -0,0 +1,64 @@ +From 739b5f8d12ffa95341bb0350b7b637ebea57927c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 May 2023 15:43:42 +0000 +Subject: af_packet: do not use READ_ONCE() in packet_bind() + +From: Eric Dumazet + +[ Upstream commit 6ffc57ea004234d9373c57b204fd10370a69f392 ] + +A recent patch added READ_ONCE() in packet_bind() and packet_bind_spkt() + +This is better handled by reading pkt_sk(sk)->num later +in packet_do_bind() while appropriate lock is held. + +READ_ONCE() in writers are often an evidence of something being wrong. + +Fixes: 822b5a1c17df ("af_packet: Fix data-races of pkt_sk(sk)->num.") +Signed-off-by: Eric Dumazet +Reviewed-by: Willem de Bruijn +Reviewed-by: Jiri Pirko +Reviewed-by: Kuniyuki Iwashima +Link: https://lore.kernel.org/r/20230526154342.2533026-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/packet/af_packet.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 2d4cc53180a1c..fbe3434dcdc1e 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3128,6 +3128,9 @@ static int packet_do_bind(struct sock *sk, const char *name, int ifindex, + + lock_sock(sk); + spin_lock(&po->bind_lock); ++ if (!proto) ++ proto = po->num; ++ + rcu_read_lock(); + + if (po->fanout) { +@@ -3230,7 +3233,7 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, + memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data)); + name[sizeof(uaddr->sa_data)] = 0; + +- return packet_do_bind(sk, name, 0, READ_ONCE(pkt_sk(sk)->num)); ++ return packet_do_bind(sk, name, 0, 0); + } + + static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) +@@ -3247,8 +3250,7 @@ static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len + if (sll->sll_family != AF_PACKET) + return -EINVAL; + +- return packet_do_bind(sk, NULL, sll->sll_ifindex, +- sll->sll_protocol ? : READ_ONCE(pkt_sk(sk)->num)); ++ return packet_do_bind(sk, NULL, sll->sll_ifindex, sll->sll_protocol); + } + + static struct proto packet_proto = { +-- +2.39.2 + diff --git a/queue-5.4/af_packet-fix-data-races-of-pkt_sk-sk-num.patch b/queue-5.4/af_packet-fix-data-races-of-pkt_sk-sk-num.patch new file mode 100644 index 00000000000..3b51636a212 --- /dev/null +++ b/queue-5.4/af_packet-fix-data-races-of-pkt_sk-sk-num.patch @@ -0,0 +1,98 @@ +From 0f719b98ebf17fda632a2497c97b42dc2e3dc70f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 May 2023 16:29:34 -0700 +Subject: af_packet: Fix data-races of pkt_sk(sk)->num. + +From: Kuniyuki Iwashima + +[ Upstream commit 822b5a1c17df7e338b9f05d1cfe5764e37c7f74f ] + +syzkaller found a data race of pkt_sk(sk)->num. + +The value is changed under lock_sock() and po->bind_lock, so we +need READ_ONCE() to access pkt_sk(sk)->num without these locks in +packet_bind_spkt(), packet_bind(), and sk_diag_fill(). + +Note that WRITE_ONCE() is already added by commit c7d2ef5dd4b0 +("net/packet: annotate accesses to po->bind"). + +BUG: KCSAN: data-race in packet_bind / packet_do_bind + +write (marked) to 0xffff88802ffd1cee of 2 bytes by task 7322 on cpu 0: + packet_do_bind+0x446/0x640 net/packet/af_packet.c:3236 + packet_bind+0x99/0xe0 net/packet/af_packet.c:3321 + __sys_bind+0x19b/0x1e0 net/socket.c:1803 + __do_sys_bind net/socket.c:1814 [inline] + __se_sys_bind net/socket.c:1812 [inline] + __x64_sys_bind+0x40/0x50 net/socket.c:1812 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x72/0xdc + +read to 0xffff88802ffd1cee of 2 bytes by task 7318 on cpu 1: + packet_bind+0xbf/0xe0 net/packet/af_packet.c:3322 + __sys_bind+0x19b/0x1e0 net/socket.c:1803 + __do_sys_bind net/socket.c:1814 [inline] + __se_sys_bind net/socket.c:1812 [inline] + __x64_sys_bind+0x40/0x50 net/socket.c:1812 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x72/0xdc + +value changed: 0x0300 -> 0x0000 + +Reported by Kernel Concurrency Sanitizer on: +CPU: 1 PID: 7318 Comm: syz-executor.4 Not tainted 6.3.0-13380-g7fddb5b5300c #4 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 + +Fixes: 96ec6327144e ("packet: Diag core and basic socket info dumping") +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzkaller +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Willem de Bruijn +Link: https://lore.kernel.org/r/20230524232934.50950-1-kuniyu@amazon.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/packet/af_packet.c | 4 ++-- + net/packet/diag.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 7a940f2f30671..2d4cc53180a1c 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3230,7 +3230,7 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, + memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data)); + name[sizeof(uaddr->sa_data)] = 0; + +- return packet_do_bind(sk, name, 0, pkt_sk(sk)->num); ++ return packet_do_bind(sk, name, 0, READ_ONCE(pkt_sk(sk)->num)); + } + + static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) +@@ -3248,7 +3248,7 @@ static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len + return -EINVAL; + + return packet_do_bind(sk, NULL, sll->sll_ifindex, +- sll->sll_protocol ? : pkt_sk(sk)->num); ++ sll->sll_protocol ? : READ_ONCE(pkt_sk(sk)->num)); + } + + static struct proto packet_proto = { +diff --git a/net/packet/diag.c b/net/packet/diag.c +index d704c7bf51b20..a68a84574c739 100644 +--- a/net/packet/diag.c ++++ b/net/packet/diag.c +@@ -143,7 +143,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, + rp = nlmsg_data(nlh); + rp->pdiag_family = AF_PACKET; + rp->pdiag_type = sk->sk_type; +- rp->pdiag_num = ntohs(po->num); ++ rp->pdiag_num = ntohs(READ_ONCE(po->num)); + rp->pdiag_ino = sk_ino; + sock_diag_save_cookie(sk, rp->pdiag_cookie); + +-- +2.39.2 + diff --git a/queue-5.4/alsa-oss-avoid-missing-prototype-warnings.patch b/queue-5.4/alsa-oss-avoid-missing-prototype-warnings.patch new file mode 100644 index 00000000000..11905687882 --- /dev/null +++ b/queue-5.4/alsa-oss-avoid-missing-prototype-warnings.patch @@ -0,0 +1,64 @@ +From 90fd0bf3a9a2da3ba392aca809cec3f5497d981d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 May 2023 21:50:42 +0200 +Subject: ALSA: oss: avoid missing-prototype warnings + +From: Arnd Bergmann + +[ Upstream commit 040b5a046a9e18098580d3ccd029e2318fca7859 ] + +Two functions are defined and used in pcm_oss.c but also optionally +used from io.c, with an optional prototype. If CONFIG_SND_PCM_OSS_PLUGINS +is disabled, this causes a warning as the functions are not static +and have no prototype: + +sound/core/oss/pcm_oss.c:1235:19: error: no previous prototype for 'snd_pcm_oss_write3' [-Werror=missing-prototypes] +sound/core/oss/pcm_oss.c:1266:19: error: no previous prototype for 'snd_pcm_oss_read3' [-Werror=missing-prototypes] + +Avoid this by making the prototypes unconditional. + +Signed-off-by: Arnd Bergmann +Link: https://lore.kernel.org/r/20230516195046.550584-2-arnd@kernel.org +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/core/oss/pcm_plugin.h | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/sound/core/oss/pcm_plugin.h b/sound/core/oss/pcm_plugin.h +index 8d2f7a4e3ab67..0e1c8cae6c5bd 100644 +--- a/sound/core/oss/pcm_plugin.h ++++ b/sound/core/oss/pcm_plugin.h +@@ -141,6 +141,14 @@ int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_channel, + + void *snd_pcm_plug_buf_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t size); + void snd_pcm_plug_buf_unlock(struct snd_pcm_substream *plug, void *ptr); ++#else ++ ++static inline snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size) { return drv_size; } ++static inline snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size) { return clt_size; } ++static inline int snd_pcm_plug_slave_format(int format, const struct snd_mask *format_mask) { return format; } ++ ++#endif ++ + snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, + const char *ptr, snd_pcm_uframes_t size, + int in_kernel); +@@ -151,14 +159,6 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, + snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, + void **bufs, snd_pcm_uframes_t frames); + +-#else +- +-static inline snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size) { return drv_size; } +-static inline snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size) { return clt_size; } +-static inline int snd_pcm_plug_slave_format(int format, const struct snd_mask *format_mask) { return format; } +- +-#endif +- + #ifdef PLUGIN_DEBUG + #define pdprintf(fmt, args...) printk(KERN_DEBUG "plugin: " fmt, ##args) + #else +-- +2.39.2 + diff --git a/queue-5.4/amd-xgbe-fix-the-false-linkup-in-xgbe_phy_status.patch b/queue-5.4/amd-xgbe-fix-the-false-linkup-in-xgbe_phy_status.patch new file mode 100644 index 00000000000..4c2e4d67a04 --- /dev/null +++ b/queue-5.4/amd-xgbe-fix-the-false-linkup-in-xgbe_phy_status.patch @@ -0,0 +1,71 @@ +From 54eaa9865f962b15a59330913a671100ef6f5174 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 May 2023 23:56:12 +0530 +Subject: amd-xgbe: fix the false linkup in xgbe_phy_status + +From: Raju Rangoju + +[ Upstream commit dc362e20cd6ab7a93d1b09669730c406f0910c35 ] + +In the event of a change in XGBE mode, the current auto-negotiation +needs to be reset and the AN cycle needs to be re-triggerred. However, +the current code ignores the return value of xgbe_set_mode(), leading to +false information as the link is declared without checking the status +register. + +Fix this by propagating the mode switch status information to +xgbe_phy_status(). + +Fixes: e57f7a3feaef ("amd-xgbe: Prepare for working with more than one type of phy") +Co-developed-by: Sudheesh Mavila +Signed-off-by: Sudheesh Mavila +Reviewed-by: Simon Horman +Acked-by: Shyam Sundar S K +Signed-off-by: Raju Rangoju +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c +index 7840eb4cdb8da..d291976d8b761 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c +@@ -1312,7 +1312,7 @@ static enum xgbe_mode xgbe_phy_status_aneg(struct xgbe_prv_data *pdata) + return pdata->phy_if.phy_impl.an_outcome(pdata); + } + +-static void xgbe_phy_status_result(struct xgbe_prv_data *pdata) ++static bool xgbe_phy_status_result(struct xgbe_prv_data *pdata) + { + struct ethtool_link_ksettings *lks = &pdata->phy.lks; + enum xgbe_mode mode; +@@ -1347,8 +1347,13 @@ static void xgbe_phy_status_result(struct xgbe_prv_data *pdata) + + pdata->phy.duplex = DUPLEX_FULL; + +- if (xgbe_set_mode(pdata, mode) && pdata->an_again) ++ if (!xgbe_set_mode(pdata, mode)) ++ return false; ++ ++ if (pdata->an_again) + xgbe_phy_reconfig_aneg(pdata); ++ ++ return true; + } + + static void xgbe_phy_status(struct xgbe_prv_data *pdata) +@@ -1378,7 +1383,8 @@ static void xgbe_phy_status(struct xgbe_prv_data *pdata) + return; + } + +- xgbe_phy_status_result(pdata); ++ if (xgbe_phy_status_result(pdata)) ++ return; + + if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) + clear_bit(XGBE_LINK_INIT, &pdata->dev_state); +-- +2.39.2 + diff --git a/queue-5.4/arm-9295-1-unwind-fix-unwind-abort-for-uleb128-case.patch b/queue-5.4/arm-9295-1-unwind-fix-unwind-abort-for-uleb128-case.patch new file mode 100644 index 00000000000..ce80aa57e8a --- /dev/null +++ b/queue-5.4/arm-9295-1-unwind-fix-unwind-abort-for-uleb128-case.patch @@ -0,0 +1,93 @@ +From d6c0a0226593bcdfb02b624807372b8a712b285e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Apr 2023 10:17:07 +0100 +Subject: ARM: 9295/1: unwind:fix unwind abort for uleb128 case + +From: Haibo Li + +[ Upstream commit fa3eeb638de0c1a9d2d860e5b48259facdd65176 ] + +When unwind instruction is 0xb2,the subsequent instructions +are uleb128 bytes. +For now,it uses only the first uleb128 byte in code. + +For vsp increments of 0x204~0x400,use one uleb128 byte like below: +0xc06a00e4 : 0x80b27fac + Compact model index: 0 + 0xb2 0x7f vsp = vsp + 1024 + 0xac pop {r4, r5, r6, r7, r8, r14} + +For vsp increments larger than 0x400,use two uleb128 bytes like below: +0xc06a00e4 : @0xc0cc9e0c + Compact model index: 1 + 0xb2 0x81 0x01 vsp = vsp + 1032 + 0xac pop {r4, r5, r6, r7, r8, r14} +The unwind works well since the decoded uleb128 byte is also 0x81. + +For vsp increments larger than 0x600,use two uleb128 bytes like below: +0xc06a00e4 : @0xc0cc9e0c + Compact model index: 1 + 0xb2 0x81 0x02 vsp = vsp + 1544 + 0xac pop {r4, r5, r6, r7, r8, r14} +In this case,the decoded uleb128 result is 0x101(vsp=0x204+(0x101<<2)). +While the uleb128 used in code is 0x81(vsp=0x204+(0x81<<2)). +The unwind aborts at this frame since it gets incorrect vsp. + +To fix this,add uleb128 decode to cover all the above case. + +Signed-off-by: Haibo Li +Reviewed-by: Linus Walleij +Reviewed-by: Alexandre Mergnat +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Russell King (Oracle) +Signed-off-by: Sasha Levin +--- + arch/arm/kernel/unwind.c | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c +index 4574e6aea0a52..f321c2aa94e1c 100644 +--- a/arch/arm/kernel/unwind.c ++++ b/arch/arm/kernel/unwind.c +@@ -300,6 +300,29 @@ static int unwind_exec_pop_subset_r0_to_r3(struct unwind_ctrl_block *ctrl, + return URC_OK; + } + ++static unsigned long unwind_decode_uleb128(struct unwind_ctrl_block *ctrl) ++{ ++ unsigned long bytes = 0; ++ unsigned long insn; ++ unsigned long result = 0; ++ ++ /* ++ * unwind_get_byte() will advance `ctrl` one instruction at a time, so ++ * loop until we get an instruction byte where bit 7 is not set. ++ * ++ * Note: This decodes a maximum of 4 bytes to output 28 bits data where ++ * max is 0xfffffff: that will cover a vsp increment of 1073742336, hence ++ * it is sufficient for unwinding the stack. ++ */ ++ do { ++ insn = unwind_get_byte(ctrl); ++ result |= (insn & 0x7f) << (bytes * 7); ++ bytes++; ++ } while (!!(insn & 0x80) && (bytes != sizeof(result))); ++ ++ return result; ++} ++ + /* + * Execute the current unwind instruction. + */ +@@ -353,7 +376,7 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl) + if (ret) + goto error; + } else if (insn == 0xb2) { +- unsigned long uleb128 = unwind_get_byte(ctrl); ++ unsigned long uleb128 = unwind_decode_uleb128(ctrl); + + ctrl->vrs[SP] += 0x204 + (uleb128 << 2); + } else { +-- +2.39.2 + diff --git a/queue-5.4/arm-dts-stm32-add-pin-map-for-can-controller-on-stm3.patch b/queue-5.4/arm-dts-stm32-add-pin-map-for-can-controller-on-stm3.patch new file mode 100644 index 00000000000..3a1198ecb65 --- /dev/null +++ b/queue-5.4/arm-dts-stm32-add-pin-map-for-can-controller-on-stm3.patch @@ -0,0 +1,115 @@ +From 7d5691bbdd7beafa8162cfd1e9731a2e9325e3c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Apr 2023 22:45:38 +0200 +Subject: ARM: dts: stm32: add pin map for CAN controller on stm32f7 + +From: Dario Binacchi + +[ Upstream commit 011644249686f2675e142519cd59e81e04cfc231 ] + +Add pin configurations for using CAN controller on stm32f7. + +Signed-off-by: Dario Binacchi +Link: https://lore.kernel.org/all/20230427204540.3126234-4-dario.binacchi@amarulasolutions.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/stm32f7-pinctrl.dtsi | 82 ++++++++++++++++++++++++++ + 1 file changed, 82 insertions(+) + +diff --git a/arch/arm/boot/dts/stm32f7-pinctrl.dtsi b/arch/arm/boot/dts/stm32f7-pinctrl.dtsi +index 9314128df1859..639a6b65749f2 100644 +--- a/arch/arm/boot/dts/stm32f7-pinctrl.dtsi ++++ b/arch/arm/boot/dts/stm32f7-pinctrl.dtsi +@@ -284,6 +284,88 @@ + slew-rate = <2>; + }; + }; ++ ++ can1_pins_a: can1-0 { ++ pins1 { ++ pinmux = ; /* CAN1_TX */ ++ }; ++ pins2 { ++ pinmux = ; /* CAN1_RX */ ++ bias-pull-up; ++ }; ++ }; ++ ++ can1_pins_b: can1-1 { ++ pins1 { ++ pinmux = ; /* CAN1_TX */ ++ }; ++ pins2 { ++ pinmux = ; /* CAN1_RX */ ++ bias-pull-up; ++ }; ++ }; ++ ++ can1_pins_c: can1-2 { ++ pins1 { ++ pinmux = ; /* CAN1_TX */ ++ }; ++ pins2 { ++ pinmux = ; /* CAN1_RX */ ++ bias-pull-up; ++ ++ }; ++ }; ++ ++ can1_pins_d: can1-3 { ++ pins1 { ++ pinmux = ; /* CAN1_TX */ ++ }; ++ pins2 { ++ pinmux = ; /* CAN1_RX */ ++ bias-pull-up; ++ ++ }; ++ }; ++ ++ can2_pins_a: can2-0 { ++ pins1 { ++ pinmux = ; /* CAN2_TX */ ++ }; ++ pins2 { ++ pinmux = ; /* CAN2_RX */ ++ bias-pull-up; ++ }; ++ }; ++ ++ can2_pins_b: can2-1 { ++ pins1 { ++ pinmux = ; /* CAN2_TX */ ++ }; ++ pins2 { ++ pinmux = ; /* CAN2_RX */ ++ bias-pull-up; ++ }; ++ }; ++ ++ can3_pins_a: can3-0 { ++ pins1 { ++ pinmux = ; /* CAN3_TX */ ++ }; ++ pins2 { ++ pinmux = ; /* CAN3_RX */ ++ bias-pull-up; ++ }; ++ }; ++ ++ can3_pins_b: can3-1 { ++ pins1 { ++ pinmux = ; /* CAN3_TX */ ++ }; ++ pins2 { ++ pinmux = ; /* CAN3_RX */ ++ bias-pull-up; ++ }; ++ }; + }; + }; + }; +-- +2.39.2 + diff --git a/queue-5.4/arm64-mm-mark-private-vm_fault_x-defines-as-vm_fault.patch b/queue-5.4/arm64-mm-mark-private-vm_fault_x-defines-as-vm_fault.patch new file mode 100644 index 00000000000..d82135dc099 --- /dev/null +++ b/queue-5.4/arm64-mm-mark-private-vm_fault_x-defines-as-vm_fault.patch @@ -0,0 +1,54 @@ +From 0bbc018cb6bc0f9ee288790ec4f0384b874e080d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 May 2023 23:19:06 +0800 +Subject: arm64/mm: mark private VM_FAULT_X defines as vm_fault_t + +From: Min-Hua Chen + +[ Upstream commit d91d580878064b880f3574ac35b98d8b70ee8620 ] + +This patch fixes several sparse warnings for fault.c: + +arch/arm64/mm/fault.c:493:24: sparse: warning: incorrect type in return expression (different base types) +arch/arm64/mm/fault.c:493:24: sparse: expected restricted vm_fault_t +arch/arm64/mm/fault.c:493:24: sparse: got int +arch/arm64/mm/fault.c:501:32: sparse: warning: incorrect type in return expression (different base types) +arch/arm64/mm/fault.c:501:32: sparse: expected restricted vm_fault_t +arch/arm64/mm/fault.c:501:32: sparse: got int +arch/arm64/mm/fault.c:503:32: sparse: warning: incorrect type in return expression (different base types) +arch/arm64/mm/fault.c:503:32: sparse: expected restricted vm_fault_t +arch/arm64/mm/fault.c:503:32: sparse: got int +arch/arm64/mm/fault.c:511:24: sparse: warning: incorrect type in return expression (different base types) +arch/arm64/mm/fault.c:511:24: sparse: expected restricted vm_fault_t +arch/arm64/mm/fault.c:511:24: sparse: got int +arch/arm64/mm/fault.c:670:13: sparse: warning: restricted vm_fault_t degrades to integer +arch/arm64/mm/fault.c:670:13: sparse: warning: restricted vm_fault_t degrades to integer +arch/arm64/mm/fault.c:713:39: sparse: warning: restricted vm_fault_t degrades to integer + +Reported-by: kernel test robot +Signed-off-by: Min-Hua Chen +Link: https://lore.kernel.org/r/20230502151909.128810-1-minhuadotchen@gmail.com +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + arch/arm64/mm/fault.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c +index a8e9c98147a19..af9a6e1fa0d3d 100644 +--- a/arch/arm64/mm/fault.c ++++ b/arch/arm64/mm/fault.c +@@ -403,8 +403,8 @@ static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *re + } + } + +-#define VM_FAULT_BADMAP 0x010000 +-#define VM_FAULT_BADACCESS 0x020000 ++#define VM_FAULT_BADMAP ((__force vm_fault_t)0x010000) ++#define VM_FAULT_BADACCESS ((__force vm_fault_t)0x020000) + + static vm_fault_t __do_page_fault(struct mm_struct *mm, unsigned long addr, + unsigned int mm_flags, unsigned long vm_flags) +-- +2.39.2 + diff --git a/queue-5.4/asoc-dwc-limit-the-number-of-overrun-messages.patch b/queue-5.4/asoc-dwc-limit-the-number-of-overrun-messages.patch new file mode 100644 index 00000000000..a67b95a89ac --- /dev/null +++ b/queue-5.4/asoc-dwc-limit-the-number-of-overrun-messages.patch @@ -0,0 +1,44 @@ +From 6f1bfbd67a94cbe760cf43bb3509ad391eb0d03c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 May 2023 09:28:20 +0300 +Subject: ASoC: dwc: limit the number of overrun messages + +From: Maxim Kochetkov + +[ Upstream commit ab6ecfbf40fccf74b6ec2ba7ed6dd2fc024c3af2 ] + +On slow CPU (FPGA/QEMU emulated) printing overrun messages from +interrupt handler to uart console may leads to more overrun errors. +So use dev_err_ratelimited to limit the number of error messages. + +Signed-off-by: Maxim Kochetkov +--- + sound/soc/dwc/dwc-i2s.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c +index 65112b9d8588a..90b8814d7506a 100644 +--- a/sound/soc/dwc/dwc-i2s.c ++++ b/sound/soc/dwc/dwc-i2s.c +@@ -132,13 +132,13 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id) + + /* Error Handling: TX */ + if (isr[i] & ISR_TXFO) { +- dev_err(dev->dev, "TX overrun (ch_id=%d)\n", i); ++ dev_err_ratelimited(dev->dev, "TX overrun (ch_id=%d)\n", i); + irq_valid = true; + } + + /* Error Handling: TX */ + if (isr[i] & ISR_RXFO) { +- dev_err(dev->dev, "RX overrun (ch_id=%d)\n", i); ++ dev_err_ratelimited(dev->dev, "RX overrun (ch_id=%d)\n", i); + irq_valid = true; + } + } +-- +2.39.2 + diff --git a/queue-5.4/asoc-ssm2602-add-workaround-for-playback-distortions.patch b/queue-5.4/asoc-ssm2602-add-workaround-for-playback-distortions.patch new file mode 100644 index 00000000000..85d8ac04185 --- /dev/null +++ b/queue-5.4/asoc-ssm2602-add-workaround-for-playback-distortions.patch @@ -0,0 +1,140 @@ +From ceef7e7f9dd8d433f05933622779753b9feee7b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 May 2023 13:30:37 +0200 +Subject: ASoC: ssm2602: Add workaround for playback distortions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Paweł Anikiel + +[ Upstream commit f63550e2b165208a2f382afcaf5551df9569e1d4 ] + +Apply a workaround for what appears to be a hardware quirk. + +The problem seems to happen when enabling "whole chip power" (bit D7 +register R6) for the very first time after the chip receives power. If +either "output" (D4) or "DAC" (D3) aren't powered on at that time, +playback becomes very distorted later on. + +This happens on the Google Chameleon v3, as well as on a ZYBO Z7-10: +https://ez.analog.com/audio/f/q-a/543726/solved-ssm2603-right-output-offset-issue/480229 +I suspect this happens only when using an external MCLK signal (which +is the case for both of these boards). + +Here are some experiments run on a Google Chameleon v3. These were run +in userspace using a wrapper around the i2cset utility: +ssmset() { + i2cset -y 0 0x1a $(($1*2)) $2 +} + +For each of the following sequences, we apply power to the ssm2603 +chip, set the configuration registers R0-R5 and R7-R8, run the selected +sequence, and check for distortions on playback. + + ssmset 0x09 0x01 # core + ssmset 0x06 0x07 # chip, out, dac + OK + + ssmset 0x09 0x01 # core + ssmset 0x06 0x87 # out, dac + ssmset 0x06 0x07 # chip + OK + + (disable MCLK) + ssmset 0x09 0x01 # core + ssmset 0x06 0x1f # chip + ssmset 0x06 0x07 # out, dac + (enable MCLK) + OK + + ssmset 0x09 0x01 # core + ssmset 0x06 0x1f # chip + ssmset 0x06 0x07 # out, dac + NOT OK + + ssmset 0x06 0x1f # chip + ssmset 0x09 0x01 # core + ssmset 0x06 0x07 # out, dac + NOT OK + + ssmset 0x09 0x01 # core + ssmset 0x06 0x0f # chip, out + ssmset 0x06 0x07 # dac + NOT OK + + ssmset 0x09 0x01 # core + ssmset 0x06 0x17 # chip, dac + ssmset 0x06 0x07 # out + NOT OK + +For each of the following sequences, we apply power to the ssm2603 +chip, run the selected sequence, issue a reset with R15, configure +R0-R5 and R7-R8, run one of the NOT OK sequences from above, and check +for distortions. + + ssmset 0x09 0x01 # core + ssmset 0x06 0x07 # chip, out, dac + OK + + (disable MCLK) + ssmset 0x09 0x01 # core + ssmset 0x06 0x07 # chip, out, dac + (enable MCLK after reset) + NOT OK + + ssmset 0x09 0x01 # core + ssmset 0x06 0x17 # chip, dac + NOT OK + + ssmset 0x09 0x01 # core + ssmset 0x06 0x0f # chip, out + NOT OK + + ssmset 0x06 0x07 # chip, out, dac + NOT OK + +Signed-off-by: Paweł Anikiel +--- + sound/soc/codecs/ssm2602.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c +index 464a4d7873bba..b797f620e3521 100644 +--- a/sound/soc/codecs/ssm2602.c ++++ b/sound/soc/codecs/ssm2602.c +@@ -53,6 +53,18 @@ static const struct reg_default ssm2602_reg[SSM2602_CACHEREGNUM] = { + { .reg = 0x09, .def = 0x0000 } + }; + ++/* ++ * ssm2602 register patch ++ * Workaround for playback distortions after power up: activates digital ++ * core, and then powers on output, DAC, and whole chip at the same time ++ */ ++ ++static const struct reg_sequence ssm2602_patch[] = { ++ { SSM2602_ACTIVE, 0x01 }, ++ { SSM2602_PWR, 0x07 }, ++ { SSM2602_RESET, 0x00 }, ++}; ++ + + /*Appending several "None"s just for OSS mixer use*/ + static const char *ssm2602_input_select[] = { +@@ -588,6 +600,9 @@ static int ssm260x_component_probe(struct snd_soc_component *component) + return ret; + } + ++ regmap_register_patch(ssm2602->regmap, ssm2602_patch, ++ ARRAY_SIZE(ssm2602_patch)); ++ + /* set the update bits */ + regmap_update_bits(ssm2602->regmap, SSM2602_LINVOL, + LINVOL_LRIN_BOTH, LINVOL_LRIN_BOTH); +-- +2.39.2 + diff --git a/queue-5.4/atm-hide-unused-procfs-functions.patch b/queue-5.4/atm-hide-unused-procfs-functions.patch new file mode 100644 index 00000000000..518065d87d6 --- /dev/null +++ b/queue-5.4/atm-hide-unused-procfs-functions.patch @@ -0,0 +1,47 @@ +From 75efe7fda4462b10b13fba5e573daa9c20e85dc1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 May 2023 21:45:34 +0200 +Subject: atm: hide unused procfs functions + +From: Arnd Bergmann + +[ Upstream commit fb1b7be9b16c1f4626969ba4e95a97da2a452b41 ] + +When CONFIG_PROC_FS is disabled, the function declarations for some +procfs functions are hidden, but the definitions are still build, +as shown by this compiler warning: + +net/atm/resources.c:403:7: error: no previous prototype for 'atm_dev_seq_start' [-Werror=missing-prototypes] +net/atm/resources.c:409:6: error: no previous prototype for 'atm_dev_seq_stop' [-Werror=missing-prototypes] +net/atm/resources.c:414:7: error: no previous prototype for 'atm_dev_seq_next' [-Werror=missing-prototypes] + +Add another #ifdef to leave these out of the build. + +Signed-off-by: Arnd Bergmann +Link: https://lore.kernel.org/r/20230516194625.549249-2-arnd@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/atm/resources.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/atm/resources.c b/net/atm/resources.c +index 889349c6d90db..04b2235c5c261 100644 +--- a/net/atm/resources.c ++++ b/net/atm/resources.c +@@ -443,6 +443,7 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg, int compat) + return error; + } + ++#ifdef CONFIG_PROC_FS + void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos) + { + mutex_lock(&atm_dev_mutex); +@@ -458,3 +459,4 @@ void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) + { + return seq_list_next(v, &atm_devs, pos); + } ++#endif +-- +2.39.2 + diff --git a/queue-5.4/dmaengine-pl330-rename-_start-to-prevent-build-error.patch b/queue-5.4/dmaengine-pl330-rename-_start-to-prevent-build-error.patch new file mode 100644 index 00000000000..71d25c7c34e --- /dev/null +++ b/queue-5.4/dmaengine-pl330-rename-_start-to-prevent-build-error.patch @@ -0,0 +1,85 @@ +From 926382f4366229ed7428f982ac943f2a1c957225 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 May 2023 21:53:10 -0700 +Subject: dmaengine: pl330: rename _start to prevent build error + +From: Randy Dunlap + +[ Upstream commit a1a5f2c887252dec161c1e12e04303ca9ba56fa9 ] + +"_start" is used in several arches and proably should be reserved +for ARCH usage. Using it in a driver for a private symbol can cause +a build error when it conflicts with ARCH usage of the same symbol. + +Therefore rename pl330's "_start" to "pl330_start_thread" so that there +is no conflict and no build error. + +drivers/dma/pl330.c:1053:13: error: '_start' redeclared as different kind of symbol + 1053 | static bool _start(struct pl330_thread *thrd) + | ^~~~~~ +In file included from ../include/linux/interrupt.h:21, + from ../drivers/dma/pl330.c:18: +arch/riscv/include/asm/sections.h:11:13: note: previous declaration of '_start' with type 'char[]' + 11 | extern char _start[]; + | ^~~~~~ + +Fixes: b7d861d93945 ("DMA: PL330: Merge PL330 driver into drivers/dma/") +Fixes: ae43b3289186 ("ARM: 8202/1: dmaengine: pl330: Add runtime Power Management support v12") +Signed-off-by: Randy Dunlap +Cc: Jaswinder Singh +Cc: Boojin Kim +Cc: Krzysztof Kozlowski +Cc: Russell King +Cc: Vinod Koul +Cc: dmaengine@vger.kernel.org +Cc: linux-riscv@lists.infradead.org +Link: https://lore.kernel.org/r/20230524045310.27923-1-rdunlap@infradead.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/dma/pl330.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c +index 77a6495bb6b19..3008ab258fa8e 100644 +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -1048,7 +1048,7 @@ static bool _trigger(struct pl330_thread *thrd) + return true; + } + +-static bool _start(struct pl330_thread *thrd) ++static bool pl330_start_thread(struct pl330_thread *thrd) + { + switch (_state(thrd)) { + case PL330_STATE_FAULT_COMPLETING: +@@ -1696,7 +1696,7 @@ static int pl330_update(struct pl330_dmac *pl330) + thrd->req_running = -1; + + /* Get going again ASAP */ +- _start(thrd); ++ pl330_start_thread(thrd); + + /* For now, just make a list of callbacks to be done */ + list_add_tail(&descdone->rqd, &pl330->req_done); +@@ -2083,7 +2083,7 @@ static void pl330_tasklet(unsigned long data) + } else { + /* Make sure the PL330 Channel thread is active */ + spin_lock(&pch->thread->dmac->lock); +- _start(pch->thread); ++ pl330_start_thread(pch->thread); + spin_unlock(&pch->thread->dmac->lock); + } + +@@ -2101,7 +2101,7 @@ static void pl330_tasklet(unsigned long data) + if (power_down) { + pch->active = true; + spin_lock(&pch->thread->dmac->lock); +- _start(pch->thread); ++ pl330_start_thread(pch->thread); + spin_unlock(&pch->thread->dmac->lock); + power_down = false; + } +-- +2.39.2 + diff --git a/queue-5.4/fbdev-modedb-add-1920x1080-at-60-hz-video-mode.patch b/queue-5.4/fbdev-modedb-add-1920x1080-at-60-hz-video-mode.patch new file mode 100644 index 00000000000..a3236dbd90f --- /dev/null +++ b/queue-5.4/fbdev-modedb-add-1920x1080-at-60-hz-video-mode.patch @@ -0,0 +1,36 @@ +From cfc0314d5acc3224b699e693aae563023266b491 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Apr 2023 23:24:26 +0200 +Subject: fbdev: modedb: Add 1920x1080 at 60 Hz video mode + +From: Helge Deller + +[ Upstream commit c8902258b2b8ecaa1b8d88c312853c5b14c2553d ] + +Add typical resolution for Full-HD monitors. + +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/core/modedb.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c +index 6473e0dfe1464..e78ec7f728463 100644 +--- a/drivers/video/fbdev/core/modedb.c ++++ b/drivers/video/fbdev/core/modedb.c +@@ -257,6 +257,11 @@ static const struct fb_videomode modedb[] = { + { NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, 0, + FB_VMODE_DOUBLE }, + ++ /* 1920x1080 @ 60 Hz, 67.3 kHz hsync */ ++ { NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5, 0, ++ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, ++ FB_VMODE_NONINTERLACED }, ++ + /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */ + { NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, +-- +2.39.2 + diff --git a/queue-5.4/fbdev-stifb-fix-info-entry-in-sti_struct-on-error-pa.patch b/queue-5.4/fbdev-stifb-fix-info-entry-in-sti_struct-on-error-pa.patch new file mode 100644 index 00000000000..012a3250a25 --- /dev/null +++ b/queue-5.4/fbdev-stifb-fix-info-entry-in-sti_struct-on-error-pa.patch @@ -0,0 +1,32 @@ +From e2213fdae0be79bbd4a71ce19906409efc536cb6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 May 2023 11:50:33 +0200 +Subject: fbdev: stifb: Fix info entry in sti_struct on error path + +From: Helge Deller + +[ Upstream commit 0bdf1ad8d10bd4e50a8b1a2c53d15984165f7fea ] + +Minor fix to reset the info field to NULL in case of error. + +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/stifb.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c +index e606fc7287947..9c2be08026514 100644 +--- a/drivers/video/fbdev/stifb.c ++++ b/drivers/video/fbdev/stifb.c +@@ -1371,6 +1371,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) + iounmap(info->screen_base); + out_err0: + kfree(fb); ++ sti->info = NULL; + return -ENXIO; + } + +-- +2.39.2 + diff --git a/queue-5.4/iommu-amd-don-t-block-updates-to-gatag-if-guest-mode.patch b/queue-5.4/iommu-amd-don-t-block-updates-to-gatag-if-guest-mode.patch new file mode 100644 index 00000000000..c617e93c679 --- /dev/null +++ b/queue-5.4/iommu-amd-don-t-block-updates-to-gatag-if-guest-mode.patch @@ -0,0 +1,76 @@ +From 58abef1cb7afae5961908ff7292eca2b8f2fbae4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Apr 2023 21:11:53 +0100 +Subject: iommu/amd: Don't block updates to GATag if guest mode is on + +From: Joao Martins + +[ Upstream commit ed8a2f4ddef2eaaf864ab1efbbca9788187036ab ] + +On KVM GSI routing table updates, specially those where they have vIOMMUs +with interrupt remapping enabled (to boot >255vcpus setups without relying +on KVM_FEATURE_MSI_EXT_DEST_ID), a VMM may update the backing VF MSIs +with a new VCPU affinity. + +On AMD with AVIC enabled, the new vcpu affinity info is updated via: + avic_pi_update_irte() + irq_set_vcpu_affinity() + amd_ir_set_vcpu_affinity() + amd_iommu_{de}activate_guest_mode() + +Where the IRTE[GATag] is updated with the new vcpu affinity. The GATag +contains VM ID and VCPU ID, and is used by IOMMU hardware to signal KVM +(via GALog) when interrupt cannot be delivered due to vCPU is in +blocking state. + +The issue is that amd_iommu_activate_guest_mode() will essentially +only change IRTE fields on transitions from non-guest-mode to guest-mode +and otherwise returns *with no changes to IRTE* on already configured +guest-mode interrupts. To the guest this means that the VF interrupts +remain affined to the first vCPU they were first configured, and guest +will be unable to issue VF interrupts and receive messages like this +from spurious interrupts (e.g. from waking the wrong vCPU in GALog): + +[ 167.759472] __common_interrupt: 3.34 No irq handler for vector +[ 230.680927] mlx5_core 0000:00:02.0: mlx5_cmd_eq_recover:247:(pid +3122): Recovered 1 EQEs on cmd_eq +[ 230.681799] mlx5_core 0000:00:02.0: +wait_func_handle_exec_timeout:1113:(pid 3122): cmd[0]: CREATE_CQ(0x400) +recovered after timeout +[ 230.683266] __common_interrupt: 3.34 No irq handler for vector + +Given the fact that amd_ir_set_vcpu_affinity() uses +amd_iommu_activate_guest_mode() underneath it essentially means that VCPU +affinity changes of IRTEs are nops. Fix it by dropping the check for +guest-mode at amd_iommu_activate_guest_mode(). Same thing is applicable to +amd_iommu_deactivate_guest_mode() although, even if the IRTE doesn't change +underlying DestID on the host, the VFIO IRQ handler will still be able to +poke at the right guest-vCPU. + +Fixes: b9c6ff94e43a ("iommu/amd: Re-factor guest virtual APIC (de-)activation code") +Signed-off-by: Joao Martins +Reviewed-by: Suravee Suthikulpanit +Link: https://lore.kernel.org/r/20230419201154.83880-2-joao.m.martins@oracle.com +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/amd_iommu.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c +index b79309928d786..a30aac41af426 100644 +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -4420,8 +4420,7 @@ int amd_iommu_activate_guest_mode(void *data) + struct amd_ir_data *ir_data = (struct amd_ir_data *)data; + struct irte_ga *entry = (struct irte_ga *) ir_data->entry; + +- if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) || +- !entry || entry->lo.fields_vapic.guest_mode) ++ if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) || !entry) + return 0; + + entry->lo.val = 0; +-- +2.39.2 + diff --git a/queue-5.4/iommu-rockchip-fix-unwind-goto-issue.patch b/queue-5.4/iommu-rockchip-fix-unwind-goto-issue.patch new file mode 100644 index 00000000000..de5af91128c --- /dev/null +++ b/queue-5.4/iommu-rockchip-fix-unwind-goto-issue.patch @@ -0,0 +1,65 @@ +From d3e0c6d9c17f713dafbc3a41c7535af3dd6200a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Apr 2023 03:04:21 +0000 +Subject: iommu/rockchip: Fix unwind goto issue + +From: Chao Wang + +[ Upstream commit ec014683c564fb74fc68e8f5e84691d3b3839d24 ] + +Smatch complains that +drivers/iommu/rockchip-iommu.c:1306 rk_iommu_probe() warn: missing unwind goto? + +The rk_iommu_probe function, after obtaining the irq value through +platform_get_irq, directly returns an error if the returned value +is negative, without releasing any resources. + +Fix this by adding a new error handling label "err_pm_disable" and +use a goto statement to redirect to the error handling process. In +order to preserve the original semantics, set err to the value of irq. + +Fixes: 1aa55ca9b14a ("iommu/rockchip: Move irq request past pm_runtime_enable") +Signed-off-by: Chao Wang +Reviewed-by: Dongliang Mu +Reviewed-by: Heiko Stuebner +Link: https://lore.kernel.org/r/20230417030421.2777-1-D202280639@hust.edu.cn +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/rockchip-iommu.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c +index 96f37d9d4d93c..67a8c08d82105 100644 +--- a/drivers/iommu/rockchip-iommu.c ++++ b/drivers/iommu/rockchip-iommu.c +@@ -1230,18 +1230,20 @@ static int rk_iommu_probe(struct platform_device *pdev) + for (i = 0; i < iommu->num_irq; i++) { + int irq = platform_get_irq(pdev, i); + +- if (irq < 0) +- return irq; ++ if (irq < 0) { ++ err = irq; ++ goto err_pm_disable; ++ } + + err = devm_request_irq(iommu->dev, irq, rk_iommu_irq, + IRQF_SHARED, dev_name(dev), iommu); +- if (err) { +- pm_runtime_disable(dev); +- goto err_remove_sysfs; +- } ++ if (err) ++ goto err_pm_disable; + } + + return 0; ++err_pm_disable: ++ pm_runtime_disable(dev); + err_remove_sysfs: + iommu_device_sysfs_remove(&iommu->iommu); + err_put_group: +-- +2.39.2 + diff --git a/queue-5.4/mailbox-mailbox-test-fix-a-locking-issue-in-mbox_tes.patch b/queue-5.4/mailbox-mailbox-test-fix-a-locking-issue-in-mbox_tes.patch new file mode 100644 index 00000000000..206126a6e44 --- /dev/null +++ b/queue-5.4/mailbox-mailbox-test-fix-a-locking-issue-in-mbox_tes.patch @@ -0,0 +1,56 @@ +From 2ca897d1c76d1cda606649efdb3adee23026130c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 May 2023 12:22:09 +0300 +Subject: mailbox: mailbox-test: fix a locking issue in + mbox_test_message_write() + +From: Dan Carpenter + +[ Upstream commit 8fe72b76db79d694858e872370df49676bc3be8c ] + +There was a bug where this code forgot to unlock the tdev->mutex if the +kzalloc() failed. Fix this issue, by moving the allocation outside the +lock. + +Fixes: 2d1e952a2b8e ("mailbox: mailbox-test: Fix potential double-free in mbox_test_message_write()") +Signed-off-by: Dan Carpenter +Reviewed-by: Lee Jones +Signed-off-by: Jassi Brar +Signed-off-by: Sasha Levin +--- + drivers/mailbox/mailbox-test.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c +index 6dd5b9614452b..abcee58e851c2 100644 +--- a/drivers/mailbox/mailbox-test.c ++++ b/drivers/mailbox/mailbox-test.c +@@ -97,6 +97,7 @@ static ssize_t mbox_test_message_write(struct file *filp, + size_t count, loff_t *ppos) + { + struct mbox_test_device *tdev = filp->private_data; ++ char *message; + void *data; + int ret; + +@@ -112,12 +113,13 @@ static ssize_t mbox_test_message_write(struct file *filp, + return -EINVAL; + } + +- mutex_lock(&tdev->mutex); +- +- tdev->message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL); +- if (!tdev->message) ++ message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL); ++ if (!message) + return -ENOMEM; + ++ mutex_lock(&tdev->mutex); ++ ++ tdev->message = message; + ret = copy_from_user(tdev->message, userbuf, count); + if (ret) { + ret = -EFAULT; +-- +2.39.2 + diff --git a/queue-5.4/mailbox-mailbox-test-fix-potential-double-free-in-mb.patch b/queue-5.4/mailbox-mailbox-test-fix-potential-double-free-in-mb.patch new file mode 100644 index 00000000000..7fd48e436c4 --- /dev/null +++ b/queue-5.4/mailbox-mailbox-test-fix-potential-double-free-in-mb.patch @@ -0,0 +1,136 @@ +From 9bda765c5f712b3c15729f8e840f61061884b65d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Apr 2023 08:27:18 +0100 +Subject: mailbox: mailbox-test: Fix potential double-free in + mbox_test_message_write() + +From: Lee Jones + +[ Upstream commit 2d1e952a2b8e5e92d8d55ac88a7cf7ca5ea591ad ] + +If a user can make copy_from_user() fail, there is a potential for +UAF/DF due to a lack of locking around the allocation, use and freeing +of the data buffers. + +This issue is not theoretical. I managed to author a POC for it: + + BUG: KASAN: double-free in kfree+0x5c/0xac + Free of addr ffff29280be5de00 by task poc/356 + CPU: 1 PID: 356 Comm: poc Not tainted 6.1.0-00001-g961aa6552c04-dirty #20 + Hardware name: linux,dummy-virt (DT) + Call trace: + dump_backtrace.part.0+0xe0/0xf0 + show_stack+0x18/0x40 + dump_stack_lvl+0x64/0x80 + print_report+0x188/0x48c + kasan_report_invalid_free+0xa0/0xc0 + ____kasan_slab_free+0x174/0x1b0 + __kasan_slab_free+0x18/0x24 + __kmem_cache_free+0x130/0x2e0 + kfree+0x5c/0xac + mbox_test_message_write+0x208/0x29c + full_proxy_write+0x90/0xf0 + vfs_write+0x154/0x440 + ksys_write+0xcc/0x180 + __arm64_sys_write+0x44/0x60 + invoke_syscall+0x60/0x190 + el0_svc_common.constprop.0+0x7c/0x160 + do_el0_svc+0x40/0xf0 + el0_svc+0x2c/0x6c + el0t_64_sync_handler+0xf4/0x120 + el0t_64_sync+0x18c/0x190 + + Allocated by task 356: + kasan_save_stack+0x3c/0x70 + kasan_set_track+0x2c/0x40 + kasan_save_alloc_info+0x24/0x34 + __kasan_kmalloc+0xb8/0xc0 + kmalloc_trace+0x58/0x70 + mbox_test_message_write+0x6c/0x29c + full_proxy_write+0x90/0xf0 + vfs_write+0x154/0x440 + ksys_write+0xcc/0x180 + __arm64_sys_write+0x44/0x60 + invoke_syscall+0x60/0x190 + el0_svc_common.constprop.0+0x7c/0x160 + do_el0_svc+0x40/0xf0 + el0_svc+0x2c/0x6c + el0t_64_sync_handler+0xf4/0x120 + el0t_64_sync+0x18c/0x190 + + Freed by task 357: + kasan_save_stack+0x3c/0x70 + kasan_set_track+0x2c/0x40 + kasan_save_free_info+0x38/0x5c + ____kasan_slab_free+0x13c/0x1b0 + __kasan_slab_free+0x18/0x24 + __kmem_cache_free+0x130/0x2e0 + kfree+0x5c/0xac + mbox_test_message_write+0x208/0x29c + full_proxy_write+0x90/0xf0 + vfs_write+0x154/0x440 + ksys_write+0xcc/0x180 + __arm64_sys_write+0x44/0x60 + invoke_syscall+0x60/0x190 + el0_svc_common.constprop.0+0x7c/0x160 + do_el0_svc+0x40/0xf0 + el0_svc+0x2c/0x6c + el0t_64_sync_handler+0xf4/0x120 + el0t_64_sync+0x18c/0x190 + +Signed-off-by: Lee Jones +Signed-off-by: Jassi Brar +Signed-off-by: Sasha Levin +--- + drivers/mailbox/mailbox-test.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c +index 4555d678fadda..6dd5b9614452b 100644 +--- a/drivers/mailbox/mailbox-test.c ++++ b/drivers/mailbox/mailbox-test.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -38,6 +39,7 @@ struct mbox_test_device { + char *signal; + char *message; + spinlock_t lock; ++ struct mutex mutex; + wait_queue_head_t waitq; + struct fasync_struct *async_queue; + struct dentry *root_debugfs_dir; +@@ -110,6 +112,8 @@ static ssize_t mbox_test_message_write(struct file *filp, + return -EINVAL; + } + ++ mutex_lock(&tdev->mutex); ++ + tdev->message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL); + if (!tdev->message) + return -ENOMEM; +@@ -144,6 +148,8 @@ static ssize_t mbox_test_message_write(struct file *filp, + kfree(tdev->message); + tdev->signal = NULL; + ++ mutex_unlock(&tdev->mutex); ++ + return ret < 0 ? ret : count; + } + +@@ -392,6 +398,7 @@ static int mbox_test_probe(struct platform_device *pdev) + platform_set_drvdata(pdev, tdev); + + spin_lock_init(&tdev->lock); ++ mutex_init(&tdev->mutex); + + if (tdev->rx_channel) { + tdev->rx_buffer = devm_kzalloc(&pdev->dev, +-- +2.39.2 + diff --git a/queue-5.4/media-dvb-core-fix-kernel-warning-for-blocking-opera.patch b/queue-5.4/media-dvb-core-fix-kernel-warning-for-blocking-opera.patch new file mode 100644 index 00000000000..738f54a4b40 --- /dev/null +++ b/queue-5.4/media-dvb-core-fix-kernel-warning-for-blocking-opera.patch @@ -0,0 +1,67 @@ +From fd985da76851fb7155646418157e919f53884617 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 May 2023 16:18:00 +0100 +Subject: media: dvb-core: Fix kernel WARNING for blocking operation in + wait_event*() + +From: Takashi Iwai + +[ Upstream commit b8c75e4a1b325ea0a9433fa8834be97b5836b946 ] + +Using a semaphore in the wait_event*() condition is no good idea. +It hits a kernel WARN_ON() at prepare_to_wait_event() like: + do not call blocking ops when !TASK_RUNNING; state=1 set at + prepare_to_wait_event+0x6d/0x690 + +For avoiding the potential deadlock, rewrite to an open-coded loop +instead. Unlike the loop in wait_event*(), this uses wait_woken() +after the condition check, hence the task state stays consistent. + +CVE-2023-31084 was assigned to this bug. + +Link: https://lore.kernel.org/r/CA+UBctCu7fXn4q41O_3=id1+OdyQ85tZY1x+TkT-6OVBL6KAUw@mail.gmail.com/ + +Link: https://lore.kernel.org/linux-media/20230512151800.1874-1-tiwai@suse.de +Reported-by: Yu Hao +Closes: https://nvd.nist.gov/vuln/detail/CVE-2023-31084 +Signed-off-by: Takashi Iwai +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/dvb-core/dvb_frontend.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c +index b04638321b75b..ad3e42a4eaf73 100644 +--- a/drivers/media/dvb-core/dvb_frontend.c ++++ b/drivers/media/dvb-core/dvb_frontend.c +@@ -292,14 +292,22 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe, + } + + if (events->eventw == events->eventr) { +- int ret; ++ struct wait_queue_entry wait; ++ int ret = 0; + + if (flags & O_NONBLOCK) + return -EWOULDBLOCK; + +- ret = wait_event_interruptible(events->wait_queue, +- dvb_frontend_test_event(fepriv, events)); +- ++ init_waitqueue_entry(&wait, current); ++ add_wait_queue(&events->wait_queue, &wait); ++ while (!dvb_frontend_test_event(fepriv, events)) { ++ wait_woken(&wait, TASK_INTERRUPTIBLE, 0); ++ if (signal_pending(current)) { ++ ret = -ERESTARTSYS; ++ break; ++ } ++ } ++ remove_wait_queue(&events->wait_queue, &wait); + if (ret < 0) + return ret; + } +-- +2.39.2 + diff --git a/queue-5.4/media-dvb-core-fix-use-after-free-due-on-race-condit.patch b/queue-5.4/media-dvb-core-fix-use-after-free-due-on-race-condit.patch new file mode 100644 index 00000000000..0614453c303 --- /dev/null +++ b/queue-5.4/media-dvb-core-fix-use-after-free-due-on-race-condit.patch @@ -0,0 +1,138 @@ +From a92aa7cc64acc27195f8ac8e067b89ce7d039a4c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 04:59:23 +0000 +Subject: media: dvb-core: Fix use-after-free due on race condition at dvb_net + +From: Hyunwoo Kim + +[ Upstream commit 4172385b0c9ac366dcab78eda48c26814b87ed1a ] + +A race condition may occur between the .disconnect function, which +is called when the device is disconnected, and the dvb_device_open() +function, which is called when the device node is open()ed. +This results in several types of UAFs. + +The root cause of this is that you use the dvb_device_open() function, +which does not implement a conditional statement +that checks 'dvbnet->exit'. + +So, add 'remove_mutex` to protect 'dvbnet->exit' and use +locked_dvb_net_open() function to check 'dvbnet->exit'. + +[mchehab: fix a checkpatch warning] + +Link: https://lore.kernel.org/linux-media/20221117045925.14297-3-imv4bel@gmail.com +Signed-off-by: Hyunwoo Kim +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/dvb-core/dvb_net.c | 38 +++++++++++++++++++++++++++++--- + include/media/dvb_net.h | 4 ++++ + 2 files changed, 39 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c +index 9fed06ba88efb..ccaaabaaeb571 100644 +--- a/drivers/media/dvb-core/dvb_net.c ++++ b/drivers/media/dvb-core/dvb_net.c +@@ -1564,15 +1564,43 @@ static long dvb_net_ioctl(struct file *file, + return dvb_usercopy(file, cmd, arg, dvb_net_do_ioctl); + } + ++static int locked_dvb_net_open(struct inode *inode, struct file *file) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct dvb_net *dvbnet = dvbdev->priv; ++ int ret; ++ ++ if (mutex_lock_interruptible(&dvbnet->remove_mutex)) ++ return -ERESTARTSYS; ++ ++ if (dvbnet->exit) { ++ mutex_unlock(&dvbnet->remove_mutex); ++ return -ENODEV; ++ } ++ ++ ret = dvb_generic_open(inode, file); ++ ++ mutex_unlock(&dvbnet->remove_mutex); ++ ++ return ret; ++} ++ + static int dvb_net_close(struct inode *inode, struct file *file) + { + struct dvb_device *dvbdev = file->private_data; + struct dvb_net *dvbnet = dvbdev->priv; + ++ mutex_lock(&dvbnet->remove_mutex); ++ + dvb_generic_release(inode, file); + +- if(dvbdev->users == 1 && dvbnet->exit == 1) ++ if (dvbdev->users == 1 && dvbnet->exit == 1) { ++ mutex_unlock(&dvbnet->remove_mutex); + wake_up(&dvbdev->wait_queue); ++ } else { ++ mutex_unlock(&dvbnet->remove_mutex); ++ } ++ + return 0; + } + +@@ -1580,7 +1608,7 @@ static int dvb_net_close(struct inode *inode, struct file *file) + static const struct file_operations dvb_net_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = dvb_net_ioctl, +- .open = dvb_generic_open, ++ .open = locked_dvb_net_open, + .release = dvb_net_close, + .llseek = noop_llseek, + }; +@@ -1599,10 +1627,13 @@ void dvb_net_release (struct dvb_net *dvbnet) + { + int i; + ++ mutex_lock(&dvbnet->remove_mutex); + dvbnet->exit = 1; ++ mutex_unlock(&dvbnet->remove_mutex); ++ + if (dvbnet->dvbdev->users < 1) + wait_event(dvbnet->dvbdev->wait_queue, +- dvbnet->dvbdev->users==1); ++ dvbnet->dvbdev->users == 1); + + dvb_unregister_device(dvbnet->dvbdev); + +@@ -1621,6 +1652,7 @@ int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet, + int i; + + mutex_init(&dvbnet->ioctl_mutex); ++ mutex_init(&dvbnet->remove_mutex); + dvbnet->demux = dmx; + + for (i=0; i +Date: Mon, 21 Nov 2022 06:33:08 +0000 +Subject: media: dvb-core: Fix use-after-free due to race condition at + dvb_ca_en50221 + +From: Hyunwoo Kim + +[ Upstream commit 280a8ab81733da8bc442253c700a52c4c0886ffd ] + +If the device node of dvb_ca_en50221 is open() and the +device is disconnected, a UAF may occur when calling +close() on the device node. + +The root cause is that wake_up() and wait_event() for +dvbdev->wait_queue are not implemented. + +So implement wait_event() function in dvb_ca_en50221_release() +and add 'remove_mutex' which prevents race condition +for 'ca->exit'. + +[mchehab: fix a checkpatch warning] + +Link: https://lore.kernel.org/linux-media/20221121063308.GA33821@ubuntu +Signed-off-by: Hyunwoo Kim +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/dvb-core/dvb_ca_en50221.c | 37 ++++++++++++++++++++++++- + 1 file changed, 36 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c +index b1a7b5f8b9aa4..dec036e0336cb 100644 +--- a/drivers/media/dvb-core/dvb_ca_en50221.c ++++ b/drivers/media/dvb-core/dvb_ca_en50221.c +@@ -151,6 +151,12 @@ struct dvb_ca_private { + + /* mutex serializing ioctls */ + struct mutex ioctl_mutex; ++ ++ /* A mutex used when a device is disconnected */ ++ struct mutex remove_mutex; ++ ++ /* Whether the device is disconnected */ ++ int exit; + }; + + static void dvb_ca_private_free(struct dvb_ca_private *ca) +@@ -1708,12 +1714,22 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) + + dprintk("%s\n", __func__); + +- if (!try_module_get(ca->pub->owner)) ++ mutex_lock(&ca->remove_mutex); ++ ++ if (ca->exit) { ++ mutex_unlock(&ca->remove_mutex); ++ return -ENODEV; ++ } ++ ++ if (!try_module_get(ca->pub->owner)) { ++ mutex_unlock(&ca->remove_mutex); + return -EIO; ++ } + + err = dvb_generic_open(inode, file); + if (err < 0) { + module_put(ca->pub->owner); ++ mutex_unlock(&ca->remove_mutex); + return err; + } + +@@ -1738,6 +1754,7 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) + + dvb_ca_private_get(ca); + ++ mutex_unlock(&ca->remove_mutex); + return 0; + } + +@@ -1757,6 +1774,8 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file) + + dprintk("%s\n", __func__); + ++ mutex_lock(&ca->remove_mutex); ++ + /* mark the CA device as closed */ + ca->open = 0; + dvb_ca_en50221_thread_update_delay(ca); +@@ -1767,6 +1786,13 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file) + + dvb_ca_private_put(ca); + ++ if (dvbdev->users == 1 && ca->exit == 1) { ++ mutex_unlock(&ca->remove_mutex); ++ wake_up(&dvbdev->wait_queue); ++ } else { ++ mutex_unlock(&ca->remove_mutex); ++ } ++ + return err; + } + +@@ -1890,6 +1916,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, + } + + mutex_init(&ca->ioctl_mutex); ++ mutex_init(&ca->remove_mutex); + + if (signal_pending(current)) { + ret = -EINTR; +@@ -1932,6 +1959,14 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) + + dprintk("%s\n", __func__); + ++ mutex_lock(&ca->remove_mutex); ++ ca->exit = 1; ++ mutex_unlock(&ca->remove_mutex); ++ ++ if (ca->dvbdev->users < 1) ++ wait_event(ca->dvbdev->wait_queue, ++ ca->dvbdev->users == 1); ++ + /* shutdown the thread if there was one */ + kthread_stop(ca->thread); + +-- +2.39.2 + diff --git a/queue-5.4/media-dvb-usb-az6027-fix-three-null-ptr-deref-in-az6.patch b/queue-5.4/media-dvb-usb-az6027-fix-three-null-ptr-deref-in-az6.patch new file mode 100644 index 00000000000..3b86a5140cd --- /dev/null +++ b/queue-5.4/media-dvb-usb-az6027-fix-three-null-ptr-deref-in-az6.patch @@ -0,0 +1,63 @@ +From fbd9de3dd292463530f25aec36b4b3e073afdcd1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Mar 2023 16:56:04 +0000 +Subject: media: dvb-usb: az6027: fix three null-ptr-deref in az6027_i2c_xfer() + +From: Wei Chen + +[ Upstream commit 858e97d7956d17a2cb56a9413468704a4d5abfe1 ] + +In az6027_i2c_xfer, msg is controlled by user. When msg[i].buf is null, +commit 0ed554fd769a ("media: dvb-usb: az6027: fix null-ptr-deref in +az6027_i2c_xfer()") fix the null-ptr-deref bug when msg[i].addr is 0x99. +However, null-ptr-deref also happens when msg[i].addr is 0xd0 and 0xc0. +We add check on msg[i].len to prevent null-ptr-deref. + +Link: https://lore.kernel.org/linux-media/20230310165604.3093483-1-harperchen1110@gmail.com +Signed-off-by: Wei Chen +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/usb/dvb-usb/az6027.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c +index ffc0db67d4d68..2b56393d10008 100644 +--- a/drivers/media/usb/dvb-usb/az6027.c ++++ b/drivers/media/usb/dvb-usb/az6027.c +@@ -988,6 +988,10 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n + /* write/read request */ + if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) { + req = 0xB9; ++ if (msg[i].len < 1) { ++ i = -EOPNOTSUPP; ++ break; ++ } + index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff)); + value = msg[i].addr + (msg[i].len << 8); + length = msg[i + 1].len + 6; +@@ -1001,6 +1005,10 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n + + /* demod 16bit addr */ + req = 0xBD; ++ if (msg[i].len < 1) { ++ i = -EOPNOTSUPP; ++ break; ++ } + index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff)); + value = msg[i].addr + (2 << 8); + length = msg[i].len - 2; +@@ -1026,6 +1034,10 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n + } else { + + req = 0xBD; ++ if (msg[i].len < 1) { ++ i = -EOPNOTSUPP; ++ break; ++ } + index = msg[i].buf[0] & 0x00FF; + value = msg[i].addr + (1 << 8); + length = msg[i].len - 1; +-- +2.39.2 + diff --git a/queue-5.4/media-dvb-usb-digitv-fix-null-ptr-deref-in-digitv_i2.patch b/queue-5.4/media-dvb-usb-digitv-fix-null-ptr-deref-in-digitv_i2.patch new file mode 100644 index 00000000000..123880ac212 --- /dev/null +++ b/queue-5.4/media-dvb-usb-digitv-fix-null-ptr-deref-in-digitv_i2.patch @@ -0,0 +1,44 @@ +From 2776dda827a67156488ede7b39bf7120d56ddad1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Mar 2023 09:50:08 +0000 +Subject: media: dvb-usb: digitv: fix null-ptr-deref in digitv_i2c_xfer() + +From: Wei Chen + +[ Upstream commit 9ded5bd2a49ce3015b7c936743eec0a0e6e11f0c ] + +In digitv_i2c_xfer, msg is controlled by user. When msg[i].buf +is null and msg[i].len is zero, former checks on msg[i].buf would be +passed. Malicious data finally reach digitv_i2c_xfer. If accessing +msg[i].buf[0] without sanity check, null ptr deref would happen. We add +check on msg[i].len to prevent crash. + +Similar commit: +commit 0ed554fd769a ("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()") + +Link: https://lore.kernel.org/linux-media/20230313095008.1039689-1-harperchen1110@gmail.com +Signed-off-by: Wei Chen +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/usb/dvb-usb/digitv.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/media/usb/dvb-usb/digitv.c b/drivers/media/usb/dvb-usb/digitv.c +index 99a39339d45d5..cf5ec8c1f6773 100644 +--- a/drivers/media/usb/dvb-usb/digitv.c ++++ b/drivers/media/usb/dvb-usb/digitv.c +@@ -63,6 +63,10 @@ static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num + warn("more than 2 i2c messages at a time is not handled yet. TODO."); + + for (i = 0; i < num; i++) { ++ if (msg[i].len < 1) { ++ i = -EOPNOTSUPP; ++ break; ++ } + /* write/read request */ + if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { + if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0, +-- +2.39.2 + diff --git a/queue-5.4/media-dvb-usb-dw2102-fix-uninit-value-in-su3000_read.patch b/queue-5.4/media-dvb-usb-dw2102-fix-uninit-value-in-su3000_read.patch new file mode 100644 index 00000000000..629f498afc0 --- /dev/null +++ b/queue-5.4/media-dvb-usb-dw2102-fix-uninit-value-in-su3000_read.patch @@ -0,0 +1,40 @@ +From c1104708f0915fe76de0c50cc64e9527276eed82 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Mar 2023 13:44:16 +0100 +Subject: media: dvb-usb: dw2102: fix uninit-value in su3000_read_mac_address + +From: Wei Chen + +[ Upstream commit a3fd1ef27aa686d871cefe207bd6168c4b0cd29e ] + +In su3000_read_mac_address, if i2c_transfer fails to execute two +messages, array mac address will not be initialized. Without handling +such error, later in function dvb_usb_adapter_dvb_init, proposed_mac +is accessed before initialization. + +Fix this error by returning a negative value if message execution fails. + +Link: https://lore.kernel.org/linux-media/20230328124416.560889-1-harperchen1110@gmail.com +Signed-off-by: Wei Chen +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/usb/dvb-usb/dw2102.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c +index 8493ebb377c4d..f8f589ebab74b 100644 +--- a/drivers/media/usb/dvb-usb/dw2102.c ++++ b/drivers/media/usb/dvb-usb/dw2102.c +@@ -946,7 +946,7 @@ static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) + for (i = 0; i < 6; i++) { + obuf[1] = 0xf0 + i; + if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) +- break; ++ return -1; + else + mac[i] = ibuf[0]; + } +-- +2.39.2 + diff --git a/queue-5.4/media-dvb-usb-v2-ce6230-fix-null-ptr-deref-in-ce6230.patch b/queue-5.4/media-dvb-usb-v2-ce6230-fix-null-ptr-deref-in-ce6230.patch new file mode 100644 index 00000000000..75604ef3f93 --- /dev/null +++ b/queue-5.4/media-dvb-usb-v2-ce6230-fix-null-ptr-deref-in-ce6230.patch @@ -0,0 +1,56 @@ +From a8889ad2d35bab0dc114c860114abdb73dab67c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Mar 2023 09:27:51 +0000 +Subject: media: dvb-usb-v2: ce6230: fix null-ptr-deref in + ce6230_i2c_master_xfer() + +From: Wei Chen + +[ Upstream commit dff919090155fb22679869e8469168f270dcd97f ] + +In ce6230_i2c_master_xfer, msg is controlled by user. When msg[i].buf +is null and msg[i].len is zero, former checks on msg[i].buf would be +passed. Malicious data finally reach ce6230_i2c_master_xfer. If accessing +msg[i].buf[0] without sanity check, null ptr deref would happen. We add +check on msg[i].len to prevent crash. + +Similar commit: +commit 0ed554fd769a ("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()") + +Link: https://lore.kernel.org/linux-media/20230313092751.209496-1-harperchen1110@gmail.com +Signed-off-by: Wei Chen +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/usb/dvb-usb-v2/ce6230.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/media/usb/dvb-usb-v2/ce6230.c b/drivers/media/usb/dvb-usb-v2/ce6230.c +index 44540de1a2066..d3b5cb4a24daf 100644 +--- a/drivers/media/usb/dvb-usb-v2/ce6230.c ++++ b/drivers/media/usb/dvb-usb-v2/ce6230.c +@@ -101,6 +101,10 @@ static int ce6230_i2c_master_xfer(struct i2c_adapter *adap, + if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { + if (msg[i].addr == + ce6230_zl10353_config.demod_address) { ++ if (msg[i].len < 1) { ++ i = -EOPNOTSUPP; ++ break; ++ } + req.cmd = DEMOD_READ; + req.value = msg[i].addr >> 1; + req.index = msg[i].buf[0]; +@@ -117,6 +121,10 @@ static int ce6230_i2c_master_xfer(struct i2c_adapter *adap, + } else { + if (msg[i].addr == + ce6230_zl10353_config.demod_address) { ++ if (msg[i].len < 1) { ++ i = -EOPNOTSUPP; ++ break; ++ } + req.cmd = DEMOD_WRITE; + req.value = msg[i].addr >> 1; + req.index = msg[i].buf[0]; +-- +2.39.2 + diff --git a/queue-5.4/media-dvb-usb-v2-ec168-fix-null-ptr-deref-in-ec168_i.patch b/queue-5.4/media-dvb-usb-v2-ec168-fix-null-ptr-deref-in-ec168_i.patch new file mode 100644 index 00000000000..88a15bb74ee --- /dev/null +++ b/queue-5.4/media-dvb-usb-v2-ec168-fix-null-ptr-deref-in-ec168_i.patch @@ -0,0 +1,65 @@ +From 03575287c50ddd3f23e040543a6e2521db964935 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Mar 2023 08:58:53 +0000 +Subject: media: dvb-usb-v2: ec168: fix null-ptr-deref in ec168_i2c_xfer() + +From: Wei Chen + +[ Upstream commit a6dcefcc08eca1bf4e3d213c97c3cfb75f377935 ] + +In ec168_i2c_xfer, msg is controlled by user. When msg[i].buf is null +and msg[i].len is zero, former checks on msg[i].buf would be passed. +If accessing msg[i].buf[0] without sanity check, null pointer deref +would happen. We add check on msg[i].len to prevent crash. + +Similar commit: +commit 0ed554fd769a ("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()") + +Link: https://lore.kernel.org/linux-media/20230313085853.3252349-1-harperchen1110@gmail.com +Signed-off-by: Wei Chen +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/usb/dvb-usb-v2/ec168.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/media/usb/dvb-usb-v2/ec168.c b/drivers/media/usb/dvb-usb-v2/ec168.c +index e30305876840f..1191e32407c77 100644 +--- a/drivers/media/usb/dvb-usb-v2/ec168.c ++++ b/drivers/media/usb/dvb-usb-v2/ec168.c +@@ -115,6 +115,10 @@ static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], + while (i < num) { + if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { + if (msg[i].addr == ec168_ec100_config.demod_address) { ++ if (msg[i].len < 1) { ++ i = -EOPNOTSUPP; ++ break; ++ } + req.cmd = READ_DEMOD; + req.value = 0; + req.index = 0xff00 + msg[i].buf[0]; /* reg */ +@@ -131,6 +135,10 @@ static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], + } + } else { + if (msg[i].addr == ec168_ec100_config.demod_address) { ++ if (msg[i].len < 1) { ++ i = -EOPNOTSUPP; ++ break; ++ } + req.cmd = WRITE_DEMOD; + req.value = msg[i].buf[1]; /* val */ + req.index = 0xff00 + msg[i].buf[0]; /* reg */ +@@ -139,6 +147,10 @@ static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], + ret = ec168_ctrl_msg(d, &req); + i += 1; + } else { ++ if (msg[i].len < 1) { ++ i = -EOPNOTSUPP; ++ break; ++ } + req.cmd = WRITE_I2C; + req.value = msg[i].buf[0]; /* val */ + req.index = 0x0100 + msg[i].addr; /* I2C addr */ +-- +2.39.2 + diff --git a/queue-5.4/media-dvb-usb-v2-rtl28xxu-fix-null-ptr-deref-in-rtl2.patch b/queue-5.4/media-dvb-usb-v2-rtl28xxu-fix-null-ptr-deref-in-rtl2.patch new file mode 100644 index 00000000000..62f29758994 --- /dev/null +++ b/queue-5.4/media-dvb-usb-v2-rtl28xxu-fix-null-ptr-deref-in-rtl2.patch @@ -0,0 +1,84 @@ +From 0136302c0d4a23438f50cbd7b027f6716610bbf3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 May 2023 15:52:47 +0100 +Subject: media: dvb-usb-v2: rtl28xxu: fix null-ptr-deref in rtl28xxu_i2c_xfer + +From: Zhang Shurong + +[ Upstream commit aa4a447b81b84f69c1a89ad899df157f386d7636 ] + +In rtl28xxu_i2c_xfer, msg is controlled by user. When msg[i].buf +is null and msg[i].len is zero, former checks on msg[i].buf would be +passed. Malicious data finally reach rtl28xxu_i2c_xfer. If accessing +msg[i].buf[0] without sanity check, null ptr deref would happen. +We add check on msg[i].len to prevent crash. + +Similar commit: +commit 0ed554fd769a +("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()") + +Link: https://lore.kernel.org/linux-media/tencent_3623572106754AC2F266B316798B0F6CCA05@qq.com +Signed-off-by: Zhang Shurong +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +index 0fe71437601e7..ec9bbd8c89ad3 100644 +--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c ++++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +@@ -176,6 +176,10 @@ static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], + ret = -EOPNOTSUPP; + goto err_mutex_unlock; + } else if (msg[0].addr == 0x10) { ++ if (msg[0].len < 1 || msg[1].len < 1) { ++ ret = -EOPNOTSUPP; ++ goto err_mutex_unlock; ++ } + /* method 1 - integrated demod */ + if (msg[0].buf[0] == 0x00) { + /* return demod page from driver cache */ +@@ -189,6 +193,10 @@ static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], + ret = rtl28xxu_ctrl_msg(d, &req); + } + } else if (msg[0].len < 2) { ++ if (msg[0].len < 1) { ++ ret = -EOPNOTSUPP; ++ goto err_mutex_unlock; ++ } + /* method 2 - old I2C */ + req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1); + req.index = CMD_I2C_RD; +@@ -217,8 +225,16 @@ static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], + ret = -EOPNOTSUPP; + goto err_mutex_unlock; + } else if (msg[0].addr == 0x10) { ++ if (msg[0].len < 1) { ++ ret = -EOPNOTSUPP; ++ goto err_mutex_unlock; ++ } + /* method 1 - integrated demod */ + if (msg[0].buf[0] == 0x00) { ++ if (msg[0].len < 2) { ++ ret = -EOPNOTSUPP; ++ goto err_mutex_unlock; ++ } + /* save demod page for later demod access */ + dev->page = msg[0].buf[1]; + ret = 0; +@@ -231,6 +247,10 @@ static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], + ret = rtl28xxu_ctrl_msg(d, &req); + } + } else if ((msg[0].len < 23) && (!dev->new_i2c_write)) { ++ if (msg[0].len < 1) { ++ ret = -EOPNOTSUPP; ++ goto err_mutex_unlock; ++ } + /* method 2 - old I2C */ + req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1); + req.index = CMD_I2C_WR; +-- +2.39.2 + diff --git a/queue-5.4/media-dvb_ca_en50221-fix-a-size-write-bug.patch b/queue-5.4/media-dvb_ca_en50221-fix-a-size-write-bug.patch new file mode 100644 index 00000000000..dda10401f11 --- /dev/null +++ b/queue-5.4/media-dvb_ca_en50221-fix-a-size-write-bug.patch @@ -0,0 +1,118 @@ +From b862662a2374c8c2962d0b9519f9a3858e903aa6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Aug 2022 13:50:27 +0100 +Subject: media: dvb_ca_en50221: fix a size write bug + +From: YongSu Yoo + +[ Upstream commit a4315e5be7020aac9b24a8151caf4bb85224cd0e ] + +The function of "dvb_ca_en50221_write_data" at source/drivers/media +/dvb-core/dvb_ca_en50221.c is used for two cases. +The first case is for writing APDU data in the function of +"dvb_ca_en50221_io_write" at source/drivers/media/dvb-core/ +dvb_ca_en50221.c. +The second case is for writing the host link buf size on the +Command Register in the function of "dvb_ca_en50221_link_init" +at source/drivers/media/dvb-core/dvb_ca_en50221.c. +In the second case, there exists a bug like following. +In the function of the "dvb_ca_en50221_link_init", +after a TV host calculates the host link buf_size, +the TV host writes the calculated host link buf_size on the +Size Register. +Accroding to the en50221 Spec (the page 60 of +https://dvb.org/wp-content/uploads/2020/02/En50221.V1.pdf), +before this writing operation, the "SW(CMDREG_SW)" flag in the +Command Register should be set. We can see this setting operation +in the function of the "dvb_ca_en50221_link_init" like below. +... + if ((ret = ca->pub->write_cam_control(ca->pub, slot, +CTRLIF_COMMAND, IRQEN | CMDREG_SW)) != 0) + return ret; +... +But, after that, the real writing operation is implemented using +the function of the "dvb_ca_en50221_write_data" in the function of +"dvb_ca_en50221_link_init", and the "dvb_ca_en50221_write_data" +includes the function of "ca->pub->write_cam_control", +and the function of the "ca->pub->write_cam_control" in the +function of the "dvb_ca_en50221_wrte_data" does not include +"CMDREG_SW" flag like below. +... + if ((status = ca->pub->write_cam_control(ca->pub, slot, +CTRLIF_COMMAND, IRQEN | CMDREG_HC)) != 0) +... +In the above source code, we can see only the "IRQEN | CMDREG_HC", +but we cannot see the "CMDREG_SW". +The "CMDREG_SW" flag which was set in the function of the +"dvb_ca_en50221_link_init" was rollbacked by the follwoing function +of the "dvb_ca_en50221_write_data". +This is a bug. and this bug causes that the calculated host link buf_size +is not properly written in the CI module. +Through this patch, we fix this bug. + +Link: https://lore.kernel.org/linux-media/20220818125027.1131-1-yongsuyoo0215@gmail.com +Signed-off-by: YongSu Yoo +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/dvb-core/dvb_ca_en50221.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c +index fd476536d32ed..b1a7b5f8b9aa4 100644 +--- a/drivers/media/dvb-core/dvb_ca_en50221.c ++++ b/drivers/media/dvb-core/dvb_ca_en50221.c +@@ -187,7 +187,7 @@ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca); + static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, + u8 *ebuf, int ecount); + static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, +- u8 *ebuf, int ecount); ++ u8 *ebuf, int ecount, int size_write_flag); + + /** + * Safely find needle in haystack. +@@ -370,7 +370,7 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot) + ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_FR, HZ / 10); + if (ret) + return ret; +- ret = dvb_ca_en50221_write_data(ca, slot, buf, 2); ++ ret = dvb_ca_en50221_write_data(ca, slot, buf, 2, CMDREG_SW); + if (ret != 2) + return -EIO; + ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN); +@@ -778,11 +778,13 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, + * @buf: The data in this buffer is treated as a complete link-level packet to + * be written. + * @bytes_write: Size of ebuf. ++ * @size_write_flag: A flag on Command Register which says whether the link size ++ * information will be writen or not. + * + * return: Number of bytes written, or < 0 on error. + */ + static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, +- u8 *buf, int bytes_write) ++ u8 *buf, int bytes_write, int size_write_flag) + { + struct dvb_ca_slot *sl = &ca->slot_info[slot]; + int status; +@@ -817,7 +819,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, + + /* OK, set HC bit */ + status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, +- IRQEN | CMDREG_HC); ++ IRQEN | CMDREG_HC | size_write_flag); + if (status) + goto exit; + +@@ -1505,7 +1507,7 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file, + + mutex_lock(&sl->slot_lock); + status = dvb_ca_en50221_write_data(ca, slot, fragbuf, +- fraglen + 2); ++ fraglen + 2, 0); + mutex_unlock(&sl->slot_lock); + if (status == (fraglen + 2)) { + written = 1; +-- +2.39.2 + diff --git a/queue-5.4/media-dvb_demux-fix-a-bug-for-the-continuity-counter.patch b/queue-5.4/media-dvb_demux-fix-a-bug-for-the-continuity-counter.patch new file mode 100644 index 00000000000..8b8d4ebf9e6 --- /dev/null +++ b/queue-5.4/media-dvb_demux-fix-a-bug-for-the-continuity-counter.patch @@ -0,0 +1,65 @@ +From 4896c45d8cc0ae56b8dfe976e3031d76332ebab3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 5 Mar 2023 21:25:19 +0000 +Subject: media: dvb_demux: fix a bug for the continuity counter + +From: YongSu Yoo + +[ Upstream commit 7efb10d8dc70ea3000cc70dca53407c52488acd1 ] + +In dvb_demux.c, some logics exist which compare the expected +continuity counter and the real continuity counter. If they +are not matched each other, both of the expected continuity +counter and the real continuity counter should be printed. +But there exists a bug that the expected continuity counter +is not correctly printed. The expected continuity counter is +replaced with the real countinuity counter + 1 so that +the epected continuity counter is not correclty printed. +This is wrong. This bug is fixed. + +Link: https://lore.kernel.org/linux-media/20230305212519.499-1-yongsuyoo0215@gmail.com + +Signed-off-by: YongSu Yoo +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/dvb-core/dvb_demux.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c +index 39a2c6ccf31d7..9904a170faeff 100644 +--- a/drivers/media/dvb-core/dvb_demux.c ++++ b/drivers/media/dvb-core/dvb_demux.c +@@ -125,12 +125,12 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed, + + cc = buf[3] & 0x0f; + ccok = ((feed->cc + 1) & 0x0f) == cc; +- feed->cc = cc; + if (!ccok) { + set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); + dprintk_sect_loss("missed packet: %d instead of %d!\n", + cc, (feed->cc + 1) & 0x0f); + } ++ feed->cc = cc; + + if (buf[1] & 0x40) // PUSI ? + feed->peslen = 0xfffa; +@@ -310,7 +310,6 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, + + cc = buf[3] & 0x0f; + ccok = ((feed->cc + 1) & 0x0f) == cc; +- feed->cc = cc; + + if (buf[3] & 0x20) { + /* adaption field present, check for discontinuity_indicator */ +@@ -346,6 +345,7 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, + feed->pusi_seen = false; + dvb_dmx_swfilter_section_new(feed); + } ++ feed->cc = cc; + + if (buf[1] & 0x40) { + /* PUSI=1 (is set), section boundary is here */ +-- +2.39.2 + diff --git a/queue-5.4/media-mn88443x-fix-config_of-error-by-drop-of_match_.patch b/queue-5.4/media-mn88443x-fix-config_of-error-by-drop-of_match_.patch new file mode 100644 index 00000000000..d31ab7d915a --- /dev/null +++ b/queue-5.4/media-mn88443x-fix-config_of-error-by-drop-of_match_.patch @@ -0,0 +1,44 @@ +From eeb5cba032c1cd73889a6c2cb96a5423eaed8b31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Mar 2023 13:13:18 +0000 +Subject: media: mn88443x: fix !CONFIG_OF error by drop of_match_ptr from ID + table +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Krzysztof Kozlowski + +[ Upstream commit ae11c0efaec32fb45130ee9886689f467232eebc ] + +The driver will match mostly by DT table (even thought there is regular +ID table) so there is little benefit in of_match_ptr (this also allows +ACPI matching via PRP0001, even though it might not be relevant here). +This also fixes !CONFIG_OF error: + + drivers/media/dvb-frontends/mn88443x.c:782:34: error: ‘mn88443x_of_match’ defined but not used [-Werror=unused-const-variable=] + +Link: https://lore.kernel.org/linux-media/20230312131318.351173-28-krzysztof.kozlowski@linaro.org +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/dvb-frontends/mn88443x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/dvb-frontends/mn88443x.c b/drivers/media/dvb-frontends/mn88443x.c +index fff212c0bf3b5..05894deb8a19a 100644 +--- a/drivers/media/dvb-frontends/mn88443x.c ++++ b/drivers/media/dvb-frontends/mn88443x.c +@@ -800,7 +800,7 @@ MODULE_DEVICE_TABLE(i2c, mn88443x_i2c_id); + static struct i2c_driver mn88443x_driver = { + .driver = { + .name = "mn88443x", +- .of_match_table = of_match_ptr(mn88443x_of_match), ++ .of_match_table = mn88443x_of_match, + }, + .probe = mn88443x_probe, + .remove = mn88443x_remove, +-- +2.39.2 + diff --git a/queue-5.4/media-netup_unidvb-fix-irq-init-by-register-it-at-th.patch b/queue-5.4/media-netup_unidvb-fix-irq-init-by-register-it-at-th.patch new file mode 100644 index 00000000000..42dfb8013f3 --- /dev/null +++ b/queue-5.4/media-netup_unidvb-fix-irq-init-by-register-it-at-th.patch @@ -0,0 +1,70 @@ +From c55ab02b3258a8ed4ce21ac1dba99e0fa96ada6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Mar 2023 13:45:18 +0000 +Subject: media: netup_unidvb: fix irq init by register it at the end of probe + +From: Wei Chen + +[ Upstream commit e6ad6233592593079db5c8fa592c298e51bc1356 ] + +IRQ handler netup_spi_interrupt() takes spinlock spi->lock. The lock +is initialized in netup_spi_init(). However, irq handler is registered +before initializing the lock. + +Spinlock dma->lock and i2c->lock suffer from the same problem. + +Fix this by registering the irq at the end of probe. + +Link: https://lore.kernel.org/linux-media/20230315134518.1074497-1-harperchen1110@gmail.com +Signed-off-by: Wei Chen +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + .../media/pci/netup_unidvb/netup_unidvb_core.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c +index 129acf595410d..478247e13637e 100644 +--- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c ++++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c +@@ -887,12 +887,7 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev, + ndev->lmmio0, (u32)pci_resource_len(pci_dev, 0), + ndev->lmmio1, (u32)pci_resource_len(pci_dev, 1), + pci_dev->irq); +- if (request_irq(pci_dev->irq, netup_unidvb_isr, IRQF_SHARED, +- "netup_unidvb", pci_dev) < 0) { +- dev_err(&pci_dev->dev, +- "%s(): can't get IRQ %d\n", __func__, pci_dev->irq); +- goto irq_request_err; +- } ++ + ndev->dma_size = 2 * 188 * + NETUP_DMA_BLOCKS_COUNT * NETUP_DMA_PACKETS_COUNT; + ndev->dma_virt = dma_alloc_coherent(&pci_dev->dev, +@@ -933,6 +928,14 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev, + dev_err(&pci_dev->dev, "netup_unidvb: DMA setup failed\n"); + goto dma_setup_err; + } ++ ++ if (request_irq(pci_dev->irq, netup_unidvb_isr, IRQF_SHARED, ++ "netup_unidvb", pci_dev) < 0) { ++ dev_err(&pci_dev->dev, ++ "%s(): can't get IRQ %d\n", __func__, pci_dev->irq); ++ goto dma_setup_err; ++ } ++ + dev_info(&pci_dev->dev, + "netup_unidvb: device has been initialized\n"); + return 0; +@@ -951,8 +954,6 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev, + dma_free_coherent(&pci_dev->dev, ndev->dma_size, + ndev->dma_virt, ndev->dma_phys); + dma_alloc_err: +- free_irq(pci_dev->irq, pci_dev); +-irq_request_err: + iounmap(ndev->lmmio1); + pci_bar1_error: + iounmap(ndev->lmmio0); +-- +2.39.2 + diff --git a/queue-5.4/media-rcar-vin-select-correct-interrupt-mode-for-v4l.patch b/queue-5.4/media-rcar-vin-select-correct-interrupt-mode-for-v4l.patch new file mode 100644 index 00000000000..71ac613c416 --- /dev/null +++ b/queue-5.4/media-rcar-vin-select-correct-interrupt-mode-for-v4l.patch @@ -0,0 +1,44 @@ +From 472da179b43ee4cfed8d10fcf520e5866beec652 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 11 Feb 2023 21:55:34 +0100 +Subject: media: rcar-vin: Select correct interrupt mode for + V4L2_FIELD_ALTERNATE +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Niklas Söderlund + +[ Upstream commit e10707d5865c90d3dfe4ef589ce02ff4287fef85 ] + +When adding proper support for V4L2_FIELD_ALTERNATE it was missed that +this field format should trigger an interrupt for each field, not just +for the whole frame. Fix this by marking it as progressive in the +capture setup, which will then select the correct interrupt mode. + +Tested on both Gen2 and Gen3 with the result of a doubling of the frame +rate for V4L2_FIELD_ALTERNATE. From a PAL video source the frame rate is +now 50, which is expected for alternate field capture. + +Signed-off-by: Niklas Söderlund +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/platform/rcar-vin/rcar-dma.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c +index e5f6360801082..5d6b7aaee2953 100644 +--- a/drivers/media/platform/rcar-vin/rcar-dma.c ++++ b/drivers/media/platform/rcar-vin/rcar-dma.c +@@ -638,6 +638,7 @@ static int rvin_setup(struct rvin_dev *vin) + vnmc = VNMC_IM_FULL | VNMC_FOC; + break; + case V4L2_FIELD_NONE: ++ case V4L2_FIELD_ALTERNATE: + vnmc = VNMC_IM_ODD_EVEN; + progressive = true; + break; +-- +2.39.2 + diff --git a/queue-5.4/media-ttusb-dec-fix-memory-leak-in-ttusb_dec_exit_dv.patch b/queue-5.4/media-ttusb-dec-fix-memory-leak-in-ttusb_dec_exit_dv.patch new file mode 100644 index 00000000000..2641650d0ef --- /dev/null +++ b/queue-5.4/media-ttusb-dec-fix-memory-leak-in-ttusb_dec_exit_dv.patch @@ -0,0 +1,43 @@ +From c03aafff662fdc228b379fb27feb83b1e0ad8305 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 04:59:25 +0000 +Subject: media: ttusb-dec: fix memory leak in ttusb_dec_exit_dvb() + +From: Hyunwoo Kim + +[ Upstream commit 517a281338322ff8293f988771c98aaa7205e457 ] + +Since dvb_frontend_detach() is not called in ttusb_dec_exit_dvb(), +which is called when the device is disconnected, dvb_frontend_free() +is not finally called. + +This causes a memory leak just by repeatedly plugging and +unplugging the device. + +Fix this issue by adding dvb_frontend_detach() to ttusb_dec_exit_dvb(). + +Link: https://lore.kernel.org/linux-media/20221117045925.14297-5-imv4bel@gmail.com +Signed-off-by: Hyunwoo Kim +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/usb/ttusb-dec/ttusb_dec.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c +index 3198f9624b7c0..46bb0ccaafc1f 100644 +--- a/drivers/media/usb/ttusb-dec/ttusb_dec.c ++++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c +@@ -1551,8 +1551,7 @@ static void ttusb_dec_exit_dvb(struct ttusb_dec *dec) + dvb_dmx_release(&dec->demux); + if (dec->fe) { + dvb_unregister_frontend(dec->fe); +- if (dec->fe->ops.release) +- dec->fe->ops.release(dec->fe); ++ dvb_frontend_detach(dec->fe); + } + dvb_unregister_adapter(&dec->adapter); + } +-- +2.39.2 + diff --git a/queue-5.4/mtd-rawnand-ingenic-fix-empty-stub-helper-definition.patch b/queue-5.4/mtd-rawnand-ingenic-fix-empty-stub-helper-definition.patch new file mode 100644 index 00000000000..4ac4e5dcf08 --- /dev/null +++ b/queue-5.4/mtd-rawnand-ingenic-fix-empty-stub-helper-definition.patch @@ -0,0 +1,67 @@ +From 95101443f4ab5eeeb088ef5331ca787851440cc8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 May 2023 22:21:24 +0200 +Subject: mtd: rawnand: ingenic: fix empty stub helper definitions + +From: Arnd Bergmann + +[ Upstream commit 650a8884a364ff2568b51cde9009cfd43cdae6ad ] + +A few functions provide an empty interface definition when +CONFIG_MTD_NAND_INGENIC_ECC is disabled, but they are accidentally +defined as global functions in the header: + +drivers/mtd/nand/raw/ingenic/ingenic_ecc.h:39:5: error: no previous prototype for 'ingenic_ecc_calculate' +drivers/mtd/nand/raw/ingenic/ingenic_ecc.h:46:5: error: no previous prototype for 'ingenic_ecc_correct' +drivers/mtd/nand/raw/ingenic/ingenic_ecc.h:53:6: error: no previous prototype for 'ingenic_ecc_release' +drivers/mtd/nand/raw/ingenic/ingenic_ecc.h:57:21: error: no previous prototype for 'of_ingenic_ecc_get' + +Turn them into 'static inline' definitions instead. + +Fixes: 15de8c6efd0e ("mtd: rawnand: ingenic: Separate top-level and SoC specific code") +Signed-off-by: Arnd Bergmann +Reviewed-by: Paul Cercueil +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20230516202133.559488-1-arnd@kernel.org +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/ingenic/ingenic_ecc.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/mtd/nand/raw/ingenic/ingenic_ecc.h b/drivers/mtd/nand/raw/ingenic/ingenic_ecc.h +index 2cda439b5e11b..017868f59f222 100644 +--- a/drivers/mtd/nand/raw/ingenic/ingenic_ecc.h ++++ b/drivers/mtd/nand/raw/ingenic/ingenic_ecc.h +@@ -36,25 +36,25 @@ int ingenic_ecc_correct(struct ingenic_ecc *ecc, + void ingenic_ecc_release(struct ingenic_ecc *ecc); + struct ingenic_ecc *of_ingenic_ecc_get(struct device_node *np); + #else /* CONFIG_MTD_NAND_INGENIC_ECC */ +-int ingenic_ecc_calculate(struct ingenic_ecc *ecc, ++static inline int ingenic_ecc_calculate(struct ingenic_ecc *ecc, + struct ingenic_ecc_params *params, + const u8 *buf, u8 *ecc_code) + { + return -ENODEV; + } + +-int ingenic_ecc_correct(struct ingenic_ecc *ecc, ++static inline int ingenic_ecc_correct(struct ingenic_ecc *ecc, + struct ingenic_ecc_params *params, u8 *buf, + u8 *ecc_code) + { + return -ENODEV; + } + +-void ingenic_ecc_release(struct ingenic_ecc *ecc) ++static inline void ingenic_ecc_release(struct ingenic_ecc *ecc) + { + } + +-struct ingenic_ecc *of_ingenic_ecc_get(struct device_node *np) ++static inline struct ingenic_ecc *of_ingenic_ecc_get(struct device_node *np) + { + return ERR_PTR(-ENODEV); + } +-- +2.39.2 + diff --git a/queue-5.4/mtd-rawnand-marvell-don-t-set-the-nand-frequency-sel.patch b/queue-5.4/mtd-rawnand-marvell-don-t-set-the-nand-frequency-sel.patch new file mode 100644 index 00000000000..9e3545121c2 --- /dev/null +++ b/queue-5.4/mtd-rawnand-marvell-don-t-set-the-nand-frequency-sel.patch @@ -0,0 +1,44 @@ +From d21d2e7dbda7dac5442d76a5327d2b1815fb1fb6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 May 2023 12:31:53 +1200 +Subject: mtd: rawnand: marvell: don't set the NAND frequency select + +From: Chris Packham + +[ Upstream commit c4d28e30a8d0b979e4029465ab8f312ab6ce2644 ] + +marvell_nfc_setup_interface() uses the frequency retrieved from the +clock associated with the nand interface to determine the timings that +will be used. By changing the NAND frequency select without reflecting +this in the clock configuration this means that the timings calculated +don't correctly meet the requirements of the NAND chip. This hasn't been +an issue up to now because of a different bug that was stopping the +timings being updated after they were initially set. + +Fixes: b25251414f6e ("mtd: rawnand: marvell: Stop implementing ->select_chip()") +Signed-off-by: Chris Packham +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20230525003154.2303012-2-chris.packham@alliedtelesis.co.nz +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/marvell_nand.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c +index 7ab9e9920c06e..c49a3e105b427 100644 +--- a/drivers/mtd/nand/raw/marvell_nand.c ++++ b/drivers/mtd/nand/raw/marvell_nand.c +@@ -2834,10 +2834,6 @@ static int marvell_nfc_init(struct marvell_nfc *nfc) + regmap_update_bits(sysctrl_base, GENCONF_CLK_GATING_CTRL, + GENCONF_CLK_GATING_CTRL_ND_GATE, + GENCONF_CLK_GATING_CTRL_ND_GATE); +- +- regmap_update_bits(sysctrl_base, GENCONF_ND_CLK_CTRL, +- GENCONF_ND_CLK_CTRL_EN, +- GENCONF_ND_CLK_CTRL_EN); + } + + /* Configure the DMA if appropriate */ +-- +2.39.2 + diff --git a/queue-5.4/mtd-rawnand-marvell-ensure-timing-values-are-written.patch b/queue-5.4/mtd-rawnand-marvell-ensure-timing-values-are-written.patch new file mode 100644 index 00000000000..854e7110783 --- /dev/null +++ b/queue-5.4/mtd-rawnand-marvell-ensure-timing-values-are-written.patch @@ -0,0 +1,43 @@ +From 1c68b7eddde836e994fd6fd3195177d44c116702 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 May 2023 12:31:52 +1200 +Subject: mtd: rawnand: marvell: ensure timing values are written + +From: Chris Packham + +[ Upstream commit 8a6f4d346f3bad9c68b4a87701eb3f7978542d57 ] + +When new timing values are calculated in marvell_nfc_setup_interface() +ensure that they will be applied in marvell_nfc_select_target() by +clearing the selected_chip pointer. + +Fixes: b25251414f6e ("mtd: rawnand: marvell: Stop implementing ->select_chip()") +Suggested-by: Miquel Raynal +Signed-off-by: Chris Packham +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20230525003154.2303012-1-chris.packham@alliedtelesis.co.nz +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/marvell_nand.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c +index 36cb0db02bbb0..7ab9e9920c06e 100644 +--- a/drivers/mtd/nand/raw/marvell_nand.c ++++ b/drivers/mtd/nand/raw/marvell_nand.c +@@ -2401,6 +2401,12 @@ static int marvell_nfc_setup_data_interface(struct nand_chip *chip, int chipnr, + NDTR1_WAIT_MODE; + } + ++ /* ++ * Reset nfc->selected_chip so the next command will cause the timing ++ * registers to be updated in marvell_nfc_select_target(). ++ */ ++ nfc->selected_chip = NULL; ++ + return 0; + } + +-- +2.39.2 + diff --git a/queue-5.4/nbd-fix-debugfs_create_dir-error-checking.patch b/queue-5.4/nbd-fix-debugfs_create_dir-error-checking.patch new file mode 100644 index 00000000000..32edb406e99 --- /dev/null +++ b/queue-5.4/nbd-fix-debugfs_create_dir-error-checking.patch @@ -0,0 +1,46 @@ +From ef124d37f43f597853942a65c719cbe1f59f330e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 May 2023 17:05:32 +0400 +Subject: nbd: Fix debugfs_create_dir error checking + +From: Ivan Orlov + +[ Upstream commit 4913cfcf014c95f0437db2df1734472fd3e15098 ] + +The debugfs_create_dir function returns ERR_PTR in case of error, and the +only correct way to check if an error occurred is 'IS_ERR' inline function. +This patch will replace the null-comparison with IS_ERR. + +Signed-off-by: Ivan Orlov +Link: https://lore.kernel.org/r/20230512130533.98709-1-ivan.orlov0322@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 610dc6a36a9de..218aa7e419700 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -1609,7 +1609,7 @@ static int nbd_dev_dbg_init(struct nbd_device *nbd) + return -EIO; + + dir = debugfs_create_dir(nbd_name(nbd), nbd_dbg_dir); +- if (!dir) { ++ if (IS_ERR(dir)) { + dev_err(nbd_to_dev(nbd), "Failed to create debugfs dir for '%s'\n", + nbd_name(nbd)); + return -EIO; +@@ -1635,7 +1635,7 @@ static int nbd_dbg_init(void) + struct dentry *dbg_dir; + + dbg_dir = debugfs_create_dir("nbd", NULL); +- if (!dbg_dir) ++ if (IS_ERR(dbg_dir)) + return -EIO; + + nbd_dbg_dir = dbg_dir; +-- +2.39.2 + diff --git a/queue-5.4/net-dsa-mv88e6xxx-increase-wait-after-reset-deactiva.patch b/queue-5.4/net-dsa-mv88e6xxx-increase-wait-after-reset-deactiva.patch new file mode 100644 index 00000000000..d805962ef7f --- /dev/null +++ b/queue-5.4/net-dsa-mv88e6xxx-increase-wait-after-reset-deactiva.patch @@ -0,0 +1,45 @@ +From 5dd614a24ba3be55634eb3ba67e102c9148b2585 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 May 2023 16:52:23 +0200 +Subject: net: dsa: mv88e6xxx: Increase wait after reset deactivation + +From: Andreas Svensson + +[ Upstream commit 3c27f3d53d588618d81d30d6712459a3cc9489b8 ] + +A switch held in reset by default needs to wait longer until we can +reliably detect it. + +An issue was observed when testing on the Marvell 88E6393X (Link Street). +The driver failed to detect the switch on some upstarts. Increasing the +wait time after reset deactivation solves this issue. + +The updated wait time is now also the same as the wait time in the +mv88e6xxx_hardware_reset function. + +Fixes: 7b75e49de424 ("net: dsa: mv88e6xxx: wait after reset deactivation") +Signed-off-by: Andreas Svensson +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/20230530145223.1223993-1-andreas.svensson@axis.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/mv88e6xxx/chip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c +index 3a8a49b7ec3d9..393ee145ae066 100644 +--- a/drivers/net/dsa/mv88e6xxx/chip.c ++++ b/drivers/net/dsa/mv88e6xxx/chip.c +@@ -5096,7 +5096,7 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev) + goto out; + } + if (chip->reset) +- usleep_range(1000, 2000); ++ usleep_range(10000, 20000); + + err = mv88e6xxx_detect(chip); + if (err) +-- +2.39.2 + diff --git a/queue-5.4/net-mlx5-fw_tracer-fix-event-handling.patch b/queue-5.4/net-mlx5-fw_tracer-fix-event-handling.patch new file mode 100644 index 00000000000..6660b432fe1 --- /dev/null +++ b/queue-5.4/net-mlx5-fw_tracer-fix-event-handling.patch @@ -0,0 +1,40 @@ +From 542072dbf6db1d351584adc0615ae77a8e548598 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 29 Apr 2023 20:41:41 +0300 +Subject: net/mlx5: fw_tracer, Fix event handling + +From: Shay Drory + +[ Upstream commit 341a80de2468f481b1f771683709b5649cbfe513 ] + +mlx5 driver needs to parse traces with event_id inside the range of +first_string_trace and num_string_trace. However, mlx5 is parsing all +events with event_id >= first_string_trace. + +Fix it by checking for the correct range. + +Fixes: c71ad41ccb0c ("net/mlx5: FW tracer, events handling") +Signed-off-by: Shay Drory +Reviewed-by: Moshe Shemesh +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +index fcf5fef7c195d..58d48d76c1b8a 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +@@ -480,7 +480,7 @@ static void poll_trace(struct mlx5_fw_tracer *tracer, + (u64)timestamp_low; + break; + default: +- if (tracer_event->event_id >= tracer->str_db.first_string_trace || ++ if (tracer_event->event_id >= tracer->str_db.first_string_trace && + tracer_event->event_id <= tracer->str_db.first_string_trace + + tracer->str_db.num_string_trace) { + tracer_event->type = TRACER_EVENT_TYPE_STRING; +-- +2.39.2 + diff --git a/queue-5.4/net-netlink-fix-netlink_list_memberships-length-repo.patch b/queue-5.4/net-netlink-fix-netlink_list_memberships-length-repo.patch new file mode 100644 index 00000000000..68567582ea2 --- /dev/null +++ b/queue-5.4/net-netlink-fix-netlink_list_memberships-length-repo.patch @@ -0,0 +1,40 @@ +From a72a3831af62e45acccd229e9b4cf99bfebfdc9f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 May 2023 12:33:35 -0300 +Subject: net/netlink: fix NETLINK_LIST_MEMBERSHIPS length report + +From: Pedro Tammela + +[ Upstream commit f4e4534850a9d18c250a93f8d7fbb51310828110 ] + +The current code for the length calculation wrongly truncates the reported +length of the groups array, causing an under report of the subscribed +groups. To fix this, use 'BITS_TO_BYTES()' which rounds up the +division by 8. + +Fixes: b42be38b2778 ("netlink: add API to retrieve all group memberships") +Signed-off-by: Pedro Tammela +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/20230529153335.389815-1-pctammela@mojatatu.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/netlink/af_netlink.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 31a3a562854fc..bf7e300e8c25d 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1780,7 +1780,7 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname, + break; + } + } +- if (put_user(ALIGN(nlk->ngroups / 8, sizeof(u32)), optlen)) ++ if (put_user(ALIGN(BITS_TO_BYTES(nlk->ngroups), sizeof(u32)), optlen)) + err = -EFAULT; + netlink_unlock_table(); + return err; +-- +2.39.2 + diff --git a/queue-5.4/net-sched-fix-null-pointer-dereference-in-mq_attach.patch b/queue-5.4/net-sched-fix-null-pointer-dereference-in-mq_attach.patch new file mode 100644 index 00000000000..80a14056051 --- /dev/null +++ b/queue-5.4/net-sched-fix-null-pointer-dereference-in-mq_attach.patch @@ -0,0 +1,93 @@ +From e0e13eddd2d9d2d087ea5d8ff445e16c16cff901 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 27 May 2023 17:37:47 +0800 +Subject: net: sched: fix NULL pointer dereference in mq_attach + +From: Zhengchao Shao + +[ Upstream commit 36eec020fab668719b541f34d97f44e232ffa165 ] + +When use the following command to test: +1)ip link add bond0 type bond +2)ip link set bond0 up +3)tc qdisc add dev bond0 root handle ffff: mq +4)tc qdisc replace dev bond0 parent ffff:fff1 handle ffff: mq + +The kernel reports NULL pointer dereference issue. The stack information +is as follows: +Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 +Internal error: Oops: 0000000096000006 [#1] SMP +Modules linked in: +pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) +pc : mq_attach+0x44/0xa0 +lr : qdisc_graft+0x20c/0x5cc +sp : ffff80000e2236a0 +x29: ffff80000e2236a0 x28: ffff0000c0e59d80 x27: ffff0000c0be19c0 +x26: ffff0000cae3e800 x25: 0000000000000010 x24: 00000000fffffff1 +x23: 0000000000000000 x22: ffff0000cae3e800 x21: ffff0000c9df4000 +x20: ffff0000c9df4000 x19: 0000000000000000 x18: ffff80000a934000 +x17: ffff8000f5b56000 x16: ffff80000bb08000 x15: 0000000000000000 +x14: 0000000000000000 x13: 6b6b6b6b6b6b6b6b x12: 6b6b6b6b00000001 +x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000 +x8 : ffff0000c0be0730 x7 : bbbbbbbbbbbbbbbb x6 : 0000000000000008 +x5 : ffff0000cae3e864 x4 : 0000000000000000 x3 : 0000000000000001 +x2 : 0000000000000001 x1 : ffff8000090bc23c x0 : 0000000000000000 +Call trace: +mq_attach+0x44/0xa0 +qdisc_graft+0x20c/0x5cc +tc_modify_qdisc+0x1c4/0x664 +rtnetlink_rcv_msg+0x354/0x440 +netlink_rcv_skb+0x64/0x144 +rtnetlink_rcv+0x28/0x34 +netlink_unicast+0x1e8/0x2a4 +netlink_sendmsg+0x308/0x4a0 +sock_sendmsg+0x64/0xac +____sys_sendmsg+0x29c/0x358 +___sys_sendmsg+0x90/0xd0 +__sys_sendmsg+0x7c/0xd0 +__arm64_sys_sendmsg+0x2c/0x38 +invoke_syscall+0x54/0x114 +el0_svc_common.constprop.1+0x90/0x174 +do_el0_svc+0x3c/0xb0 +el0_svc+0x24/0xec +el0t_64_sync_handler+0x90/0xb4 +el0t_64_sync+0x174/0x178 + +This is because when mq is added for the first time, qdiscs in mq is set +to NULL in mq_attach(). Therefore, when replacing mq after adding mq, we +need to initialize qdiscs in the mq before continuing to graft. Otherwise, +it will couse NULL pointer dereference issue in mq_attach(). And the same +issue will occur in the attach functions of mqprio, taprio and htb. +ffff:fff1 means that the repalce qdisc is ingress. Ingress does not allow +any qdisc to be attached. Therefore, ffff:fff1 is incorrectly used, and +the command should be dropped. + +Fixes: 6ec1c69a8f64 ("net_sched: add classful multiqueue dummy scheduler") +Signed-off-by: Zhengchao Shao +Tested-by: Peilin Ye +Acked-by: Jamal Hadi Salim +Link: https://lore.kernel.org/r/20230527093747.3583502-1-shaozhengchao@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_api.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c +index 84d371d30d444..6ca0cba8aad16 100644 +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -1589,6 +1589,10 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, + NL_SET_ERR_MSG(extack, "Qdisc parent/child loop detected"); + return -ELOOP; + } ++ if (clid == TC_H_INGRESS) { ++ NL_SET_ERR_MSG(extack, "Ingress cannot graft directly"); ++ return -EINVAL; ++ } + qdisc_refcount_inc(q); + goto graft; + } else { +-- +2.39.2 + diff --git a/queue-5.4/net-sched-flower-fix-possible-oob-write-in-fl_set_ge.patch b/queue-5.4/net-sched-flower-fix-possible-oob-write-in-fl_set_ge.patch new file mode 100644 index 00000000000..7f77f82f4fe --- /dev/null +++ b/queue-5.4/net-sched-flower-fix-possible-oob-write-in-fl_set_ge.patch @@ -0,0 +1,43 @@ +From b8a31ef16d196375750f1d09bf90580a1f00ea0f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 May 2023 18:28:04 +0800 +Subject: net/sched: flower: fix possible OOB write in fl_set_geneve_opt() + +From: Hangyu Hua + +[ Upstream commit 4d56304e5827c8cc8cc18c75343d283af7c4825c ] + +If we send two TCA_FLOWER_KEY_ENC_OPTS_GENEVE packets and their total +size is 252 bytes(key->enc_opts.len = 252) then +key->enc_opts.len = opt->length = data_len / 4 = 0 when the third +TCA_FLOWER_KEY_ENC_OPTS_GENEVE packet enters fl_set_geneve_opt. This +bypasses the next bounds check and results in an out-of-bounds. + +Fixes: 0a6e77784f49 ("net/sched: allow flower to match tunnel options") +Signed-off-by: Hangyu Hua +Reviewed-by: Simon Horman +Reviewed-by: Pieter Jansen van Vuuren +Link: https://lore.kernel.org/r/20230531102805.27090-1-hbh25y@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/sched/cls_flower.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c +index 007fbc1993522..63f53aa8460a2 100644 +--- a/net/sched/cls_flower.c ++++ b/net/sched/cls_flower.c +@@ -870,6 +870,9 @@ static int fl_set_geneve_opt(const struct nlattr *nla, struct fl_flow_key *key, + if (option_len > sizeof(struct geneve_opt)) + data_len = option_len - sizeof(struct geneve_opt); + ++ if (key->enc_opts.len > FLOW_DIS_TUN_OPTS_MAX - 4) ++ return -ERANGE; ++ + opt = (struct geneve_opt *)&key->enc_opts.data[key->enc_opts.len]; + memset(opt, 0xff, option_len); + opt->length = data_len / 4; +-- +2.39.2 + diff --git a/queue-5.4/net-sched-prohibit-regrafting-ingress-or-clsact-qdis.patch b/queue-5.4/net-sched-prohibit-regrafting-ingress-or-clsact-qdis.patch new file mode 100644 index 00000000000..dd725d5b256 --- /dev/null +++ b/queue-5.4/net-sched-prohibit-regrafting-ingress-or-clsact-qdis.patch @@ -0,0 +1,60 @@ +From 57267ab8b1a0c196c0444d03e8d40196e03d825c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 May 2023 12:54:26 -0700 +Subject: net/sched: Prohibit regrafting ingress or clsact Qdiscs + +From: Peilin Ye + +[ Upstream commit 9de95df5d15baa956c2b70b9e794842e790a8a13 ] + +Currently, after creating an ingress (or clsact) Qdisc and grafting it +under TC_H_INGRESS (TC_H_CLSACT), it is possible to graft it again under +e.g. a TBF Qdisc: + + $ ip link add ifb0 type ifb + $ tc qdisc add dev ifb0 handle 1: root tbf rate 20kbit buffer 1600 limit 3000 + $ tc qdisc add dev ifb0 clsact + $ tc qdisc link dev ifb0 handle ffff: parent 1:1 + $ tc qdisc show dev ifb0 + qdisc tbf 1: root refcnt 2 rate 20Kbit burst 1600b lat 560.0ms + qdisc clsact ffff: parent ffff:fff1 refcnt 2 + ^^^^^^^^ + +clsact's refcount has increased: it is now grafted under both +TC_H_CLSACT and 1:1. + +ingress and clsact Qdiscs should only be used under TC_H_INGRESS +(TC_H_CLSACT). Prohibit regrafting them. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Fixes: 1f211a1b929c ("net, sched: add clsact qdisc") +Tested-by: Pedro Tammela +Acked-by: Jamal Hadi Salim +Reviewed-by: Jamal Hadi Salim +Reviewed-by: Vlad Buslov +Signed-off-by: Peilin Ye +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_api.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c +index cd6af51bd9ff2..84d371d30d444 100644 +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -1579,6 +1579,11 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, + NL_SET_ERR_MSG(extack, "Invalid qdisc name"); + return -EINVAL; + } ++ if (q->flags & TCQ_F_INGRESS) { ++ NL_SET_ERR_MSG(extack, ++ "Cannot regraft ingress or clsact Qdiscs"); ++ return -EINVAL; ++ } + if (q == p || + (p && check_loop(q, p, 0))) { + NL_SET_ERR_MSG(extack, "Qdisc parent/child loop detected"); +-- +2.39.2 + diff --git a/queue-5.4/net-sched-reserve-tc_h_ingress-tc_h_clsact-for-ingre.patch b/queue-5.4/net-sched-reserve-tc_h_ingress-tc_h_clsact-for-ingre.patch new file mode 100644 index 00000000000..ec69e5bf638 --- /dev/null +++ b/queue-5.4/net-sched-reserve-tc_h_ingress-tc_h_clsact-for-ingre.patch @@ -0,0 +1,87 @@ +From 9a2921b9225d6c6d8a2021f9640ca0f449d4929f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 May 2023 12:54:03 -0700 +Subject: net/sched: Reserve TC_H_INGRESS (TC_H_CLSACT) for ingress (clsact) + Qdiscs + +From: Peilin Ye + +[ Upstream commit f85fa45d4a9408d98c46c8fa45ba2e3b2f4bf219 ] + +Currently it is possible to add e.g. an HTB Qdisc under ffff:fff1 +(TC_H_INGRESS, TC_H_CLSACT): + + $ ip link add name ifb0 type ifb + $ tc qdisc add dev ifb0 parent ffff:fff1 htb + $ tc qdisc add dev ifb0 clsact + Error: Exclusivity flag on, cannot modify. + $ drgn + ... + >>> ifb0 = netdev_get_by_name(prog, "ifb0") + >>> qdisc = ifb0.ingress_queue.qdisc_sleeping + >>> print(qdisc.ops.id.string_().decode()) + htb + >>> qdisc.flags.value_() # TCQ_F_INGRESS + 2 + +Only allow ingress and clsact Qdiscs under ffff:fff1. Return -EINVAL +for everything else. Make TCQ_F_INGRESS a static flag of ingress and +clsact Qdiscs. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Fixes: 1f211a1b929c ("net, sched: add clsact qdisc") +Tested-by: Pedro Tammela +Acked-by: Jamal Hadi Salim +Reviewed-by: Jamal Hadi Salim +Reviewed-by: Vlad Buslov +Signed-off-by: Peilin Ye +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_api.c | 7 ++++++- + net/sched/sch_ingress.c | 4 ++-- + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c +index 67d6bc97e5fe9..cd6af51bd9ff2 100644 +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -1214,7 +1214,12 @@ static struct Qdisc *qdisc_create(struct net_device *dev, + sch->parent = parent; + + if (handle == TC_H_INGRESS) { +- sch->flags |= TCQ_F_INGRESS; ++ if (!(sch->flags & TCQ_F_INGRESS)) { ++ NL_SET_ERR_MSG(extack, ++ "Specified parent ID is reserved for ingress and clsact Qdiscs"); ++ err = -EINVAL; ++ goto err_out3; ++ } + handle = TC_H_MAKE(TC_H_INGRESS, 0); + } else { + if (handle == 0) { +diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c +index 9f1ed810b7b89..28168799ca1b8 100644 +--- a/net/sched/sch_ingress.c ++++ b/net/sched/sch_ingress.c +@@ -133,7 +133,7 @@ static struct Qdisc_ops ingress_qdisc_ops __read_mostly = { + .cl_ops = &ingress_class_ops, + .id = "ingress", + .priv_size = sizeof(struct ingress_sched_data), +- .static_flags = TCQ_F_CPUSTATS, ++ .static_flags = TCQ_F_INGRESS | TCQ_F_CPUSTATS, + .init = ingress_init, + .destroy = ingress_destroy, + .dump = ingress_dump, +@@ -272,7 +272,7 @@ static struct Qdisc_ops clsact_qdisc_ops __read_mostly = { + .cl_ops = &clsact_class_ops, + .id = "clsact", + .priv_size = sizeof(struct clsact_sched_data), +- .static_flags = TCQ_F_CPUSTATS, ++ .static_flags = TCQ_F_INGRESS | TCQ_F_CPUSTATS, + .init = clsact_init, + .destroy = clsact_destroy, + .dump = ingress_dump, +-- +2.39.2 + diff --git a/queue-5.4/net-sched-sch_clsact-only-create-under-tc_h_clsact.patch b/queue-5.4/net-sched-sch_clsact-only-create-under-tc_h_clsact.patch new file mode 100644 index 00000000000..dec537936a2 --- /dev/null +++ b/queue-5.4/net-sched-sch_clsact-only-create-under-tc_h_clsact.patch @@ -0,0 +1,52 @@ +From 4ab7b0a73dce583ea10ba7e2b12c0f75ba330a5d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 May 2023 12:53:21 -0700 +Subject: net/sched: sch_clsact: Only create under TC_H_CLSACT + +From: Peilin Ye + +[ Upstream commit 5eeebfe6c493192b10d516abfd72742900f2a162 ] + +clsact Qdiscs are only supposed to be created under TC_H_CLSACT (which +equals TC_H_INGRESS). Return -EOPNOTSUPP if 'parent' is not +TC_H_CLSACT. + +Fixes: 1f211a1b929c ("net, sched: add clsact qdisc") +Tested-by: Pedro Tammela +Acked-by: Jamal Hadi Salim +Reviewed-by: Jamal Hadi Salim +Reviewed-by: Vlad Buslov +Signed-off-by: Peilin Ye +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_ingress.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c +index d5358c033d247..9f1ed810b7b89 100644 +--- a/net/sched/sch_ingress.c ++++ b/net/sched/sch_ingress.c +@@ -218,6 +218,9 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt, + struct net_device *dev = qdisc_dev(sch); + int err; + ++ if (sch->parent != TC_H_CLSACT) ++ return -EOPNOTSUPP; ++ + net_inc_ingress_queue(); + net_inc_egress_queue(); + +@@ -245,6 +248,9 @@ static void clsact_destroy(struct Qdisc *sch) + { + struct clsact_sched_data *q = qdisc_priv(sch); + ++ if (sch->parent != TC_H_CLSACT) ++ return; ++ + tcf_block_put_ext(q->egress_block, sch, &q->egress_block_info); + tcf_block_put_ext(q->ingress_block, sch, &q->ingress_block_info); + +-- +2.39.2 + diff --git a/queue-5.4/net-sched-sch_ingress-only-create-under-tc_h_ingress.patch b/queue-5.4/net-sched-sch_ingress-only-create-under-tc_h_ingress.patch new file mode 100644 index 00000000000..5fe91017876 --- /dev/null +++ b/queue-5.4/net-sched-sch_ingress-only-create-under-tc_h_ingress.patch @@ -0,0 +1,54 @@ +From df0a2384a3639c0575fd6088bc2b997d43fd514a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 May 2023 12:52:55 -0700 +Subject: net/sched: sch_ingress: Only create under TC_H_INGRESS + +From: Peilin Ye + +[ Upstream commit c7cfbd115001f94de9e4053657946a383147e803 ] + +ingress Qdiscs are only supposed to be created under TC_H_INGRESS. +Return -EOPNOTSUPP if 'parent' is not TC_H_INGRESS, similar to +mq_init(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot+b53a9c0d1ea4ad62da8b@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/r/0000000000006cf87705f79acf1a@google.com/ +Tested-by: Pedro Tammela +Acked-by: Jamal Hadi Salim +Reviewed-by: Jamal Hadi Salim +Reviewed-by: Vlad Buslov +Signed-off-by: Peilin Ye +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_ingress.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c +index bf56aa5197974..d5358c033d247 100644 +--- a/net/sched/sch_ingress.c ++++ b/net/sched/sch_ingress.c +@@ -79,6 +79,9 @@ static int ingress_init(struct Qdisc *sch, struct nlattr *opt, + struct ingress_sched_data *q = qdisc_priv(sch); + struct net_device *dev = qdisc_dev(sch); + ++ if (sch->parent != TC_H_INGRESS) ++ return -EOPNOTSUPP; ++ + net_inc_ingress_queue(); + + mini_qdisc_pair_init(&q->miniqp, sch, &dev->miniq_ingress); +@@ -94,6 +97,9 @@ static void ingress_destroy(struct Qdisc *sch) + { + struct ingress_sched_data *q = qdisc_priv(sch); + ++ if (sch->parent != TC_H_INGRESS) ++ return; ++ + tcf_block_put_ext(q->block, sch, &q->block_info); + net_dec_ingress_queue(); + } +-- +2.39.2 + diff --git a/queue-5.4/netfilter-conntrack-define-variables-exp_nat_nla_pol.patch b/queue-5.4/netfilter-conntrack-define-variables-exp_nat_nla_pol.patch new file mode 100644 index 00000000000..2f7d8888c9d --- /dev/null +++ b/queue-5.4/netfilter-conntrack-define-variables-exp_nat_nla_pol.patch @@ -0,0 +1,63 @@ +From 6c94d9f97e02548f6afb509e1d7b48be23a78fcf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 May 2023 10:00:10 -0400 +Subject: netfilter: conntrack: define variables exp_nat_nla_policy and + any_addr with CONFIG_NF_NAT +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Tom Rix + +[ Upstream commit 224a876e37543eee111bf9b6aa4935080e619335 ] + +gcc with W=1 and ! CONFIG_NF_NAT +net/netfilter/nf_conntrack_netlink.c:3463:32: error: + ‘exp_nat_nla_policy’ defined but not used [-Werror=unused-const-variable=] + 3463 | static const struct nla_policy exp_nat_nla_policy[CTA_EXPECT_NAT_MAX+1] = { + | ^~~~~~~~~~~~~~~~~~ +net/netfilter/nf_conntrack_netlink.c:2979:33: error: + ‘any_addr’ defined but not used [-Werror=unused-const-variable=] + 2979 | static const union nf_inet_addr any_addr; + | ^~~~~~~~ + +These variables use is controlled by CONFIG_NF_NAT, so should their definitions. + +Signed-off-by: Tom Rix +Reviewed-by: Simon Horman +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conntrack_netlink.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c +index 754f473ce3de4..4328d10ad1bc3 100644 +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -2704,7 +2704,9 @@ static int ctnetlink_exp_dump_mask(struct sk_buff *skb, + return -1; + } + ++#if IS_ENABLED(CONFIG_NF_NAT) + static const union nf_inet_addr any_addr; ++#endif + + static __be32 nf_expect_get_id(const struct nf_conntrack_expect *exp) + { +@@ -3204,10 +3206,12 @@ ctnetlink_change_expect(struct nf_conntrack_expect *x, + return 0; + } + ++#if IS_ENABLED(CONFIG_NF_NAT) + static const struct nla_policy exp_nat_nla_policy[CTA_EXPECT_NAT_MAX+1] = { + [CTA_EXPECT_NAT_DIR] = { .type = NLA_U32 }, + [CTA_EXPECT_NAT_TUPLE] = { .type = NLA_NESTED }, + }; ++#endif + + static int + ctnetlink_parse_expect_nat(const struct nlattr *attr, +-- +2.39.2 + diff --git a/queue-5.4/netrom-fix-info-leak-in-nr_write_internal.patch b/queue-5.4/netrom-fix-info-leak-in-nr_write_internal.patch new file mode 100644 index 00000000000..bbe775c0d9f --- /dev/null +++ b/queue-5.4/netrom-fix-info-leak-in-nr_write_internal.patch @@ -0,0 +1,85 @@ +From 789646abd96da9a73d3a92a8eb3cd30f86497a21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 May 2023 14:14:56 +0000 +Subject: netrom: fix info-leak in nr_write_internal() + +From: Eric Dumazet + +[ Upstream commit 31642e7089df8fd3f54ca7843f7ee2952978cad1 ] + +Simon Kapadia reported the following issue: + + + +The Online Amateur Radio Community (OARC) has recently been experimenting +with building a nationwide packet network in the UK. +As part of our experimentation, we have been testing out packet on 300bps HF, +and playing with net/rom. For HF packet at this baud rate you really need +to make sure that your MTU is relatively low; AX.25 suggests a PACLEN of 60, +and a net/rom PACLEN of 40 to go with that. +However the Linux net/rom support didn't work with a low PACLEN; +the mkiss module would truncate packets if you set the PACLEN below about 200 or so, e.g.: + +Apr 19 14:00:51 radio kernel: [12985.747310] mkiss: ax1: truncating oversized transmit packet! + +This didn't make any sense to me (if the packets are smaller why would they +be truncated?) so I started investigating. +I looked at the packets using ethereal, and found that many were just huge +compared to what I would expect. +A simple net/rom connection request packet had the request and then a bunch +of what appeared to be random data following it: + + + +Simon provided a patch that I slightly revised: +Not only we must not use skb_tailroom(), we also do +not want to count NR_NETWORK_LEN twice. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Co-Developed-by: Simon Kapadia +Signed-off-by: Simon Kapadia +Signed-off-by: Eric Dumazet +Tested-by: Simon Kapadia +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/20230524141456.1045467-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/netrom/nr_subr.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/net/netrom/nr_subr.c b/net/netrom/nr_subr.c +index 3f99b432ea707..e2d2af924cff4 100644 +--- a/net/netrom/nr_subr.c ++++ b/net/netrom/nr_subr.c +@@ -123,7 +123,7 @@ void nr_write_internal(struct sock *sk, int frametype) + unsigned char *dptr; + int len, timeout; + +- len = NR_NETWORK_LEN + NR_TRANSPORT_LEN; ++ len = NR_TRANSPORT_LEN; + + switch (frametype & 0x0F) { + case NR_CONNREQ: +@@ -141,7 +141,8 @@ void nr_write_internal(struct sock *sk, int frametype) + return; + } + +- if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL) ++ skb = alloc_skb(NR_NETWORK_LEN + len, GFP_ATOMIC); ++ if (!skb) + return; + + /* +@@ -149,7 +150,7 @@ void nr_write_internal(struct sock *sk, int frametype) + */ + skb_reserve(skb, NR_NETWORK_LEN); + +- dptr = skb_put(skb, skb_tailroom(skb)); ++ dptr = skb_put(skb, len); + + switch (frametype & 0x0F) { + case NR_CONNREQ: +-- +2.39.2 + diff --git a/queue-5.4/ocfs2-dlm-move-bits_to_bytes-to-bitops.h-for-wider-u.patch b/queue-5.4/ocfs2-dlm-move-bits_to_bytes-to-bitops.h-for-wider-u.patch new file mode 100644 index 00000000000..bb20d4db281 --- /dev/null +++ b/queue-5.4/ocfs2-dlm-move-bits_to_bytes-to-bitops.h-for-wider-u.patch @@ -0,0 +1,90 @@ +From 9a7931de9c19c01f35ddd67fae4b80781ba8a641 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Jan 2020 22:11:47 -0800 +Subject: ocfs2/dlm: move BITS_TO_BYTES() to bitops.h for wider use + +From: Andy Shevchenko + +[ Upstream commit dd3e7cba16274831f5a69f071ed3cf13ffb352ea ] + +There are users already and will be more of BITS_TO_BYTES() macro. Move +it to bitops.h for wider use. + +In the case of ocfs2 the replacement is identical. + +As for bnx2x, there are two places where floor version is used. In the +first case to calculate the amount of structures that can fit one memory +page. In this case obviously the ceiling variant is correct and +original code might have a potential bug, if amount of bits % 8 is not +0. In the second case the macro is used to calculate bytes transmitted +in one microsecond. This will work for all speeds which is multiply of +1Gbps without any change, for the rest new code will give ceiling value, +for instance 100Mbps will give 13 bytes, while old code gives 12 bytes +and the arithmetically correct one is 12.5 bytes. Further the value is +used to setup timer threshold which in any case has its own margins due +to certain resolution. I don't see here an issue with slightly shifting +thresholds for low speed connections, the card is supposed to utilize +highest available rate, which is usually 10Gbps. + +Link: http://lkml.kernel.org/r/20200108121316.22411-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Andy Shevchenko +Reviewed-by: Joseph Qi +Acked-by: Sudarsana Reddy Kalluru +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Gang He +Cc: Jun Piao +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Stable-dep-of: f4e4534850a9 ("net/netlink: fix NETLINK_LIST_MEMBERSHIPS length report") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h | 1 - + fs/ocfs2/dlm/dlmcommon.h | 4 ---- + include/linux/bitops.h | 1 + + 3 files changed, 1 insertion(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h +index 066765fbef069..0a59a09ef82f4 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h +@@ -296,7 +296,6 @@ static inline void bnx2x_dcb_config_qm(struct bnx2x *bp, enum cos_mode mode, + * possible, the driver should only write the valid vnics into the internal + * ram according to the appropriate port mode. + */ +-#define BITS_TO_BYTES(x) ((x)/8) + + /* CMNG constants, as derived from system spec calculations */ + +diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h +index aaf24548b02a1..0463dce65bb22 100644 +--- a/fs/ocfs2/dlm/dlmcommon.h ++++ b/fs/ocfs2/dlm/dlmcommon.h +@@ -688,10 +688,6 @@ struct dlm_begin_reco + __be32 pad2; + }; + +- +-#define BITS_PER_BYTE 8 +-#define BITS_TO_BYTES(bits) (((bits)+BITS_PER_BYTE-1)/BITS_PER_BYTE) +- + struct dlm_query_join_request + { + u8 node_idx; +diff --git a/include/linux/bitops.h b/include/linux/bitops.h +index 4f0e62cbf2ffe..e9e74af163fab 100644 +--- a/include/linux/bitops.h ++++ b/include/linux/bitops.h +@@ -13,6 +13,7 @@ + + #define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE) + #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(long)) ++#define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(char)) + + extern unsigned int __sw_hweight8(unsigned int w); + extern unsigned int __sw_hweight16(unsigned int w); +-- +2.39.2 + diff --git a/queue-5.4/rdma-bnxt_re-enable-sriov-vf-support-on-broadcom-s-5.patch b/queue-5.4/rdma-bnxt_re-enable-sriov-vf-support-on-broadcom-s-5.patch new file mode 100644 index 00000000000..2f9732f2024 --- /dev/null +++ b/queue-5.4/rdma-bnxt_re-enable-sriov-vf-support-on-broadcom-s-5.patch @@ -0,0 +1,244 @@ +From 970e6fc31cf477f69c62d759451fc88324ea6c18 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Oct 2019 01:48:35 -0400 +Subject: RDMA/bnxt_re: Enable SRIOV VF support on Broadcom's 57500 adapter + series + +From: Devesh Sharma + +[ Upstream commit 39c48c514601d76f8750d1739928c9577b1785d9 ] + +Broadcom's 575xx adapter series has support for SRIOV VFs. Making changes +to enable SRIOV VF support. There are two major area where changes are +done: + + - Added new DB location for control-path and data-path DB ring + + - New devices do not need to issue the sriov-config slow-path command + thus, skipping to call that firmware command. + +For now enabling support for 64 RoCE VFs. + +Link: https://lore.kernel.org/r/1570081715-14301-1-git-send-email-devesh.sharma@broadcom.com +Signed-off-by: Devesh Sharma +Signed-off-by: Jason Gunthorpe +Stable-dep-of: 349e3c0cf239 ("RDMA/bnxt_re: Fix a possible memory leak") +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/bnxt_re.h | 1 + + drivers/infiniband/hw/bnxt_re/main.c | 133 ++++++++++++--------- + drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 5 +- + 3 files changed, 82 insertions(+), 57 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h +index e55a1666c0cd6..725b2350e3498 100644 +--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h ++++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h +@@ -108,6 +108,7 @@ struct bnxt_re_sqp_entries { + #define BNXT_RE_MAX_MSIX 9 + #define BNXT_RE_AEQ_IDX 0 + #define BNXT_RE_NQ_IDX 1 ++#define BNXT_RE_GEN_P5_MAX_VF 64 + + struct bnxt_re_dev { + struct ib_device ibdev; +diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c +index cfe5f47d9890e..41fc05d531183 100644 +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -119,61 +119,76 @@ static void bnxt_re_get_sriov_func_type(struct bnxt_re_dev *rdev) + * reserved for the function. The driver may choose to allocate fewer + * resources than the firmware maximum. + */ +-static void bnxt_re_set_resource_limits(struct bnxt_re_dev *rdev) ++static void bnxt_re_limit_pf_res(struct bnxt_re_dev *rdev) + { +- u32 vf_qps = 0, vf_srqs = 0, vf_cqs = 0, vf_mrws = 0, vf_gids = 0; +- u32 i; +- u32 vf_pct; +- u32 num_vfs; +- struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr; ++ struct bnxt_qplib_dev_attr *attr; ++ struct bnxt_qplib_ctx *ctx; ++ int i; + +- rdev->qplib_ctx.qpc_count = min_t(u32, BNXT_RE_MAX_QPC_COUNT, +- dev_attr->max_qp); ++ attr = &rdev->dev_attr; ++ ctx = &rdev->qplib_ctx; + +- rdev->qplib_ctx.mrw_count = BNXT_RE_MAX_MRW_COUNT_256K; ++ ctx->qpc_count = min_t(u32, BNXT_RE_MAX_QPC_COUNT, ++ attr->max_qp); ++ ctx->mrw_count = BNXT_RE_MAX_MRW_COUNT_256K; + /* Use max_mr from fw since max_mrw does not get set */ +- rdev->qplib_ctx.mrw_count = min_t(u32, rdev->qplib_ctx.mrw_count, +- dev_attr->max_mr); +- rdev->qplib_ctx.srqc_count = min_t(u32, BNXT_RE_MAX_SRQC_COUNT, +- dev_attr->max_srq); +- rdev->qplib_ctx.cq_count = min_t(u32, BNXT_RE_MAX_CQ_COUNT, +- dev_attr->max_cq); +- +- for (i = 0; i < MAX_TQM_ALLOC_REQ; i++) +- rdev->qplib_ctx.tqm_count[i] = +- rdev->dev_attr.tqm_alloc_reqs[i]; +- +- if (rdev->num_vfs) { +- /* +- * Reserve a set of resources for the PF. Divide the remaining +- * resources among the VFs +- */ +- vf_pct = 100 - BNXT_RE_PCT_RSVD_FOR_PF; +- num_vfs = 100 * rdev->num_vfs; +- vf_qps = (rdev->qplib_ctx.qpc_count * vf_pct) / num_vfs; +- vf_srqs = (rdev->qplib_ctx.srqc_count * vf_pct) / num_vfs; +- vf_cqs = (rdev->qplib_ctx.cq_count * vf_pct) / num_vfs; +- /* +- * The driver allows many more MRs than other resources. If the +- * firmware does also, then reserve a fixed amount for the PF +- * and divide the rest among VFs. VFs may use many MRs for NFS +- * mounts, ISER, NVME applications, etc. If the firmware +- * severely restricts the number of MRs, then let PF have +- * half and divide the rest among VFs, as for the other +- * resource types. +- */ +- if (rdev->qplib_ctx.mrw_count < BNXT_RE_MAX_MRW_COUNT_64K) +- vf_mrws = rdev->qplib_ctx.mrw_count * vf_pct / num_vfs; +- else +- vf_mrws = (rdev->qplib_ctx.mrw_count - +- BNXT_RE_RESVD_MR_FOR_PF) / rdev->num_vfs; +- vf_gids = BNXT_RE_MAX_GID_PER_VF; ++ ctx->mrw_count = min_t(u32, ctx->mrw_count, attr->max_mr); ++ ctx->srqc_count = min_t(u32, BNXT_RE_MAX_SRQC_COUNT, ++ attr->max_srq); ++ ctx->cq_count = min_t(u32, BNXT_RE_MAX_CQ_COUNT, attr->max_cq); ++ if (!bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx)) ++ for (i = 0; i < MAX_TQM_ALLOC_REQ; i++) ++ rdev->qplib_ctx.tqm_count[i] = ++ rdev->dev_attr.tqm_alloc_reqs[i]; ++} ++ ++static void bnxt_re_limit_vf_res(struct bnxt_qplib_ctx *qplib_ctx, u32 num_vf) ++{ ++ struct bnxt_qplib_vf_res *vf_res; ++ u32 mrws = 0; ++ u32 vf_pct; ++ u32 nvfs; ++ ++ vf_res = &qplib_ctx->vf_res; ++ /* ++ * Reserve a set of resources for the PF. Divide the remaining ++ * resources among the VFs ++ */ ++ vf_pct = 100 - BNXT_RE_PCT_RSVD_FOR_PF; ++ nvfs = num_vf; ++ num_vf = 100 * num_vf; ++ vf_res->max_qp_per_vf = (qplib_ctx->qpc_count * vf_pct) / num_vf; ++ vf_res->max_srq_per_vf = (qplib_ctx->srqc_count * vf_pct) / num_vf; ++ vf_res->max_cq_per_vf = (qplib_ctx->cq_count * vf_pct) / num_vf; ++ /* ++ * The driver allows many more MRs than other resources. If the ++ * firmware does also, then reserve a fixed amount for the PF and ++ * divide the rest among VFs. VFs may use many MRs for NFS ++ * mounts, ISER, NVME applications, etc. If the firmware severely ++ * restricts the number of MRs, then let PF have half and divide ++ * the rest among VFs, as for the other resource types. ++ */ ++ if (qplib_ctx->mrw_count < BNXT_RE_MAX_MRW_COUNT_64K) { ++ mrws = qplib_ctx->mrw_count * vf_pct; ++ nvfs = num_vf; ++ } else { ++ mrws = qplib_ctx->mrw_count - BNXT_RE_RESVD_MR_FOR_PF; + } +- rdev->qplib_ctx.vf_res.max_mrw_per_vf = vf_mrws; +- rdev->qplib_ctx.vf_res.max_gid_per_vf = vf_gids; +- rdev->qplib_ctx.vf_res.max_qp_per_vf = vf_qps; +- rdev->qplib_ctx.vf_res.max_srq_per_vf = vf_srqs; +- rdev->qplib_ctx.vf_res.max_cq_per_vf = vf_cqs; ++ vf_res->max_mrw_per_vf = (mrws / nvfs); ++ vf_res->max_gid_per_vf = BNXT_RE_MAX_GID_PER_VF; ++} ++ ++static void bnxt_re_set_resource_limits(struct bnxt_re_dev *rdev) ++{ ++ u32 num_vfs; ++ ++ memset(&rdev->qplib_ctx.vf_res, 0, sizeof(struct bnxt_qplib_vf_res)); ++ bnxt_re_limit_pf_res(rdev); ++ ++ num_vfs = bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx) ? ++ BNXT_RE_GEN_P5_MAX_VF : rdev->num_vfs; ++ if (num_vfs) ++ bnxt_re_limit_vf_res(&rdev->qplib_ctx, num_vfs); + } + + /* for handling bnxt_en callbacks later */ +@@ -193,9 +208,11 @@ static void bnxt_re_sriov_config(void *p, int num_vfs) + return; + + rdev->num_vfs = num_vfs; +- bnxt_re_set_resource_limits(rdev); +- bnxt_qplib_set_func_resources(&rdev->qplib_res, &rdev->rcfw, +- &rdev->qplib_ctx); ++ if (!bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx)) { ++ bnxt_re_set_resource_limits(rdev); ++ bnxt_qplib_set_func_resources(&rdev->qplib_res, &rdev->rcfw, ++ &rdev->qplib_ctx); ++ } + } + + static void bnxt_re_shutdown(void *p) +@@ -897,10 +914,14 @@ static int bnxt_re_cqn_handler(struct bnxt_qplib_nq *nq, + return 0; + } + ++#define BNXT_RE_GEN_P5_PF_NQ_DB 0x10000 ++#define BNXT_RE_GEN_P5_VF_NQ_DB 0x4000 + static u32 bnxt_re_get_nqdb_offset(struct bnxt_re_dev *rdev, u16 indx) + { + return bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx) ? +- 0x10000 : rdev->msix_entries[indx].db_offset; ++ (rdev->is_virtfn ? BNXT_RE_GEN_P5_VF_NQ_DB : ++ BNXT_RE_GEN_P5_PF_NQ_DB) : ++ rdev->msix_entries[indx].db_offset; + } + + static void bnxt_re_cleanup_res(struct bnxt_re_dev *rdev) +@@ -1410,8 +1431,8 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev) + rdev->is_virtfn); + if (rc) + goto disable_rcfw; +- if (!rdev->is_virtfn) +- bnxt_re_set_resource_limits(rdev); ++ ++ bnxt_re_set_resource_limits(rdev); + + rc = bnxt_qplib_alloc_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx, 0, + bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx)); +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +index 60c8f76aab33d..5cdfa84faf85e 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +@@ -494,8 +494,10 @@ int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw, + * shall setup this area for VF. Skipping the + * HW programming + */ +- if (is_virtfn || bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx)) ++ if (is_virtfn) + goto skip_ctx_setup; ++ if (bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx)) ++ goto config_vf_res; + + level = ctx->qpc_tbl.level; + req.qpc_pg_size_qpc_lvl = (level << CMDQ_INITIALIZE_FW_QPC_LVL_SFT) | +@@ -540,6 +542,7 @@ int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw, + req.number_of_srq = cpu_to_le32(ctx->srqc_tbl.max_elements); + req.number_of_cq = cpu_to_le32(ctx->cq_tbl.max_elements); + ++config_vf_res: + req.max_qp_per_vf = cpu_to_le32(ctx->vf_res.max_qp_per_vf); + req.max_mrw_per_vf = cpu_to_le32(ctx->vf_res.max_mrw_per_vf); + req.max_srq_per_vf = cpu_to_le32(ctx->vf_res.max_srq_per_vf); +-- +2.39.2 + diff --git a/queue-5.4/rdma-bnxt_re-fix-return-value-of-bnxt_re_process_raw.patch b/queue-5.4/rdma-bnxt_re-fix-return-value-of-bnxt_re_process_raw.patch new file mode 100644 index 00000000000..eaa365b8213 --- /dev/null +++ b/queue-5.4/rdma-bnxt_re-fix-return-value-of-bnxt_re_process_raw.patch @@ -0,0 +1,42 @@ +From ce0b7139a447e47f18a5c13950e196388eae3bda Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 May 2023 01:11:00 -0700 +Subject: RDMA/bnxt_re: Fix return value of bnxt_re_process_raw_qp_pkt_rx + +From: Kalesh AP + +[ Upstream commit 0fa0d520e2a878cb4c94c4dc84395905d3f14f54 ] + +bnxt_re_process_raw_qp_pkt_rx() always return 0 and ignores the return +value of bnxt_re_post_send_shadow_qp(). + +Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") +Link: https://lore.kernel.org/r/1684397461-23082-3-git-send-email-selvin.xavier@broadcom.com +Reviewed-by: Hongguang Gao +Reviewed-by: Ajit Khaparde +Signed-off-by: Kalesh AP +Signed-off-by: Selvin Xavier +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +index e3e1ea0c7666a..f0e96639850eb 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -3165,9 +3165,7 @@ static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *gsi_qp, + udwr.remote_qkey = gsi_sqp->qplib_qp.qkey; + + /* post data received in the send queue */ +- rc = bnxt_re_post_send_shadow_qp(rdev, gsi_sqp, swr); +- +- return 0; ++ return bnxt_re_post_send_shadow_qp(rdev, gsi_sqp, swr); + } + + static void bnxt_re_process_res_rawqp1_wc(struct ib_wc *wc, +-- +2.39.2 + diff --git a/queue-5.4/rdma-bnxt_re-refactor-queue-pair-creation-code.patch b/queue-5.4/rdma-bnxt_re-refactor-queue-pair-creation-code.patch new file mode 100644 index 00000000000..443830bec38 --- /dev/null +++ b/queue-5.4/rdma-bnxt_re-refactor-queue-pair-creation-code.patch @@ -0,0 +1,936 @@ +From ebc2f5884983b6e039bd7b2c46e82a687c1b3a98 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Feb 2020 12:10:58 -0500 +Subject: RDMA/bnxt_re: Refactor queue pair creation code + +From: Devesh Sharma + +[ Upstream commit 8dae419f9ec730c1984ea7395067a2534780ada1 ] + +Restructuring the bnxt_re_create_qp function. Listing below the major +changes: + - Monolithic central part of create_qp where attributes are initialized + is now enclosed in one function and this new function has few more + sub-functions. + - Top level qp limit checking code moved to a function. + - GSI QP creation and GSI Shadow qp creation code is handled in a sub + function. + +Link: https://lore.kernel.org/r/1581786665-23705-2-git-send-email-devesh.sharma@broadcom.com +Signed-off-by: Naresh Kumar PBS +Signed-off-by: Selvin Xavier +Signed-off-by: Devesh Sharma +Signed-off-by: Jason Gunthorpe +Stable-dep-of: 349e3c0cf239 ("RDMA/bnxt_re: Fix a possible memory leak") +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/bnxt_re.h | 13 +- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 629 +++++++++++++++-------- + drivers/infiniband/hw/bnxt_re/main.c | 3 +- + 3 files changed, 428 insertions(+), 217 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h +index 725b2350e3498..c2805384e832f 100644 +--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h ++++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h +@@ -104,6 +104,14 @@ struct bnxt_re_sqp_entries { + struct bnxt_re_qp *qp1_qp; + }; + ++#define BNXT_RE_MAX_GSI_SQP_ENTRIES 1024 ++struct bnxt_re_gsi_context { ++ struct bnxt_re_qp *gsi_qp; ++ struct bnxt_re_qp *gsi_sqp; ++ struct bnxt_re_ah *gsi_sah; ++ struct bnxt_re_sqp_entries *sqp_tbl; ++}; ++ + #define BNXT_RE_MIN_MSIX 2 + #define BNXT_RE_MAX_MSIX 9 + #define BNXT_RE_AEQ_IDX 0 +@@ -165,10 +173,7 @@ struct bnxt_re_dev { + u16 cosq[2]; + + /* QP for for handling QP1 packets */ +- u32 sqp_id; +- struct bnxt_re_qp *qp1_sqp; +- struct bnxt_re_ah *sqp_ah; +- struct bnxt_re_sqp_entries sqp_tbl[1024]; ++ struct bnxt_re_gsi_context gsi_ctx; + atomic_t nq_alloc_cnt; + u32 is_virtfn; + u32 num_vfs; +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +index dd006b177b544..e3e1ea0c7666a 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -330,7 +330,7 @@ int bnxt_re_del_gid(const struct ib_gid_attr *attr, void **context) + */ + if (ctx->idx == 0 && + rdma_link_local_addr((struct in6_addr *)gid_to_del) && +- ctx->refcnt == 1 && rdev->qp1_sqp) { ++ ctx->refcnt == 1 && rdev->gsi_ctx.gsi_sqp) { + dev_dbg(rdev_to_dev(rdev), + "Trying to delete GID0 while QP1 is alive\n"); + return -EFAULT; +@@ -760,6 +760,49 @@ void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, + spin_unlock_irqrestore(&qp->scq->cq_lock, flags); + } + ++static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp) ++{ ++ struct bnxt_re_qp *gsi_sqp; ++ struct bnxt_re_ah *gsi_sah; ++ struct bnxt_re_dev *rdev; ++ int rc = 0; ++ ++ rdev = qp->rdev; ++ gsi_sqp = rdev->gsi_ctx.gsi_sqp; ++ gsi_sah = rdev->gsi_ctx.gsi_sah; ++ ++ /* remove from active qp list */ ++ mutex_lock(&rdev->qp_lock); ++ list_del(&gsi_sqp->list); ++ mutex_unlock(&rdev->qp_lock); ++ atomic_dec(&rdev->qp_count); ++ ++ dev_dbg(rdev_to_dev(rdev), "Destroy the shadow AH\n"); ++ bnxt_qplib_destroy_ah(&rdev->qplib_res, ++ &gsi_sah->qplib_ah, ++ true); ++ bnxt_qplib_clean_qp(&qp->qplib_qp); ++ ++ dev_dbg(rdev_to_dev(rdev), "Destroy the shadow QP\n"); ++ rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &gsi_sqp->qplib_qp); ++ if (rc) { ++ dev_err(rdev_to_dev(rdev), "Destroy Shadow QP failed"); ++ goto fail; ++ } ++ bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp); ++ ++ kfree(rdev->gsi_ctx.sqp_tbl); ++ kfree(gsi_sah); ++ kfree(gsi_sqp); ++ rdev->gsi_ctx.gsi_sqp = NULL; ++ rdev->gsi_ctx.gsi_sah = NULL; ++ rdev->gsi_ctx.sqp_tbl = NULL; ++ ++ return 0; ++fail: ++ return rc; ++} ++ + /* Queue Pairs */ + int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata) + { +@@ -768,7 +811,13 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata) + unsigned int flags; + int rc; + ++ mutex_lock(&rdev->qp_lock); ++ list_del(&qp->list); ++ mutex_unlock(&rdev->qp_lock); ++ atomic_dec(&rdev->qp_count); ++ + bnxt_qplib_flush_cqn_wq(&qp->qplib_qp); ++ + rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp); + if (rc) { + dev_err(rdev_to_dev(rdev), "Failed to destroy HW QP"); +@@ -783,40 +832,19 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata) + + bnxt_qplib_free_qp_res(&rdev->qplib_res, &qp->qplib_qp); + +- if (ib_qp->qp_type == IB_QPT_GSI && rdev->qp1_sqp) { +- bnxt_qplib_destroy_ah(&rdev->qplib_res, &rdev->sqp_ah->qplib_ah, +- false); +- +- bnxt_qplib_clean_qp(&qp->qplib_qp); +- rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, +- &rdev->qp1_sqp->qplib_qp); +- if (rc) { +- dev_err(rdev_to_dev(rdev), +- "Failed to destroy Shadow QP"); +- return rc; +- } +- bnxt_qplib_free_qp_res(&rdev->qplib_res, +- &rdev->qp1_sqp->qplib_qp); +- mutex_lock(&rdev->qp_lock); +- list_del(&rdev->qp1_sqp->list); +- atomic_dec(&rdev->qp_count); +- mutex_unlock(&rdev->qp_lock); +- +- kfree(rdev->sqp_ah); +- kfree(rdev->qp1_sqp); +- rdev->qp1_sqp = NULL; +- rdev->sqp_ah = NULL; ++ if (ib_qp->qp_type == IB_QPT_GSI && rdev->gsi_ctx.gsi_sqp) { ++ rc = bnxt_re_destroy_gsi_sqp(qp); ++ if (rc) ++ goto sh_fail; + } + + ib_umem_release(qp->rumem); + ib_umem_release(qp->sumem); + +- mutex_lock(&rdev->qp_lock); +- list_del(&qp->list); +- atomic_dec(&rdev->qp_count); +- mutex_unlock(&rdev->qp_lock); + kfree(qp); + return 0; ++sh_fail: ++ return rc; + } + + static u8 __from_ib_qp_type(enum ib_qp_type type) +@@ -984,8 +1012,6 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp + if (rc) + goto fail; + +- rdev->sqp_id = qp->qplib_qp.id; +- + spin_lock_init(&qp->sq_lock); + INIT_LIST_HEAD(&qp->list); + mutex_lock(&rdev->qp_lock); +@@ -998,205 +1024,377 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp + return NULL; + } + +-struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, +- struct ib_qp_init_attr *qp_init_attr, +- struct ib_udata *udata) ++static int bnxt_re_init_rq_attr(struct bnxt_re_qp *qp, ++ struct ib_qp_init_attr *init_attr) + { +- struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd); +- struct bnxt_re_dev *rdev = pd->rdev; +- struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr; +- struct bnxt_re_qp *qp; +- struct bnxt_re_cq *cq; +- struct bnxt_re_srq *srq; +- int rc, entries; ++ struct bnxt_qplib_dev_attr *dev_attr; ++ struct bnxt_qplib_qp *qplqp; ++ struct bnxt_re_dev *rdev; ++ int entries; + +- if ((qp_init_attr->cap.max_send_wr > dev_attr->max_qp_wqes) || +- (qp_init_attr->cap.max_recv_wr > dev_attr->max_qp_wqes) || +- (qp_init_attr->cap.max_send_sge > dev_attr->max_qp_sges) || +- (qp_init_attr->cap.max_recv_sge > dev_attr->max_qp_sges) || +- (qp_init_attr->cap.max_inline_data > dev_attr->max_inline_data)) +- return ERR_PTR(-EINVAL); ++ rdev = qp->rdev; ++ qplqp = &qp->qplib_qp; ++ dev_attr = &rdev->dev_attr; + +- qp = kzalloc(sizeof(*qp), GFP_KERNEL); +- if (!qp) +- return ERR_PTR(-ENOMEM); ++ if (init_attr->srq) { ++ struct bnxt_re_srq *srq; + +- qp->rdev = rdev; +- ether_addr_copy(qp->qplib_qp.smac, rdev->netdev->dev_addr); +- qp->qplib_qp.pd = &pd->qplib_pd; +- qp->qplib_qp.qp_handle = (u64)(unsigned long)(&qp->qplib_qp); +- qp->qplib_qp.type = __from_ib_qp_type(qp_init_attr->qp_type); ++ srq = container_of(init_attr->srq, struct bnxt_re_srq, ib_srq); ++ if (!srq) { ++ dev_err(rdev_to_dev(rdev), "SRQ not found"); ++ return -EINVAL; ++ } ++ qplqp->srq = &srq->qplib_srq; ++ qplqp->rq.max_wqe = 0; ++ } else { ++ /* Allocate 1 more than what's provided so posting max doesn't ++ * mean empty. ++ */ ++ entries = roundup_pow_of_two(init_attr->cap.max_recv_wr + 1); ++ qplqp->rq.max_wqe = min_t(u32, entries, ++ dev_attr->max_qp_wqes + 1); + +- if (qp_init_attr->qp_type == IB_QPT_GSI && +- bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx)) +- qp->qplib_qp.type = CMDQ_CREATE_QP_TYPE_GSI; +- if (qp->qplib_qp.type == IB_QPT_MAX) { ++ qplqp->rq.q_full_delta = qplqp->rq.max_wqe - ++ init_attr->cap.max_recv_wr; ++ qplqp->rq.max_sge = init_attr->cap.max_recv_sge; ++ if (qplqp->rq.max_sge > dev_attr->max_qp_sges) ++ qplqp->rq.max_sge = dev_attr->max_qp_sges; ++ } ++ ++ return 0; ++} ++ ++static void bnxt_re_adjust_gsi_rq_attr(struct bnxt_re_qp *qp) ++{ ++ struct bnxt_qplib_dev_attr *dev_attr; ++ struct bnxt_qplib_qp *qplqp; ++ struct bnxt_re_dev *rdev; ++ ++ rdev = qp->rdev; ++ qplqp = &qp->qplib_qp; ++ dev_attr = &rdev->dev_attr; ++ ++ qplqp->rq.max_sge = dev_attr->max_qp_sges; ++ if (qplqp->rq.max_sge > dev_attr->max_qp_sges) ++ qplqp->rq.max_sge = dev_attr->max_qp_sges; ++} ++ ++static void bnxt_re_init_sq_attr(struct bnxt_re_qp *qp, ++ struct ib_qp_init_attr *init_attr, ++ struct ib_udata *udata) ++{ ++ struct bnxt_qplib_dev_attr *dev_attr; ++ struct bnxt_qplib_qp *qplqp; ++ struct bnxt_re_dev *rdev; ++ int entries; ++ ++ rdev = qp->rdev; ++ qplqp = &qp->qplib_qp; ++ dev_attr = &rdev->dev_attr; ++ ++ qplqp->sq.max_sge = init_attr->cap.max_send_sge; ++ if (qplqp->sq.max_sge > dev_attr->max_qp_sges) ++ qplqp->sq.max_sge = dev_attr->max_qp_sges; ++ /* ++ * Change the SQ depth if user has requested minimum using ++ * configfs. Only supported for kernel consumers ++ */ ++ entries = init_attr->cap.max_send_wr; ++ /* Allocate 128 + 1 more than what's provided */ ++ entries = roundup_pow_of_two(entries + BNXT_QPLIB_RESERVED_QP_WRS + 1); ++ qplqp->sq.max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + ++ BNXT_QPLIB_RESERVED_QP_WRS + 1); ++ qplqp->sq.q_full_delta = BNXT_QPLIB_RESERVED_QP_WRS + 1; ++ /* ++ * Reserving one slot for Phantom WQE. Application can ++ * post one extra entry in this case. But allowing this to avoid ++ * unexpected Queue full condition ++ */ ++ qplqp->sq.q_full_delta -= 1; ++} ++ ++static void bnxt_re_adjust_gsi_sq_attr(struct bnxt_re_qp *qp, ++ struct ib_qp_init_attr *init_attr) ++{ ++ struct bnxt_qplib_dev_attr *dev_attr; ++ struct bnxt_qplib_qp *qplqp; ++ struct bnxt_re_dev *rdev; ++ int entries; ++ ++ rdev = qp->rdev; ++ qplqp = &qp->qplib_qp; ++ dev_attr = &rdev->dev_attr; ++ ++ entries = roundup_pow_of_two(init_attr->cap.max_send_wr + 1); ++ qplqp->sq.max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + 1); ++ qplqp->sq.q_full_delta = qplqp->sq.max_wqe - ++ init_attr->cap.max_send_wr; ++ qplqp->sq.max_sge++; /* Need one extra sge to put UD header */ ++ if (qplqp->sq.max_sge > dev_attr->max_qp_sges) ++ qplqp->sq.max_sge = dev_attr->max_qp_sges; ++} ++ ++static int bnxt_re_init_qp_type(struct bnxt_re_dev *rdev, ++ struct ib_qp_init_attr *init_attr) ++{ ++ struct bnxt_qplib_chip_ctx *chip_ctx; ++ int qptype; ++ ++ chip_ctx = &rdev->chip_ctx; ++ ++ qptype = __from_ib_qp_type(init_attr->qp_type); ++ if (qptype == IB_QPT_MAX) { + dev_err(rdev_to_dev(rdev), "QP type 0x%x not supported", +- qp->qplib_qp.type); +- rc = -EINVAL; +- goto fail; ++ qptype); ++ qptype = -EINVAL; ++ goto out; + } + +- qp->qplib_qp.max_inline_data = qp_init_attr->cap.max_inline_data; +- qp->qplib_qp.sig_type = ((qp_init_attr->sq_sig_type == +- IB_SIGNAL_ALL_WR) ? true : false); ++ if (bnxt_qplib_is_chip_gen_p5(chip_ctx) && ++ init_attr->qp_type == IB_QPT_GSI) ++ qptype = CMDQ_CREATE_QP_TYPE_GSI; ++out: ++ return qptype; ++} + +- qp->qplib_qp.sq.max_sge = qp_init_attr->cap.max_send_sge; +- if (qp->qplib_qp.sq.max_sge > dev_attr->max_qp_sges) +- qp->qplib_qp.sq.max_sge = dev_attr->max_qp_sges; ++static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd, ++ struct ib_qp_init_attr *init_attr, ++ struct ib_udata *udata) ++{ ++ struct bnxt_qplib_dev_attr *dev_attr; ++ struct bnxt_qplib_qp *qplqp; ++ struct bnxt_re_dev *rdev; ++ struct bnxt_re_cq *cq; ++ int rc = 0, qptype; ++ ++ rdev = qp->rdev; ++ qplqp = &qp->qplib_qp; ++ dev_attr = &rdev->dev_attr; ++ ++ /* Setup misc params */ ++ ether_addr_copy(qplqp->smac, rdev->netdev->dev_addr); ++ qplqp->pd = &pd->qplib_pd; ++ qplqp->qp_handle = (u64)qplqp; ++ qplqp->max_inline_data = init_attr->cap.max_inline_data; ++ qplqp->sig_type = ((init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) ? ++ true : false); ++ qptype = bnxt_re_init_qp_type(rdev, init_attr); ++ if (qptype < 0) { ++ rc = qptype; ++ goto out; ++ } ++ qplqp->type = (u8)qptype; ++ ++ if (init_attr->qp_type == IB_QPT_RC) { ++ qplqp->max_rd_atomic = dev_attr->max_qp_rd_atom; ++ qplqp->max_dest_rd_atomic = dev_attr->max_qp_init_rd_atom; ++ } ++ qplqp->mtu = ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu)); ++ qplqp->dpi = &rdev->dpi_privileged; /* Doorbell page */ ++ if (init_attr->create_flags) ++ dev_dbg(rdev_to_dev(rdev), ++ "QP create flags 0x%x not supported", ++ init_attr->create_flags); + +- if (qp_init_attr->send_cq) { +- cq = container_of(qp_init_attr->send_cq, struct bnxt_re_cq, +- ib_cq); ++ /* Setup CQs */ ++ if (init_attr->send_cq) { ++ cq = container_of(init_attr->send_cq, struct bnxt_re_cq, ib_cq); + if (!cq) { + dev_err(rdev_to_dev(rdev), "Send CQ not found"); + rc = -EINVAL; +- goto fail; ++ goto out; + } +- qp->qplib_qp.scq = &cq->qplib_cq; ++ qplqp->scq = &cq->qplib_cq; + qp->scq = cq; + } + +- if (qp_init_attr->recv_cq) { +- cq = container_of(qp_init_attr->recv_cq, struct bnxt_re_cq, +- ib_cq); ++ if (init_attr->recv_cq) { ++ cq = container_of(init_attr->recv_cq, struct bnxt_re_cq, ib_cq); + if (!cq) { + dev_err(rdev_to_dev(rdev), "Receive CQ not found"); + rc = -EINVAL; +- goto fail; ++ goto out; + } +- qp->qplib_qp.rcq = &cq->qplib_cq; ++ qplqp->rcq = &cq->qplib_cq; + qp->rcq = cq; + } + +- if (qp_init_attr->srq) { +- srq = container_of(qp_init_attr->srq, struct bnxt_re_srq, +- ib_srq); +- if (!srq) { +- dev_err(rdev_to_dev(rdev), "SRQ not found"); +- rc = -EINVAL; +- goto fail; +- } +- qp->qplib_qp.srq = &srq->qplib_srq; +- qp->qplib_qp.rq.max_wqe = 0; +- } else { +- /* Allocate 1 more than what's provided so posting max doesn't +- * mean empty +- */ +- entries = roundup_pow_of_two(qp_init_attr->cap.max_recv_wr + 1); +- qp->qplib_qp.rq.max_wqe = min_t(u32, entries, +- dev_attr->max_qp_wqes + 1); ++ /* Setup RQ/SRQ */ ++ rc = bnxt_re_init_rq_attr(qp, init_attr); ++ if (rc) ++ goto out; ++ if (init_attr->qp_type == IB_QPT_GSI) ++ bnxt_re_adjust_gsi_rq_attr(qp); ++ ++ /* Setup SQ */ ++ bnxt_re_init_sq_attr(qp, init_attr, udata); ++ if (init_attr->qp_type == IB_QPT_GSI) ++ bnxt_re_adjust_gsi_sq_attr(qp, init_attr); ++ ++ if (udata) /* This will update DPI and qp_handle */ ++ rc = bnxt_re_init_user_qp(rdev, pd, qp, udata); ++out: ++ return rc; ++} + +- qp->qplib_qp.rq.q_full_delta = qp->qplib_qp.rq.max_wqe - +- qp_init_attr->cap.max_recv_wr; ++static int bnxt_re_create_shadow_gsi(struct bnxt_re_qp *qp, ++ struct bnxt_re_pd *pd) ++{ ++ struct bnxt_re_sqp_entries *sqp_tbl = NULL; ++ struct bnxt_re_dev *rdev; ++ struct bnxt_re_qp *sqp; ++ struct bnxt_re_ah *sah; ++ int rc = 0; + +- qp->qplib_qp.rq.max_sge = qp_init_attr->cap.max_recv_sge; +- if (qp->qplib_qp.rq.max_sge > dev_attr->max_qp_sges) +- qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges; ++ rdev = qp->rdev; ++ /* Create a shadow QP to handle the QP1 traffic */ ++ sqp_tbl = kzalloc(sizeof(*sqp_tbl) * BNXT_RE_MAX_GSI_SQP_ENTRIES, ++ GFP_KERNEL); ++ if (!sqp_tbl) ++ return -ENOMEM; ++ rdev->gsi_ctx.sqp_tbl = sqp_tbl; ++ ++ sqp = bnxt_re_create_shadow_qp(pd, &rdev->qplib_res, &qp->qplib_qp); ++ if (!sqp) { ++ rc = -ENODEV; ++ dev_err(rdev_to_dev(rdev), ++ "Failed to create Shadow QP for QP1"); ++ goto out; + } ++ rdev->gsi_ctx.gsi_sqp = sqp; + +- qp->qplib_qp.mtu = ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu)); ++ sqp->rcq = qp->rcq; ++ sqp->scq = qp->scq; ++ sah = bnxt_re_create_shadow_qp_ah(pd, &rdev->qplib_res, ++ &qp->qplib_qp); ++ if (!sah) { ++ bnxt_qplib_destroy_qp(&rdev->qplib_res, ++ &sqp->qplib_qp); ++ rc = -ENODEV; ++ dev_err(rdev_to_dev(rdev), ++ "Failed to create AH entry for ShadowQP"); ++ goto out; ++ } ++ rdev->gsi_ctx.gsi_sah = sah; + +- if (qp_init_attr->qp_type == IB_QPT_GSI && +- !(bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx))) { +- /* Allocate 1 more than what's provided */ +- entries = roundup_pow_of_two(qp_init_attr->cap.max_send_wr + 1); +- qp->qplib_qp.sq.max_wqe = min_t(u32, entries, +- dev_attr->max_qp_wqes + 1); +- qp->qplib_qp.sq.q_full_delta = qp->qplib_qp.sq.max_wqe - +- qp_init_attr->cap.max_send_wr; +- qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges; +- if (qp->qplib_qp.rq.max_sge > dev_attr->max_qp_sges) +- qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges; +- qp->qplib_qp.sq.max_sge++; +- if (qp->qplib_qp.sq.max_sge > dev_attr->max_qp_sges) +- qp->qplib_qp.sq.max_sge = dev_attr->max_qp_sges; +- +- qp->qplib_qp.rq_hdr_buf_size = +- BNXT_QPLIB_MAX_QP1_RQ_HDR_SIZE_V2; +- +- qp->qplib_qp.sq_hdr_buf_size = +- BNXT_QPLIB_MAX_QP1_SQ_HDR_SIZE_V2; +- qp->qplib_qp.dpi = &rdev->dpi_privileged; +- rc = bnxt_qplib_create_qp1(&rdev->qplib_res, &qp->qplib_qp); +- if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to create HW QP1"); +- goto fail; +- } +- /* Create a shadow QP to handle the QP1 traffic */ +- rdev->qp1_sqp = bnxt_re_create_shadow_qp(pd, &rdev->qplib_res, +- &qp->qplib_qp); +- if (!rdev->qp1_sqp) { +- rc = -EINVAL; +- dev_err(rdev_to_dev(rdev), +- "Failed to create Shadow QP for QP1"); +- goto qp_destroy; +- } +- rdev->sqp_ah = bnxt_re_create_shadow_qp_ah(pd, &rdev->qplib_res, +- &qp->qplib_qp); +- if (!rdev->sqp_ah) { +- bnxt_qplib_destroy_qp(&rdev->qplib_res, +- &rdev->qp1_sqp->qplib_qp); +- rc = -EINVAL; +- dev_err(rdev_to_dev(rdev), +- "Failed to create AH entry for ShadowQP"); +- goto qp_destroy; +- } ++ return 0; ++out: ++ kfree(sqp_tbl); ++ return rc; ++} + +- } else { +- /* Allocate 128 + 1 more than what's provided */ +- entries = roundup_pow_of_two(qp_init_attr->cap.max_send_wr + +- BNXT_QPLIB_RESERVED_QP_WRS + 1); +- qp->qplib_qp.sq.max_wqe = min_t(u32, entries, +- dev_attr->max_qp_wqes + +- BNXT_QPLIB_RESERVED_QP_WRS + 1); +- qp->qplib_qp.sq.q_full_delta = BNXT_QPLIB_RESERVED_QP_WRS + 1; ++static int bnxt_re_create_gsi_qp(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd, ++ struct ib_qp_init_attr *init_attr) ++{ ++ struct bnxt_qplib_dev_attr *dev_attr; ++ struct bnxt_re_dev *rdev; ++ struct bnxt_qplib_qp *qplqp; ++ int rc = 0; + +- /* +- * Reserving one slot for Phantom WQE. Application can +- * post one extra entry in this case. But allowing this to avoid +- * unexpected Queue full condition +- */ ++ rdev = qp->rdev; ++ qplqp = &qp->qplib_qp; ++ dev_attr = &rdev->dev_attr; + +- qp->qplib_qp.sq.q_full_delta -= 1; ++ qplqp->rq_hdr_buf_size = BNXT_QPLIB_MAX_QP1_RQ_HDR_SIZE_V2; ++ qplqp->sq_hdr_buf_size = BNXT_QPLIB_MAX_QP1_SQ_HDR_SIZE_V2; + +- qp->qplib_qp.max_rd_atomic = dev_attr->max_qp_rd_atom; +- qp->qplib_qp.max_dest_rd_atomic = dev_attr->max_qp_init_rd_atom; +- if (udata) { +- rc = bnxt_re_init_user_qp(rdev, pd, qp, udata); +- if (rc) +- goto fail; +- } else { +- qp->qplib_qp.dpi = &rdev->dpi_privileged; +- } ++ rc = bnxt_qplib_create_qp1(&rdev->qplib_res, qplqp); ++ if (rc) { ++ dev_err(rdev_to_dev(rdev), "create HW QP1 failed!"); ++ goto out; ++ } ++ ++ rc = bnxt_re_create_shadow_gsi(qp, pd); ++out: ++ return rc; ++} + ++static bool bnxt_re_test_qp_limits(struct bnxt_re_dev *rdev, ++ struct ib_qp_init_attr *init_attr, ++ struct bnxt_qplib_dev_attr *dev_attr) ++{ ++ bool rc = true; ++ ++ if (init_attr->cap.max_send_wr > dev_attr->max_qp_wqes || ++ init_attr->cap.max_recv_wr > dev_attr->max_qp_wqes || ++ init_attr->cap.max_send_sge > dev_attr->max_qp_sges || ++ init_attr->cap.max_recv_sge > dev_attr->max_qp_sges || ++ init_attr->cap.max_inline_data > dev_attr->max_inline_data) { ++ dev_err(rdev_to_dev(rdev), ++ "Create QP failed - max exceeded! 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x", ++ init_attr->cap.max_send_wr, dev_attr->max_qp_wqes, ++ init_attr->cap.max_recv_wr, dev_attr->max_qp_wqes, ++ init_attr->cap.max_send_sge, dev_attr->max_qp_sges, ++ init_attr->cap.max_recv_sge, dev_attr->max_qp_sges, ++ init_attr->cap.max_inline_data, ++ dev_attr->max_inline_data); ++ rc = false; ++ } ++ return rc; ++} ++ ++struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, ++ struct ib_qp_init_attr *qp_init_attr, ++ struct ib_udata *udata) ++{ ++ struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd); ++ struct bnxt_re_dev *rdev = pd->rdev; ++ struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr; ++ struct bnxt_re_qp *qp; ++ int rc; ++ ++ rc = bnxt_re_test_qp_limits(rdev, qp_init_attr, dev_attr); ++ if (!rc) { ++ rc = -EINVAL; ++ goto exit; ++ } ++ ++ qp = kzalloc(sizeof(*qp), GFP_KERNEL); ++ if (!qp) { ++ rc = -ENOMEM; ++ goto exit; ++ } ++ qp->rdev = rdev; ++ rc = bnxt_re_init_qp_attr(qp, pd, qp_init_attr, udata); ++ if (rc) ++ goto fail; ++ ++ if (qp_init_attr->qp_type == IB_QPT_GSI && ++ !(bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx))) { ++ rc = bnxt_re_create_gsi_qp(qp, pd, qp_init_attr); ++ if (rc == -ENODEV) ++ goto qp_destroy; ++ if (rc) ++ goto fail; ++ } else { + rc = bnxt_qplib_create_qp(&rdev->qplib_res, &qp->qplib_qp); + if (rc) { + dev_err(rdev_to_dev(rdev), "Failed to create HW QP"); + goto free_umem; + } ++ if (udata) { ++ struct bnxt_re_qp_resp resp; ++ ++ resp.qpid = qp->qplib_qp.id; ++ resp.rsvd = 0; ++ rc = ib_copy_to_udata(udata, &resp, sizeof(resp)); ++ if (rc) { ++ dev_err(rdev_to_dev(rdev), "Failed to copy QP udata"); ++ goto qp_destroy; ++ } ++ } + } + + qp->ib_qp.qp_num = qp->qplib_qp.id; ++ if (qp_init_attr->qp_type == IB_QPT_GSI) ++ rdev->gsi_ctx.gsi_qp = qp; + spin_lock_init(&qp->sq_lock); + spin_lock_init(&qp->rq_lock); +- +- if (udata) { +- struct bnxt_re_qp_resp resp; +- +- resp.qpid = qp->ib_qp.qp_num; +- resp.rsvd = 0; +- rc = ib_copy_to_udata(udata, &resp, sizeof(resp)); +- if (rc) { +- dev_err(rdev_to_dev(rdev), "Failed to copy QP udata"); +- goto qp_destroy; +- } +- } + INIT_LIST_HEAD(&qp->list); + mutex_lock(&rdev->qp_lock); + list_add_tail(&qp->list, &rdev->qp_list); +- atomic_inc(&rdev->qp_count); + mutex_unlock(&rdev->qp_lock); ++ atomic_inc(&rdev->qp_count); + + return &qp->ib_qp; + qp_destroy: +@@ -1206,6 +1404,7 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, + ib_umem_release(qp->sumem); + fail: + kfree(qp); ++exit: + return ERR_PTR(rc); + } + +@@ -1504,7 +1703,7 @@ static int bnxt_re_modify_shadow_qp(struct bnxt_re_dev *rdev, + struct bnxt_re_qp *qp1_qp, + int qp_attr_mask) + { +- struct bnxt_re_qp *qp = rdev->qp1_sqp; ++ struct bnxt_re_qp *qp = rdev->gsi_ctx.gsi_sqp; + int rc = 0; + + if (qp_attr_mask & IB_QP_STATE) { +@@ -1768,7 +1967,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, + dev_err(rdev_to_dev(rdev), "Failed to modify HW QP"); + return rc; + } +- if (ib_qp->qp_type == IB_QPT_GSI && rdev->qp1_sqp) ++ if (ib_qp->qp_type == IB_QPT_GSI && rdev->gsi_ctx.gsi_sqp) + rc = bnxt_re_modify_shadow_qp(rdev, qp, qp_attr_mask); + return rc; + } +@@ -2013,9 +2212,12 @@ static int bnxt_re_build_qp1_shadow_qp_recv(struct bnxt_re_qp *qp, + struct bnxt_qplib_swqe *wqe, + int payload_size) + { ++ struct bnxt_re_sqp_entries *sqp_entry; + struct bnxt_qplib_sge ref, sge; ++ struct bnxt_re_dev *rdev; + u32 rq_prod_index; +- struct bnxt_re_sqp_entries *sqp_entry; ++ ++ rdev = qp->rdev; + + rq_prod_index = bnxt_qplib_get_rq_prod_index(&qp->qplib_qp); + +@@ -2030,7 +2232,7 @@ static int bnxt_re_build_qp1_shadow_qp_recv(struct bnxt_re_qp *qp, + ref.lkey = wqe->sg_list[0].lkey; + ref.size = wqe->sg_list[0].size; + +- sqp_entry = &qp->rdev->sqp_tbl[rq_prod_index]; ++ sqp_entry = &rdev->gsi_ctx.sqp_tbl[rq_prod_index]; + + /* SGE 1 */ + wqe->sg_list[0].addr = sge.addr; +@@ -2850,12 +3052,13 @@ static bool bnxt_re_is_loopback_packet(struct bnxt_re_dev *rdev, + return rc; + } + +-static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *qp1_qp, ++static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *gsi_qp, + struct bnxt_qplib_cqe *cqe) + { +- struct bnxt_re_dev *rdev = qp1_qp->rdev; ++ struct bnxt_re_dev *rdev = gsi_qp->rdev; + struct bnxt_re_sqp_entries *sqp_entry = NULL; +- struct bnxt_re_qp *qp = rdev->qp1_sqp; ++ struct bnxt_re_qp *gsi_sqp = rdev->gsi_ctx.gsi_sqp; ++ struct bnxt_re_ah *gsi_sah; + struct ib_send_wr *swr; + struct ib_ud_wr udwr; + struct ib_recv_wr rwr; +@@ -2878,19 +3081,19 @@ static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *qp1_qp, + swr = &udwr.wr; + tbl_idx = cqe->wr_id; + +- rq_hdr_buf = qp1_qp->qplib_qp.rq_hdr_buf + +- (tbl_idx * qp1_qp->qplib_qp.rq_hdr_buf_size); +- rq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&qp1_qp->qplib_qp, ++ rq_hdr_buf = gsi_qp->qplib_qp.rq_hdr_buf + ++ (tbl_idx * gsi_qp->qplib_qp.rq_hdr_buf_size); ++ rq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&gsi_qp->qplib_qp, + tbl_idx); + + /* Shadow QP header buffer */ +- shrq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&qp->qplib_qp, ++ shrq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&gsi_qp->qplib_qp, + tbl_idx); +- sqp_entry = &rdev->sqp_tbl[tbl_idx]; ++ sqp_entry = &rdev->gsi_ctx.sqp_tbl[tbl_idx]; + + /* Store this cqe */ + memcpy(&sqp_entry->cqe, cqe, sizeof(struct bnxt_qplib_cqe)); +- sqp_entry->qp1_qp = qp1_qp; ++ sqp_entry->qp1_qp = gsi_qp; + + /* Find packet type from the cqe */ + +@@ -2944,7 +3147,7 @@ static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *qp1_qp, + rwr.wr_id = tbl_idx; + rwr.next = NULL; + +- rc = bnxt_re_post_recv_shadow_qp(rdev, qp, &rwr); ++ rc = bnxt_re_post_recv_shadow_qp(rdev, gsi_sqp, &rwr); + if (rc) { + dev_err(rdev_to_dev(rdev), + "Failed to post Rx buffers to shadow QP"); +@@ -2956,13 +3159,13 @@ static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *qp1_qp, + swr->wr_id = tbl_idx; + swr->opcode = IB_WR_SEND; + swr->next = NULL; +- +- udwr.ah = &rdev->sqp_ah->ib_ah; +- udwr.remote_qpn = rdev->qp1_sqp->qplib_qp.id; +- udwr.remote_qkey = rdev->qp1_sqp->qplib_qp.qkey; ++ gsi_sah = rdev->gsi_ctx.gsi_sah; ++ udwr.ah = &gsi_sah->ib_ah; ++ udwr.remote_qpn = gsi_sqp->qplib_qp.id; ++ udwr.remote_qkey = gsi_sqp->qplib_qp.qkey; + + /* post data received in the send queue */ +- rc = bnxt_re_post_send_shadow_qp(rdev, qp, swr); ++ rc = bnxt_re_post_send_shadow_qp(rdev, gsi_sqp, swr); + + return 0; + } +@@ -3029,12 +3232,12 @@ static void bnxt_re_process_res_rc_wc(struct ib_wc *wc, + wc->opcode = IB_WC_RECV_RDMA_WITH_IMM; + } + +-static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *qp, ++static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *gsi_sqp, + struct ib_wc *wc, + struct bnxt_qplib_cqe *cqe) + { +- struct bnxt_re_dev *rdev = qp->rdev; +- struct bnxt_re_qp *qp1_qp = NULL; ++ struct bnxt_re_dev *rdev = gsi_sqp->rdev; ++ struct bnxt_re_qp *gsi_qp = NULL; + struct bnxt_qplib_cqe *orig_cqe = NULL; + struct bnxt_re_sqp_entries *sqp_entry = NULL; + int nw_type; +@@ -3044,13 +3247,13 @@ static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *qp, + + tbl_idx = cqe->wr_id; + +- sqp_entry = &rdev->sqp_tbl[tbl_idx]; +- qp1_qp = sqp_entry->qp1_qp; ++ sqp_entry = &rdev->gsi_ctx.sqp_tbl[tbl_idx]; ++ gsi_qp = sqp_entry->qp1_qp; + orig_cqe = &sqp_entry->cqe; + + wc->wr_id = sqp_entry->wrid; + wc->byte_len = orig_cqe->length; +- wc->qp = &qp1_qp->ib_qp; ++ wc->qp = &gsi_qp->ib_qp; + + wc->ex.imm_data = orig_cqe->immdata; + wc->src_qp = orig_cqe->src_qp; +@@ -3137,7 +3340,7 @@ static int send_phantom_wqe(struct bnxt_re_qp *qp) + int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc) + { + struct bnxt_re_cq *cq = container_of(ib_cq, struct bnxt_re_cq, ib_cq); +- struct bnxt_re_qp *qp; ++ struct bnxt_re_qp *qp, *sh_qp; + struct bnxt_qplib_cqe *cqe; + int i, ncqe, budget; + struct bnxt_qplib_q *sq; +@@ -3201,8 +3404,9 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc) + + switch (cqe->opcode) { + case CQ_BASE_CQE_TYPE_REQ: +- if (qp->rdev->qp1_sqp && qp->qplib_qp.id == +- qp->rdev->qp1_sqp->qplib_qp.id) { ++ sh_qp = qp->rdev->gsi_ctx.gsi_sqp; ++ if (sh_qp && ++ qp->qplib_qp.id == sh_qp->qplib_qp.id) { + /* Handle this completion with + * the stored completion + */ +@@ -3228,7 +3432,7 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc) + * stored in the table + */ + tbl_idx = cqe->wr_id; +- sqp_entry = &cq->rdev->sqp_tbl[tbl_idx]; ++ sqp_entry = &cq->rdev->gsi_ctx.sqp_tbl[tbl_idx]; + wc->wr_id = sqp_entry->wrid; + bnxt_re_process_res_rawqp1_wc(wc, cqe); + break; +@@ -3236,8 +3440,9 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc) + bnxt_re_process_res_rc_wc(wc, cqe); + break; + case CQ_BASE_CQE_TYPE_RES_UD: +- if (qp->rdev->qp1_sqp && qp->qplib_qp.id == +- qp->rdev->qp1_sqp->qplib_qp.id) { ++ sh_qp = qp->rdev->gsi_ctx.gsi_sqp; ++ if (sh_qp && ++ qp->qplib_qp.id == sh_qp->qplib_qp.id) { + /* Handle this completion with + * the stored completion + */ +diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c +index 41fc05d531183..a40bc23196bf7 100644 +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -1127,7 +1127,8 @@ static int bnxt_re_query_hwrm_pri2cos(struct bnxt_re_dev *rdev, u8 dir, + static bool bnxt_re_is_qp1_or_shadow_qp(struct bnxt_re_dev *rdev, + struct bnxt_re_qp *qp) + { +- return (qp->ib_qp.qp_type == IB_QPT_GSI) || (qp == rdev->qp1_sqp); ++ return (qp->ib_qp.qp_type == IB_QPT_GSI) || ++ (qp == rdev->gsi_ctx.gsi_sqp); + } + + static void bnxt_re_dev_stop(struct bnxt_re_dev *rdev) +-- +2.39.2 + diff --git a/queue-5.4/rdma-efa-fix-unsupported-page-sizes-in-device.patch b/queue-5.4/rdma-efa-fix-unsupported-page-sizes-in-device.patch new file mode 100644 index 00000000000..5bb62bac9a8 --- /dev/null +++ b/queue-5.4/rdma-efa-fix-unsupported-page-sizes-in-device.patch @@ -0,0 +1,42 @@ +From 92f49de64ea952ed00e743038c27834a0282b916 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 May 2023 11:51:03 +0000 +Subject: RDMA/efa: Fix unsupported page sizes in device + +From: Yonatan Nachum + +[ Upstream commit 866422cdddcdf59d8c68e9472d49ba1be29b5fcf ] + +Device uses 4KB size blocks for user pages indirect list while the +driver creates those blocks with the size of PAGE_SIZE of the kernel. On +kernels with PAGE_SIZE different than 4KB (ARM RHEL), this leads to a +failure on register MR with indirect list because of the miss +communication between driver and device. + +Fixes: 40909f664d27 ("RDMA/efa: Add EFA verbs implementation") +Link: https://lore.kernel.org/r/20230511115103.13876-1-ynachum@amazon.com +Reviewed-by: Firas Jahjah +Reviewed-by: Michael Margolin +Signed-off-by: Yonatan Nachum +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/efa/efa_verbs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c +index 17f1e59ab12ee..559b24ca52050 100644 +--- a/drivers/infiniband/hw/efa/efa_verbs.c ++++ b/drivers/infiniband/hw/efa/efa_verbs.c +@@ -1231,7 +1231,7 @@ static int pbl_continuous_initialize(struct efa_dev *dev, + */ + static int pbl_indirect_initialize(struct efa_dev *dev, struct pbl_context *pbl) + { +- u32 size_in_pages = DIV_ROUND_UP(pbl->pbl_buf_size_in_bytes, PAGE_SIZE); ++ u32 size_in_pages = DIV_ROUND_UP(pbl->pbl_buf_size_in_bytes, EFA_CHUNK_PAYLOAD_SIZE); + struct scatterlist *sgl; + int sg_dma_cnt, err; + +-- +2.39.2 + diff --git a/queue-5.4/scsi-core-decrease-scsi_device-s-iorequest_cnt-if-di.patch b/queue-5.4/scsi-core-decrease-scsi_device-s-iorequest_cnt-if-di.patch new file mode 100644 index 00000000000..4fd6156ae4d --- /dev/null +++ b/queue-5.4/scsi-core-decrease-scsi_device-s-iorequest_cnt-if-di.patch @@ -0,0 +1,51 @@ +From 26c4d8b52cd64649fae66f98c3e3164b223370af Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 May 2023 15:01:56 +0800 +Subject: scsi: core: Decrease scsi_device's iorequest_cnt if dispatch failed + +From: Wenchao Hao + +[ Upstream commit 09e797c8641f6ad435c33ae24c223351197ea29a ] + +If scsi_dispatch_cmd() failed, the SCSI command was not sent to the target, +scsi_queue_rq() would return BLK_STS_RESOURCE and the related request would +be requeued. The timeout of this request would not fire, no one would +increase iodone_cnt. + +The above flow would result the iodone_cnt smaller than iorequest_cnt. So +decrease the iorequest_cnt if dispatch failed to workaround the issue. + +Signed-off-by: Wenchao Hao +Reported-by: Ming Lei +Closes: https://lore.kernel.org/r/ZF+zB+bB7iqe0wGd@ovpn-8-17.pek2.redhat.com +Link: https://lore.kernel.org/r/20230515070156.1790181-3-haowenchao2@huawei.com +Reviewed-by: Ming Lei +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/scsi_lib.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c +index 490d6c72d8bd6..8d05faf95ac3b 100644 +--- a/drivers/scsi/scsi_lib.c ++++ b/drivers/scsi/scsi_lib.c +@@ -1534,6 +1534,7 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd) + */ + SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd, + "queuecommand : device blocked\n")); ++ atomic_dec(&cmd->device->iorequest_cnt); + return SCSI_MLQUEUE_DEVICE_BUSY; + } + +@@ -1566,6 +1567,7 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd) + trace_scsi_dispatch_cmd_start(cmd); + rtn = host->hostt->queuecommand(host, cmd); + if (rtn) { ++ atomic_dec(&cmd->device->iorequest_cnt); + trace_scsi_dispatch_cmd_error(cmd, rtn); + if (rtn != SCSI_MLQUEUE_DEVICE_BUSY && + rtn != SCSI_MLQUEUE_TARGET_BUSY) +-- +2.39.2 + diff --git a/queue-5.4/series b/queue-5.4/series index e69de29bb2d..84d89c655bc 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -0,0 +1,60 @@ +rdma-efa-fix-unsupported-page-sizes-in-device.patch +rdma-bnxt_re-enable-sriov-vf-support-on-broadcom-s-5.patch +rdma-bnxt_re-refactor-queue-pair-creation-code.patch +rdma-bnxt_re-fix-return-value-of-bnxt_re_process_raw.patch +iommu-rockchip-fix-unwind-goto-issue.patch +iommu-amd-don-t-block-updates-to-gatag-if-guest-mode.patch +dmaengine-pl330-rename-_start-to-prevent-build-error.patch +net-mlx5-fw_tracer-fix-event-handling.patch +netrom-fix-info-leak-in-nr_write_internal.patch +af_packet-fix-data-races-of-pkt_sk-sk-num.patch +amd-xgbe-fix-the-false-linkup-in-xgbe_phy_status.patch +mtd-rawnand-ingenic-fix-empty-stub-helper-definition.patch +af_packet-do-not-use-read_once-in-packet_bind.patch +tcp-deny-tcp_disconnect-when-threads-are-waiting.patch +tcp-return-user_mss-for-tcp_maxseg-in-close-listen-s.patch +net-sched-sch_ingress-only-create-under-tc_h_ingress.patch +net-sched-sch_clsact-only-create-under-tc_h_clsact.patch +net-sched-reserve-tc_h_ingress-tc_h_clsact-for-ingre.patch +net-sched-prohibit-regrafting-ingress-or-clsact-qdis.patch +net-sched-fix-null-pointer-dereference-in-mq_attach.patch +ocfs2-dlm-move-bits_to_bytes-to-bitops.h-for-wider-u.patch +net-netlink-fix-netlink_list_memberships-length-repo.patch +udp6-fix-race-condition-in-udp6_sendmsg-connect.patch +net-sched-flower-fix-possible-oob-write-in-fl_set_ge.patch +net-dsa-mv88e6xxx-increase-wait-after-reset-deactiva.patch +mtd-rawnand-marvell-ensure-timing-values-are-written.patch +mtd-rawnand-marvell-don-t-set-the-nand-frequency-sel.patch +watchdog-menz069_wdt-fix-watchdog-initialisation.patch +mailbox-mailbox-test-fix-potential-double-free-in-mb.patch +arm-9295-1-unwind-fix-unwind-abort-for-uleb128-case.patch +media-rcar-vin-select-correct-interrupt-mode-for-v4l.patch +fbdev-modedb-add-1920x1080-at-60-hz-video-mode.patch +fbdev-stifb-fix-info-entry-in-sti_struct-on-error-pa.patch +nbd-fix-debugfs_create_dir-error-checking.patch +asoc-dwc-limit-the-number-of-overrun-messages.patch +xfrm-check-if_id-in-inbound-policy-secpath-match.patch +asoc-ssm2602-add-workaround-for-playback-distortions.patch +media-dvb_demux-fix-a-bug-for-the-continuity-counter.patch +media-dvb-usb-az6027-fix-three-null-ptr-deref-in-az6.patch +media-dvb-usb-v2-ec168-fix-null-ptr-deref-in-ec168_i.patch +media-dvb-usb-v2-ce6230-fix-null-ptr-deref-in-ce6230.patch +media-dvb-usb-v2-rtl28xxu-fix-null-ptr-deref-in-rtl2.patch +media-dvb-usb-digitv-fix-null-ptr-deref-in-digitv_i2.patch +media-dvb-usb-dw2102-fix-uninit-value-in-su3000_read.patch +media-netup_unidvb-fix-irq-init-by-register-it-at-th.patch +media-dvb_ca_en50221-fix-a-size-write-bug.patch +media-ttusb-dec-fix-memory-leak-in-ttusb_dec_exit_dv.patch +media-mn88443x-fix-config_of-error-by-drop-of_match_.patch +media-dvb-core-fix-use-after-free-due-on-race-condit.patch +media-dvb-core-fix-kernel-warning-for-blocking-opera.patch +media-dvb-core-fix-use-after-free-due-to-race-condit.patch +wifi-rtl8xxxu-fix-authentication-timeout-due-to-inco.patch +arm-dts-stm32-add-pin-map-for-can-controller-on-stm3.patch +arm64-mm-mark-private-vm_fault_x-defines-as-vm_fault.patch +scsi-core-decrease-scsi_device-s-iorequest_cnt-if-di.patch +wifi-b43-fix-incorrect-__packed-annotation.patch +netfilter-conntrack-define-variables-exp_nat_nla_pol.patch +alsa-oss-avoid-missing-prototype-warnings.patch +atm-hide-unused-procfs-functions.patch +mailbox-mailbox-test-fix-a-locking-issue-in-mbox_tes.patch diff --git a/queue-5.4/tcp-deny-tcp_disconnect-when-threads-are-waiting.patch b/queue-5.4/tcp-deny-tcp_disconnect-when-threads-are-waiting.patch new file mode 100644 index 00000000000..491d431e8e0 --- /dev/null +++ b/queue-5.4/tcp-deny-tcp_disconnect-when-threads-are-waiting.patch @@ -0,0 +1,186 @@ +From 5e7d9e00f58e9183caa665c730425291cef8dce8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 May 2023 16:34:58 +0000 +Subject: tcp: deny tcp_disconnect() when threads are waiting + +From: Eric Dumazet + +[ Upstream commit 4faeee0cf8a5d88d63cdbc3bab124fb0e6aed08c ] + +Historically connect(AF_UNSPEC) has been abused by syzkaller +and other fuzzers to trigger various bugs. + +A recent one triggers a divide-by-zero [1], and Paolo Abeni +was able to diagnose the issue. + +tcp_recvmsg_locked() has tests about sk_state being not TCP_LISTEN +and TCP REPAIR mode being not used. + +Then later if socket lock is released in sk_wait_data(), +another thread can call connect(AF_UNSPEC), then make this +socket a TCP listener. + +When recvmsg() is resumed, it can eventually call tcp_cleanup_rbuf() +and attempt a divide by 0 in tcp_rcv_space_adjust() [1] + +This patch adds a new socket field, counting number of threads +blocked in sk_wait_event() and inet_wait_for_connect(). + +If this counter is not zero, tcp_disconnect() returns an error. + +This patch adds code in blocking socket system calls, thus should +not hurt performance of non blocking ones. + +Note that we probably could revert commit 499350a5a6e7 ("tcp: +initialize rcv_mss to TCP_MIN_MSS instead of 0") to restore +original tcpi_rcv_mss meaning (was 0 if no payload was ever +received on a socket) + +[1] +divide error: 0000 [#1] PREEMPT SMP KASAN +CPU: 0 PID: 13832 Comm: syz-executor.5 Not tainted 6.3.0-rc4-syzkaller-00224-g00c7b5f4ddc5 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/02/2023 +RIP: 0010:tcp_rcv_space_adjust+0x36e/0x9d0 net/ipv4/tcp_input.c:740 +Code: 00 00 00 00 fc ff df 4c 89 64 24 48 8b 44 24 04 44 89 f9 41 81 c7 80 03 00 00 c1 e1 04 44 29 f0 48 63 c9 48 01 e9 48 0f af c1 <49> f7 f6 48 8d 04 41 48 89 44 24 40 48 8b 44 24 30 48 c1 e8 03 48 +RSP: 0018:ffffc900033af660 EFLAGS: 00010206 +RAX: 4a66b76cbade2c48 RBX: ffff888076640cc0 RCX: 00000000c334e4ac +RDX: 0000000000000000 RSI: dffffc0000000000 RDI: 0000000000000001 +RBP: 00000000c324e86c R08: 0000000000000001 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: ffff8880766417f8 +R13: ffff888028fbb980 R14: 0000000000000000 R15: 0000000000010344 +FS: 00007f5bffbfe700(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000001b32f25000 CR3: 000000007ced0000 CR4: 00000000003506f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + +tcp_recvmsg_locked+0x100e/0x22e0 net/ipv4/tcp.c:2616 +tcp_recvmsg+0x117/0x620 net/ipv4/tcp.c:2681 +inet6_recvmsg+0x114/0x640 net/ipv6/af_inet6.c:670 +sock_recvmsg_nosec net/socket.c:1017 [inline] +sock_recvmsg+0xe2/0x160 net/socket.c:1038 +____sys_recvmsg+0x210/0x5a0 net/socket.c:2720 +___sys_recvmsg+0xf2/0x180 net/socket.c:2762 +do_recvmmsg+0x25e/0x6e0 net/socket.c:2856 +__sys_recvmmsg net/socket.c:2935 [inline] +__do_sys_recvmmsg net/socket.c:2958 [inline] +__se_sys_recvmmsg net/socket.c:2951 [inline] +__x64_sys_recvmmsg+0x20f/0x260 net/socket.c:2951 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] +do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 +entry_SYSCALL_64_after_hwframe+0x63/0xcd +RIP: 0033:0x7f5c0108c0f9 +Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 f1 19 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007f5bffbfe168 EFLAGS: 00000246 ORIG_RAX: 000000000000012b +RAX: ffffffffffffffda RBX: 00007f5c011ac050 RCX: 00007f5c0108c0f9 +RDX: 0000000000000001 RSI: 0000000020000bc0 RDI: 0000000000000003 +RBP: 00007f5c010e7b39 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000122 R11: 0000000000000246 R12: 0000000000000000 +R13: 00007f5c012cfb1f R14: 00007f5bffbfe300 R15: 0000000000022000 + + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot +Reported-by: Paolo Abeni +Diagnosed-by: Paolo Abeni +Signed-off-by: Eric Dumazet +Tested-by: Paolo Abeni +Link: https://lore.kernel.org/r/20230526163458.2880232-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 4 ++++ + net/ipv4/af_inet.c | 2 ++ + net/ipv4/inet_connection_sock.c | 1 + + net/ipv4/tcp.c | 6 ++++++ + 4 files changed, 13 insertions(+) + +diff --git a/include/net/sock.h b/include/net/sock.h +index fa19c6ba24441..06fdb8f207b69 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -309,6 +309,7 @@ struct bpf_sk_storage; + * @sk_cgrp_data: cgroup data for this cgroup + * @sk_memcg: this socket's memory cgroup association + * @sk_write_pending: a write to stream socket waits to start ++ * @sk_wait_pending: number of threads blocked on this socket + * @sk_state_change: callback to indicate change in the state of the sock + * @sk_data_ready: callback to indicate there is data to be processed + * @sk_write_space: callback to indicate there is bf sending space available +@@ -390,6 +391,7 @@ struct sock { + unsigned int sk_napi_id; + #endif + int sk_rcvbuf; ++ int sk_wait_pending; + + struct sk_filter __rcu *sk_filter; + union { +@@ -1019,6 +1021,7 @@ static inline void sock_rps_reset_rxhash(struct sock *sk) + + #define sk_wait_event(__sk, __timeo, __condition, __wait) \ + ({ int __rc; \ ++ __sk->sk_wait_pending++; \ + release_sock(__sk); \ + __rc = __condition; \ + if (!__rc) { \ +@@ -1028,6 +1031,7 @@ static inline void sock_rps_reset_rxhash(struct sock *sk) + } \ + sched_annotate_sleep(); \ + lock_sock(__sk); \ ++ __sk->sk_wait_pending--; \ + __rc = __condition; \ + __rc; \ + }) +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index 3c6412cb4b486..a3f77ac173b53 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -578,6 +578,7 @@ static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias) + + add_wait_queue(sk_sleep(sk), &wait); + sk->sk_write_pending += writebias; ++ sk->sk_wait_pending++; + + /* Basic assumption: if someone sets sk->sk_err, he _must_ + * change state of the socket from TCP_SYN_*. +@@ -593,6 +594,7 @@ static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias) + } + remove_wait_queue(sk_sleep(sk), &wait); + sk->sk_write_pending -= writebias; ++ sk->sk_wait_pending--; + return timeo; + } + +diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c +index 04593893e0c63..374a0c3f39cc1 100644 +--- a/net/ipv4/inet_connection_sock.c ++++ b/net/ipv4/inet_connection_sock.c +@@ -824,6 +824,7 @@ struct sock *inet_csk_clone_lock(const struct sock *sk, + if (newsk) { + struct inet_connection_sock *newicsk = inet_csk(newsk); + ++ newsk->sk_wait_pending = 0; + inet_sk_set_state(newsk, TCP_SYN_RECV); + newicsk->icsk_bind_hash = NULL; + +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index a74965a6a54f4..e427eabc7f278 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2581,6 +2581,12 @@ int tcp_disconnect(struct sock *sk, int flags) + int old_state = sk->sk_state; + u32 seq; + ++ /* Deny disconnect if other threads are blocked in sk_wait_event() ++ * or inet_wait_for_connect(). ++ */ ++ if (sk->sk_wait_pending) ++ return -EBUSY; ++ + if (old_state != TCP_CLOSE) + tcp_set_state(sk, TCP_CLOSE); + +-- +2.39.2 + diff --git a/queue-5.4/tcp-return-user_mss-for-tcp_maxseg-in-close-listen-s.patch b/queue-5.4/tcp-return-user_mss-for-tcp_maxseg-in-close-listen-s.patch new file mode 100644 index 00000000000..a17f9211726 --- /dev/null +++ b/queue-5.4/tcp-return-user_mss-for-tcp_maxseg-in-close-listen-s.patch @@ -0,0 +1,50 @@ +From 023f8be6a04f25f46a0c2a31a1cf593bfa8f9d54 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 27 May 2023 12:03:17 +0800 +Subject: tcp: Return user_mss for TCP_MAXSEG in CLOSE/LISTEN state if user_mss + set + +From: Cambda Zhu + +[ Upstream commit 34dfde4ad87b84d21278a7e19d92b5b2c68e6c4d ] + +This patch replaces the tp->mss_cache check in getting TCP_MAXSEG +with tp->rx_opt.user_mss check for CLOSE/LISTEN sock. Since +tp->mss_cache is initialized with TCP_MSS_DEFAULT, checking if +it's zero is probably a bug. + +With this change, getting TCP_MAXSEG before connecting will return +default MSS normally, and return user_mss if user_mss is set. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: Jack Yang +Suggested-by: Eric Dumazet +Link: https://lore.kernel.org/netdev/CANn89i+3kL9pYtkxkwxwNMzvC_w3LNUum_2=3u+UyLBmGmifHA@mail.gmail.com/#t +Signed-off-by: Cambda Zhu +Link: https://lore.kernel.org/netdev/14D45862-36EA-4076-974C-EA67513C92F6@linux.alibaba.com/ +Reviewed-by: Jason Xing +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/20230527040317.68247-1-cambda@linux.alibaba.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index e427eabc7f278..fdf2ddc4864df 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -3451,7 +3451,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level, + switch (optname) { + case TCP_MAXSEG: + val = tp->mss_cache; +- if (!val && ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) ++ if (tp->rx_opt.user_mss && ++ ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) + val = tp->rx_opt.user_mss; + if (tp->repair) + val = tp->rx_opt.mss_clamp; +-- +2.39.2 + diff --git a/queue-5.4/udp6-fix-race-condition-in-udp6_sendmsg-connect.patch b/queue-5.4/udp6-fix-race-condition-in-udp6_sendmsg-connect.patch new file mode 100644 index 00000000000..6095afbbc15 --- /dev/null +++ b/queue-5.4/udp6-fix-race-condition-in-udp6_sendmsg-connect.patch @@ -0,0 +1,63 @@ +From c9878967d62ef2fa5501d96ba2b88c38353a6dd6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 May 2023 14:39:41 +0300 +Subject: udp6: Fix race condition in udp6_sendmsg & connect + +From: Vladislav Efanov + +[ Upstream commit 448a5ce1120c5bdbce1f1ccdabcd31c7d029f328 ] + +Syzkaller got the following report: +BUG: KASAN: use-after-free in sk_setup_caps+0x621/0x690 net/core/sock.c:2018 +Read of size 8 at addr ffff888027f82780 by task syz-executor276/3255 + +The function sk_setup_caps (called by ip6_sk_dst_store_flow-> +ip6_dst_store) referenced already freed memory as this memory was +freed by parallel task in udpv6_sendmsg->ip6_sk_dst_lookup_flow-> +sk_dst_check. + + task1 (connect) task2 (udp6_sendmsg) + sk_setup_caps->sk_dst_set | + | sk_dst_check-> + | sk_dst_set + | dst_release + sk_setup_caps references | + to already freed dst_entry| + +The reason for this race condition is: sk_setup_caps() keeps using +the dst after transferring the ownership to the dst cache. + +Found by Linux Verification Center (linuxtesting.org) with syzkaller. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Vladislav Efanov +Signed-off-by: Paolo Abeni +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/core/sock.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/core/sock.c b/net/core/sock.c +index 7f6f1a0bf8a13..5e1dccbd61a60 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1938,7 +1938,6 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst) + { + u32 max_segs = 1; + +- sk_dst_set(sk, dst); + sk->sk_route_caps = dst->dev->features | sk->sk_route_forced_caps; + if (sk->sk_route_caps & NETIF_F_GSO) + sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE; +@@ -1953,6 +1952,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst) + } + } + sk->sk_gso_max_segs = max_segs; ++ sk_dst_set(sk, dst); + } + EXPORT_SYMBOL_GPL(sk_setup_caps); + +-- +2.39.2 + diff --git a/queue-5.4/watchdog-menz069_wdt-fix-watchdog-initialisation.patch b/queue-5.4/watchdog-menz069_wdt-fix-watchdog-initialisation.patch new file mode 100644 index 00000000000..6fd6dbb1382 --- /dev/null +++ b/queue-5.4/watchdog-menz069_wdt-fix-watchdog-initialisation.patch @@ -0,0 +1,71 @@ +From 16ea29dc46d4c58084b70db93d3fd1111abef27f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Apr 2023 19:25:30 +0200 +Subject: watchdog: menz069_wdt: fix watchdog initialisation + +From: Johannes Thumshirn + +[ Upstream commit 87b22656ca6a896d0378e9e60ffccb0c82f48b08 ] + +Doing a 'cat /dev/watchdog0' with menz069_wdt as watchdog0 will result in +a NULL pointer dereference. + +This happens because we're passing the wrong pointer to +watchdog_register_device(). Fix this by getting rid of the static +watchdog_device structure and use the one embedded into the driver's +per-instance private data. + +Signed-off-by: Johannes Thumshirn +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20230418172531.177349-2-jth@kernel.org +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/menz69_wdt.c | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +diff --git a/drivers/watchdog/menz69_wdt.c b/drivers/watchdog/menz69_wdt.c +index ed18238c54074..96a25d18ab643 100644 +--- a/drivers/watchdog/menz69_wdt.c ++++ b/drivers/watchdog/menz69_wdt.c +@@ -98,14 +98,6 @@ static const struct watchdog_ops men_z069_ops = { + .set_timeout = men_z069_wdt_set_timeout, + }; + +-static struct watchdog_device men_z069_wdt = { +- .info = &men_z069_info, +- .ops = &men_z069_ops, +- .timeout = MEN_Z069_DEFAULT_TIMEOUT, +- .min_timeout = 1, +- .max_timeout = MEN_Z069_WDT_COUNTER_MAX / MEN_Z069_TIMER_FREQ, +-}; +- + static int men_z069_probe(struct mcb_device *dev, + const struct mcb_device_id *id) + { +@@ -125,15 +117,19 @@ static int men_z069_probe(struct mcb_device *dev, + goto release_mem; + + drv->mem = mem; ++ drv->wdt.info = &men_z069_info; ++ drv->wdt.ops = &men_z069_ops; ++ drv->wdt.timeout = MEN_Z069_DEFAULT_TIMEOUT; ++ drv->wdt.min_timeout = 1; ++ drv->wdt.max_timeout = MEN_Z069_WDT_COUNTER_MAX / MEN_Z069_TIMER_FREQ; + +- drv->wdt = men_z069_wdt; + watchdog_init_timeout(&drv->wdt, 0, &dev->dev); + watchdog_set_nowayout(&drv->wdt, nowayout); + watchdog_set_drvdata(&drv->wdt, drv); + drv->wdt.parent = &dev->dev; + mcb_set_drvdata(dev, drv); + +- return watchdog_register_device(&men_z069_wdt); ++ return watchdog_register_device(&drv->wdt); + + release_mem: + mcb_release_mem(mem); +-- +2.39.2 + diff --git a/queue-5.4/wifi-b43-fix-incorrect-__packed-annotation.patch b/queue-5.4/wifi-b43-fix-incorrect-__packed-annotation.patch new file mode 100644 index 00000000000..45058c0a1bc --- /dev/null +++ b/queue-5.4/wifi-b43-fix-incorrect-__packed-annotation.patch @@ -0,0 +1,69 @@ +From 34858adc49c2799fed4aefe072721378d5dd1b59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 May 2023 20:34:22 +0200 +Subject: wifi: b43: fix incorrect __packed annotation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Arnd Bergmann + +[ Upstream commit 212457ccbd60dba34f965e4ffbe62f0e4f970538 ] + +clang warns about an unpacked structure inside of a packed one: + +drivers/net/wireless/broadcom/b43/b43.h:654:4: error: field data within 'struct b43_iv' is less aligned than 'union (unnamed union at /home/arnd/arm-soc/drivers/net/wireless/broadcom/b43/b43.h:651:2)' and is usually due to 'struct b43_iv' being packed, which can lead to unaligned accesses [-Werror,-Wunaligned-access] + +The problem here is that the anonymous union has the default alignment +from its members, apparently because the original author mixed up the +placement of the __packed attribute by placing it next to the struct +member rather than the union definition. As the struct itself is +also marked as __packed, there is no need to mark its members, so just +move the annotation to the inner type instead. + +As Michael noted, the same problem is present in b43legacy, so +change both at the same time. + +Acked-by: Michael Büsch +Reported-by: kernel test robot +Reviewed-by: Simon Horman +Tested-by: Larry Finger +Link: https://lore.kernel.org/oe-kbuild-all/202305160749.ay1HAoyP-lkp@intel.com/ +Signed-off-by: Arnd Bergmann +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230516183442.536589-1-arnd@kernel.org +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/broadcom/b43/b43.h | 2 +- + drivers/net/wireless/broadcom/b43legacy/b43legacy.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/b43/b43.h b/drivers/net/wireless/broadcom/b43/b43.h +index 9fc7c088a539e..67b4bac048e58 100644 +--- a/drivers/net/wireless/broadcom/b43/b43.h ++++ b/drivers/net/wireless/broadcom/b43/b43.h +@@ -651,7 +651,7 @@ struct b43_iv { + union { + __be16 d16; + __be32 d32; +- } data __packed; ++ } __packed data; + } __packed; + + +diff --git a/drivers/net/wireless/broadcom/b43legacy/b43legacy.h b/drivers/net/wireless/broadcom/b43legacy/b43legacy.h +index 6b0cec467938f..f49365d14619f 100644 +--- a/drivers/net/wireless/broadcom/b43legacy/b43legacy.h ++++ b/drivers/net/wireless/broadcom/b43legacy/b43legacy.h +@@ -379,7 +379,7 @@ struct b43legacy_iv { + union { + __be16 d16; + __be32 d32; +- } data __packed; ++ } __packed data; + } __packed; + + #define B43legacy_PHYMODE(phytype) (1 << (phytype)) +-- +2.39.2 + diff --git a/queue-5.4/wifi-rtl8xxxu-fix-authentication-timeout-due-to-inco.patch b/queue-5.4/wifi-rtl8xxxu-fix-authentication-timeout-due-to-inco.patch new file mode 100644 index 00000000000..6e7a80cc9ab --- /dev/null +++ b/queue-5.4/wifi-rtl8xxxu-fix-authentication-timeout-due-to-inco.patch @@ -0,0 +1,73 @@ +From 55dd52ccbe354c9fc3c03178419e4088607df6e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 May 2023 09:20:55 +0800 +Subject: wifi: rtl8xxxu: fix authentication timeout due to incorrect RCR value + +From: Yun Lu + +[ Upstream commit 20429444e653ee8242dfbf815c0c37866beb371b ] + +When using rtl8192cu with rtl8xxxu driver to connect wifi, there is a +probability of failure, which shows "authentication with ... timed out". +Through debugging, it was found that the RCR register has been inexplicably +modified to an incorrect value, resulting in the nic not being able to +receive authenticated frames. + +To fix this problem, add regrcr in rtl8xxxu_priv struct, and store +the RCR value every time the register is written, and use it the next +time the register need to be modified. + +Signed-off-by: Yun Lu +Link: https://lore.kernel.org/all/20230427020512.1221062-1-luyun_611@163.com +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230512012055.2990472-1-luyun_611@163.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 1 + + drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +index 2a02d4d72dec9..b7da89ba1e7d5 100644 +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +@@ -1255,6 +1255,7 @@ struct rtl8xxxu_priv { + u32 rege9c; + u32 regeb4; + u32 regebc; ++ u32 regrcr; + int next_mbox; + int nr_out_eps; + +diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +index bdccc84278d85..2648b30aab76a 100644 +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -4048,6 +4048,7 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw) + RCR_ACCEPT_MGMT_FRAME | RCR_HTC_LOC_CTRL | + RCR_APPEND_PHYSTAT | RCR_APPEND_ICV | RCR_APPEND_MIC; + rtl8xxxu_write32(priv, REG_RCR, val32); ++ priv->regrcr = val32; + + /* + * Accept all multicast +@@ -5585,7 +5586,7 @@ static void rtl8xxxu_configure_filter(struct ieee80211_hw *hw, + unsigned int *total_flags, u64 multicast) + { + struct rtl8xxxu_priv *priv = hw->priv; +- u32 rcr = rtl8xxxu_read32(priv, REG_RCR); ++ u32 rcr = priv->regrcr; + + dev_dbg(&priv->udev->dev, "%s: changed_flags %08x, total_flags %08x\n", + __func__, changed_flags, *total_flags); +@@ -5631,6 +5632,7 @@ static void rtl8xxxu_configure_filter(struct ieee80211_hw *hw, + */ + + rtl8xxxu_write32(priv, REG_RCR, rcr); ++ priv->regrcr = rcr; + + *total_flags &= (FIF_ALLMULTI | FIF_FCSFAIL | FIF_BCN_PRBRESP_PROMISC | + FIF_CONTROL | FIF_OTHER_BSS | FIF_PSPOLL | +-- +2.39.2 + diff --git a/queue-5.4/xfrm-check-if_id-in-inbound-policy-secpath-match.patch b/queue-5.4/xfrm-check-if_id-in-inbound-policy-secpath-match.patch new file mode 100644 index 00000000000..0128c1ca458 --- /dev/null +++ b/queue-5.4/xfrm-check-if_id-in-inbound-policy-secpath-match.patch @@ -0,0 +1,79 @@ +From 5e968b03ae3f979e4cbb61b9119ebf11ab74bd0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 May 2023 01:14:14 +0000 +Subject: xfrm: Check if_id in inbound policy/secpath match + +From: Benedict Wong + +[ Upstream commit 8680407b6f8f5fba59e8f1d63c869abc280f04df ] + +This change ensures that if configured in the policy, the if_id set in +the policy and secpath states match during the inbound policy check. +Without this, there is potential for ambiguity where entries in the +secpath differing by only the if_id could be mismatched. + +Notably, this is checked in the outbound direction when resolving +templates to SAs, but not on the inbound path when matching SAs and +policies. + +Test: Tested against Android kernel unit tests & CTS +Signed-off-by: Benedict Wong +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + net/xfrm/xfrm_policy.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c +index 6f58be5a17711..9d4b405659058 100644 +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -3223,7 +3223,7 @@ xfrm_secpath_reject(int idx, struct sk_buff *skb, const struct flowi *fl) + + static inline int + xfrm_state_ok(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, +- unsigned short family) ++ unsigned short family, u32 if_id) + { + if (xfrm_state_kern(x)) + return tmpl->optional && !xfrm_state_addr_cmp(tmpl, x, tmpl->encap_family); +@@ -3234,7 +3234,8 @@ xfrm_state_ok(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, + (tmpl->allalgs || (tmpl->aalgos & (1<props.aalgo)) || + !(xfrm_id_proto_match(tmpl->id.proto, IPSEC_PROTO_ANY))) && + !(x->props.mode != XFRM_MODE_TRANSPORT && +- xfrm_state_addr_cmp(tmpl, x, family)); ++ xfrm_state_addr_cmp(tmpl, x, family)) && ++ (if_id == 0 || if_id == x->if_id); + } + + /* +@@ -3246,7 +3247,7 @@ xfrm_state_ok(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, + */ + static inline int + xfrm_policy_ok(const struct xfrm_tmpl *tmpl, const struct sec_path *sp, int start, +- unsigned short family) ++ unsigned short family, u32 if_id) + { + int idx = start; + +@@ -3256,7 +3257,7 @@ xfrm_policy_ok(const struct xfrm_tmpl *tmpl, const struct sec_path *sp, int star + } else + start = -1; + for (; idx < sp->len; idx++) { +- if (xfrm_state_ok(tmpl, sp->xvec[idx], family)) ++ if (xfrm_state_ok(tmpl, sp->xvec[idx], family, if_id)) + return ++idx; + if (sp->xvec[idx]->props.mode != XFRM_MODE_TRANSPORT) { + if (start == -1) +@@ -3666,7 +3667,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, + * are implied between each two transformations. + */ + for (i = xfrm_nr-1, k = 0; i >= 0; i--) { +- k = xfrm_policy_ok(tpp[i], sp, k, family); ++ k = xfrm_policy_ok(tpp[i], sp, k, family, if_id); + if (k < 0) { + if (k < -1) + /* "-2 - errored_index" returned */ +-- +2.39.2 +