From: Sasha Levin Date: Sat, 4 Jan 2025 14:21:12 +0000 (-0500) Subject: Fixes for 6.12 X-Git-Tag: v5.4.289~58 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ae3651565753e359663d95ee6919ce23e30f6a68;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.12 Signed-off-by: Sasha Levin --- diff --git a/queue-6.12/af_packet-fix-vlan_get_protocol_dgram-vs-msg_peek.patch b/queue-6.12/af_packet-fix-vlan_get_protocol_dgram-vs-msg_peek.patch new file mode 100644 index 00000000000..74c3750f43a --- /dev/null +++ b/queue-6.12/af_packet-fix-vlan_get_protocol_dgram-vs-msg_peek.patch @@ -0,0 +1,149 @@ +From b79264643d4267d75a6ecc09476fcca7aa528b04 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Dec 2024 16:10:04 +0000 +Subject: af_packet: fix vlan_get_protocol_dgram() vs MSG_PEEK + +From: Eric Dumazet + +[ Upstream commit f91a5b8089389eb408501af2762f168c3aaa7b79 ] + +Blamed commit forgot MSG_PEEK case, allowing a crash [1] as found +by syzbot. + +Rework vlan_get_protocol_dgram() to not touch skb at all, +so that it can be used from many cpus on the same skb. + +Add a const qualifier to skb argument. + +[1] +skbuff: skb_under_panic: text:ffffffff8a8ccd05 len:29 put:14 head:ffff88807fc8e400 data:ffff88807fc8e3f4 tail:0x11 end:0x140 dev: +------------[ cut here ]------------ + kernel BUG at net/core/skbuff.c:206 ! +Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI +CPU: 1 UID: 0 PID: 5892 Comm: syz-executor883 Not tainted 6.13.0-rc4-syzkaller-00054-gd6ef8b40d075 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 + RIP: 0010:skb_panic net/core/skbuff.c:206 [inline] + RIP: 0010:skb_under_panic+0x14b/0x150 net/core/skbuff.c:216 +Code: 0b 8d 48 c7 c6 86 d5 25 8e 48 8b 54 24 08 8b 0c 24 44 8b 44 24 04 4d 89 e9 50 41 54 41 57 41 56 e8 5a 69 79 f7 48 83 c4 20 90 <0f> 0b 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 +RSP: 0018:ffffc900038d7638 EFLAGS: 00010282 +RAX: 0000000000000087 RBX: dffffc0000000000 RCX: 609ffd18ea660600 +RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000 +RBP: ffff88802483c8d0 R08: ffffffff817f0a8c R09: 1ffff9200071ae60 +R10: dffffc0000000000 R11: fffff5200071ae61 R12: 0000000000000140 +R13: ffff88807fc8e400 R14: ffff88807fc8e3f4 R15: 0000000000000011 +FS: 00007fbac5e006c0(0000) GS:ffff8880b8700000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007fbac5e00d58 CR3: 000000001238e000 CR4: 00000000003526f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + + skb_push+0xe5/0x100 net/core/skbuff.c:2636 + vlan_get_protocol_dgram+0x165/0x290 net/packet/af_packet.c:585 + packet_recvmsg+0x948/0x1ef0 net/packet/af_packet.c:3552 + sock_recvmsg_nosec net/socket.c:1033 [inline] + sock_recvmsg+0x22f/0x280 net/socket.c:1055 + ____sys_recvmsg+0x1c6/0x480 net/socket.c:2803 + ___sys_recvmsg net/socket.c:2845 [inline] + do_recvmmsg+0x426/0xab0 net/socket.c:2940 + __sys_recvmmsg net/socket.c:3014 [inline] + __do_sys_recvmmsg net/socket.c:3037 [inline] + __se_sys_recvmmsg net/socket.c:3030 [inline] + __x64_sys_recvmmsg+0x199/0x250 net/socket.c:3030 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Fixes: 79eecf631c14 ("af_packet: Handle outgoing VLAN packets without hardware offloading") +Reported-by: syzbot+74f70bb1cb968bf09e4f@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/6772c485.050a0220.2f3838.04c5.GAE@google.com/T/#u +Signed-off-by: Eric Dumazet +Cc: Chengen Du +Reviewed-by: Willem de Bruijn +Link: https://patch.msgid.link/20241230161004.2681892-2-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/linux/if_vlan.h | 16 +++++++++++++--- + net/packet/af_packet.c | 16 ++++------------ + 2 files changed, 17 insertions(+), 15 deletions(-) + +diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h +index c1645c86eed9..d65b5d71b93b 100644 +--- a/include/linux/if_vlan.h ++++ b/include/linux/if_vlan.h +@@ -585,13 +585,16 @@ static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci) + * vlan_get_protocol - get protocol EtherType. + * @skb: skbuff to query + * @type: first vlan protocol ++ * @mac_offset: MAC offset + * @depth: buffer to store length of eth and vlan tags in bytes + * + * Returns the EtherType of the packet, regardless of whether it is + * vlan encapsulated (normal or hardware accelerated) or not. + */ +-static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type, +- int *depth) ++static inline __be16 __vlan_get_protocol_offset(const struct sk_buff *skb, ++ __be16 type, ++ int mac_offset, ++ int *depth) + { + unsigned int vlan_depth = skb->mac_len, parse_depth = VLAN_MAX_DEPTH; + +@@ -610,7 +613,8 @@ static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type, + do { + struct vlan_hdr vhdr, *vh; + +- vh = skb_header_pointer(skb, vlan_depth, sizeof(vhdr), &vhdr); ++ vh = skb_header_pointer(skb, mac_offset + vlan_depth, ++ sizeof(vhdr), &vhdr); + if (unlikely(!vh || !--parse_depth)) + return 0; + +@@ -625,6 +629,12 @@ static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type, + return type; + } + ++static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type, ++ int *depth) ++{ ++ return __vlan_get_protocol_offset(skb, type, 0, depth); ++} ++ + /** + * vlan_get_protocol - get protocol EtherType. + * @skb: skbuff to query +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index ac84b1fc1a65..f3cecb3e4bcb 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -568,21 +568,13 @@ static u16 vlan_get_tci(const struct sk_buff *skb, struct net_device *dev) + return ntohs(vh->h_vlan_TCI); + } + +-static __be16 vlan_get_protocol_dgram(struct sk_buff *skb) ++static __be16 vlan_get_protocol_dgram(const struct sk_buff *skb) + { + __be16 proto = skb->protocol; + +- if (unlikely(eth_type_vlan(proto))) { +- u8 *skb_orig_data = skb->data; +- int skb_orig_len = skb->len; +- +- skb_push(skb, skb->data - skb_mac_header(skb)); +- proto = __vlan_get_protocol(skb, proto, NULL); +- if (skb_orig_data != skb->data) { +- skb->data = skb_orig_data; +- skb->len = skb_orig_len; +- } +- } ++ if (unlikely(eth_type_vlan(proto))) ++ proto = __vlan_get_protocol_offset(skb, proto, ++ skb_mac_offset(skb), NULL); + + return proto; + } +-- +2.39.5 + diff --git a/queue-6.12/af_packet-fix-vlan_get_tci-vs-msg_peek.patch b/queue-6.12/af_packet-fix-vlan_get_tci-vs-msg_peek.patch new file mode 100644 index 00000000000..1a8cb7cc4c2 --- /dev/null +++ b/queue-6.12/af_packet-fix-vlan_get_tci-vs-msg_peek.patch @@ -0,0 +1,102 @@ +From ee52e802bcb975ae582f9230bc2bb9c60494eb23 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Dec 2024 16:10:03 +0000 +Subject: af_packet: fix vlan_get_tci() vs MSG_PEEK + +From: Eric Dumazet + +[ Upstream commit 77ee7a6d16b6ec07b5c3ae2b6b60a24c1afbed09 ] + +Blamed commit forgot MSG_PEEK case, allowing a crash [1] as found +by syzbot. + +Rework vlan_get_tci() to not touch skb at all, +so that it can be used from many cpus on the same skb. + +Add a const qualifier to skb argument. + +[1] +skbuff: skb_under_panic: text:ffffffff8a8da482 len:32 put:14 head:ffff88807a1d5800 data:ffff88807a1d5810 tail:0x14 end:0x140 dev: +------------[ cut here ]------------ + kernel BUG at net/core/skbuff.c:206 ! +Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI +CPU: 0 UID: 0 PID: 5880 Comm: syz-executor172 Not tainted 6.13.0-rc3-syzkaller-00762-g9268abe611b0 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 + RIP: 0010:skb_panic net/core/skbuff.c:206 [inline] + RIP: 0010:skb_under_panic+0x14b/0x150 net/core/skbuff.c:216 +Code: 0b 8d 48 c7 c6 9e 6c 26 8e 48 8b 54 24 08 8b 0c 24 44 8b 44 24 04 4d 89 e9 50 41 54 41 57 41 56 e8 3a 5a 79 f7 48 83 c4 20 90 <0f> 0b 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 +RSP: 0018:ffffc90003baf5b8 EFLAGS: 00010286 +RAX: 0000000000000087 RBX: dffffc0000000000 RCX: 8565c1eec37aa000 +RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000 +RBP: ffff88802616fb50 R08: ffffffff817f0a4c R09: 1ffff92000775e50 +R10: dffffc0000000000 R11: fffff52000775e51 R12: 0000000000000140 +R13: ffff88807a1d5800 R14: ffff88807a1d5810 R15: 0000000000000014 +FS: 00007fa03261f6c0(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007ffd65753000 CR3: 0000000031720000 CR4: 00000000003526f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + + skb_push+0xe5/0x100 net/core/skbuff.c:2636 + vlan_get_tci+0x272/0x550 net/packet/af_packet.c:565 + packet_recvmsg+0x13c9/0x1ef0 net/packet/af_packet.c:3616 + sock_recvmsg_nosec net/socket.c:1044 [inline] + sock_recvmsg+0x22f/0x280 net/socket.c:1066 + ____sys_recvmsg+0x1c6/0x480 net/socket.c:2814 + ___sys_recvmsg net/socket.c:2856 [inline] + do_recvmmsg+0x426/0xab0 net/socket.c:2951 + __sys_recvmmsg net/socket.c:3025 [inline] + __do_sys_recvmmsg net/socket.c:3048 [inline] + __se_sys_recvmmsg net/socket.c:3041 [inline] + __x64_sys_recvmmsg+0x199/0x250 net/socket.c:3041 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 + +Fixes: 79eecf631c14 ("af_packet: Handle outgoing VLAN packets without hardware offloading") +Reported-by: syzbot+8400677f3fd43f37d3bc@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/6772c485.050a0220.2f3838.04c6.GAE@google.com/T/#u +Signed-off-by: Eric Dumazet +Cc: Chengen Du +Reviewed-by: Willem de Bruijn +Link: https://patch.msgid.link/20241230161004.2681892-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/packet/af_packet.c | 12 +++--------- + 1 file changed, 3 insertions(+), 9 deletions(-) + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 97774bd4b6cb..ac84b1fc1a65 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -538,10 +538,8 @@ static void *packet_current_frame(struct packet_sock *po, + return packet_lookup_frame(po, rb, rb->head, status); + } + +-static u16 vlan_get_tci(struct sk_buff *skb, struct net_device *dev) ++static u16 vlan_get_tci(const struct sk_buff *skb, struct net_device *dev) + { +- u8 *skb_orig_data = skb->data; +- int skb_orig_len = skb->len; + struct vlan_hdr vhdr, *vh; + unsigned int header_len; + +@@ -562,12 +560,8 @@ static u16 vlan_get_tci(struct sk_buff *skb, struct net_device *dev) + else + return 0; + +- skb_push(skb, skb->data - skb_mac_header(skb)); +- vh = skb_header_pointer(skb, header_len, sizeof(vhdr), &vhdr); +- if (skb_orig_data != skb->data) { +- skb->data = skb_orig_data; +- skb->len = skb_orig_len; +- } ++ vh = skb_header_pointer(skb, skb_mac_offset(skb) + header_len, ++ sizeof(vhdr), &vhdr); + if (unlikely(!vh)) + return 0; + +-- +2.39.5 + diff --git a/queue-6.12/alsa-usb-audio-us16x08-initialize-array-before-use.patch b/queue-6.12/alsa-usb-audio-us16x08-initialize-array-before-use.patch new file mode 100644 index 00000000000..8795c8b7cdc --- /dev/null +++ b/queue-6.12/alsa-usb-audio-us16x08-initialize-array-before-use.patch @@ -0,0 +1,43 @@ +From 1111d4be43019a3c487f117caba21d8d0612611a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 29 Dec 2024 11:32:42 +0530 +Subject: ALSA: usb-audio: US16x08: Initialize array before use + +From: Tanya Agarwal + +[ Upstream commit b06a6187ef983f501e93faa56209169752d3bde3 ] + +Initialize meter_urb array before use in mixer_us16x08.c. + +CID 1410197: (#1 of 1): Uninitialized scalar variable (UNINIT) +uninit_use_in_call: Using uninitialized value *meter_urb when +calling get_meter_levels_from_urb. + +Coverity Link: +https://scan7.scan.coverity.com/#/project-view/52849/11354?selectedIssue=1410197 + +Fixes: d2bb390a2081 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk") +Signed-off-by: Tanya Agarwal +Link: https://patch.msgid.link/20241229060240.1642-1-tanyaagarwal25699@gmail.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/usb/mixer_us16x08.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c +index 6eb7d93b358d..20ac32635f1f 100644 +--- a/sound/usb/mixer_us16x08.c ++++ b/sound/usb/mixer_us16x08.c +@@ -687,7 +687,7 @@ static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol, + struct usb_mixer_elem_info *elem = kcontrol->private_data; + struct snd_usb_audio *chip = elem->head.mixer->chip; + struct snd_us16x08_meter_store *store = elem->private_data; +- u8 meter_urb[64]; ++ u8 meter_urb[64] = {0}; + + switch (kcontrol->private_value) { + case 0: { +-- +2.39.5 + diff --git a/queue-6.12/drm-bridge-adv7511_audio-update-audio-infoframe-prop.patch b/queue-6.12/drm-bridge-adv7511_audio-update-audio-infoframe-prop.patch new file mode 100644 index 00000000000..2403a0dccb9 --- /dev/null +++ b/queue-6.12/drm-bridge-adv7511_audio-update-audio-infoframe-prop.patch @@ -0,0 +1,74 @@ +From 7f04403f9d690d2421fc7dc06abce3ad2dff647c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Nov 2024 08:40:29 +0100 +Subject: drm/bridge: adv7511_audio: Update Audio InfoFrame properly + +From: Stefan Ekenberg + +[ Upstream commit 902806baf3c1e8383c1fe3ff0b6042b8cb5c2707 ] + +AUDIO_UPDATE bit (Bit 5 of MAIN register 0x4A) needs to be set to 1 +while updating Audio InfoFrame information and then set to 0 when done. +Otherwise partially updated Audio InfoFrames could be sent out. Two +cases where this rule were not followed are fixed: + - In adv7511_hdmi_hw_params() make sure AUDIO_UPDATE bit is updated + before/after setting ADV7511_REG_AUDIO_INFOFRAME. + - In audio_startup() use the correct register for clearing + AUDIO_UPDATE bit. + +The problem with corrupted audio infoframes were discovered by letting +a HDMI logic analyser check the output of ADV7535. + +Note that this patchs replaces writing REG_GC(1) with +REG_INFOFRAME_UPDATE. Bit 5 of REG_GC(1) is positioned within field +GC_PP[3:0] and that field doesn't control audio infoframe and is read- +only. My conclusion therefore was that the author if this code meant to +clear bit 5 of REG_INFOFRAME_UPDATE from the very beginning. + +Tested-by: Biju Das +Fixes: 53c515befe28 ("drm/bridge: adv7511: Add Audio support") +Signed-off-by: Stefan Ekenberg +Reviewed-by: Dmitry Baryshkov +Link: https://patchwork.freedesktop.org/patch/msgid/20241119-adv7511-audio-info-frame-v4-1-4ae68e76c89c@axis.com +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/adv7511/adv7511_audio.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c +index 61f4a38e7d2b..8f786592143b 100644 +--- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c ++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c +@@ -153,7 +153,16 @@ static int adv7511_hdmi_hw_params(struct device *dev, void *data, + ADV7511_AUDIO_CFG3_LEN_MASK, len); + regmap_update_bits(adv7511->regmap, ADV7511_REG_I2C_FREQ_ID_CFG, + ADV7511_I2C_FREQ_ID_CFG_RATE_MASK, rate << 4); +- regmap_write(adv7511->regmap, 0x73, 0x1); ++ ++ /* send current Audio infoframe values while updating */ ++ regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, ++ BIT(5), BIT(5)); ++ ++ regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME(0), 0x1); ++ ++ /* use Audio infoframe updated info */ ++ regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, ++ BIT(5), 0); + + return 0; + } +@@ -184,8 +193,9 @@ static int audio_startup(struct device *dev, void *data) + regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(0), + BIT(7) | BIT(6), BIT(7)); + /* use Audio infoframe updated info */ +- regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(1), ++ regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, + BIT(5), 0); ++ + /* enable SPDIF receiver */ + if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF) + regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, +-- +2.39.5 + diff --git a/queue-6.12/drm-i915-cx0_phy-fix-c10-pll-programming-sequence.patch b/queue-6.12/drm-i915-cx0_phy-fix-c10-pll-programming-sequence.patch new file mode 100644 index 00000000000..eaa401f1d1e --- /dev/null +++ b/queue-6.12/drm-i915-cx0_phy-fix-c10-pll-programming-sequence.patch @@ -0,0 +1,59 @@ +From 10838ff82ffa27276af65bfb01a96b8800ca1603 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Dec 2024 23:45:54 +0530 +Subject: drm/i915/cx0_phy: Fix C10 pll programming sequence + +From: Suraj Kandpal + +[ Upstream commit 385a95cc72941c7f88630a7bc4176048cc03b395 ] + +According to spec VDR_CUSTOM_WIDTH register gets programmed after pll +specific VDR registers and TX Lane programming registers are done. +Moreover we only program into C10_VDR_CONTROL1 to update config and +setup master lane once all VDR registers are written into. + +Bspec: 67636 +Fixes: 51390cc0e00a ("drm/i915/mtl: Add Support for C10 PHY message bus and pll programming") +Signed-off-by: Suraj Kandpal +Reviewed-by: Ankit Nautiyal +Link: https://patchwork.freedesktop.org/patch/msgid/20241216181554.2861381-1-suraj.kandpal@intel.com +(cherry picked from commit f9d418552ba1e3a0e92487ff82eb515dab7516c0) +Signed-off-by: Tvrtko Ursulin +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/display/intel_cx0_phy.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c +index 4a6c3040ca15..f11309efff33 100644 +--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c ++++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c +@@ -2084,14 +2084,6 @@ static void intel_c10_pll_program(struct drm_i915_private *i915, + 0, C10_VDR_CTRL_MSGBUS_ACCESS, + MB_WRITE_COMMITTED); + +- /* Custom width needs to be programmed to 0 for both the phy lanes */ +- intel_cx0_rmw(encoder, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CUSTOM_WIDTH, +- C10_VDR_CUSTOM_WIDTH_MASK, C10_VDR_CUSTOM_WIDTH_8_10, +- MB_WRITE_COMMITTED); +- intel_cx0_rmw(encoder, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1), +- 0, C10_VDR_CTRL_UPDATE_CFG, +- MB_WRITE_COMMITTED); +- + /* Program the pll values only for the master lane */ + for (i = 0; i < ARRAY_SIZE(pll_state->pll); i++) + intel_cx0_write(encoder, INTEL_CX0_LANE0, PHY_C10_VDR_PLL(i), +@@ -2101,6 +2093,10 @@ static void intel_c10_pll_program(struct drm_i915_private *i915, + intel_cx0_write(encoder, INTEL_CX0_LANE0, PHY_C10_VDR_CMN(0), pll_state->cmn, MB_WRITE_COMMITTED); + intel_cx0_write(encoder, INTEL_CX0_LANE0, PHY_C10_VDR_TX(0), pll_state->tx, MB_WRITE_COMMITTED); + ++ /* Custom width needs to be programmed to 0 for both the phy lanes */ ++ intel_cx0_rmw(encoder, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CUSTOM_WIDTH, ++ C10_VDR_CUSTOM_WIDTH_MASK, C10_VDR_CUSTOM_WIDTH_8_10, ++ MB_WRITE_COMMITTED); + intel_cx0_rmw(encoder, INTEL_CX0_LANE0, PHY_C10_VDR_CONTROL(1), + 0, C10_VDR_CTRL_MASTER_LANE | C10_VDR_CTRL_UPDATE_CFG, + MB_WRITE_COMMITTED); +-- +2.39.5 + diff --git a/queue-6.12/drm-i915-dg1-fix-power-gate-sequence.patch b/queue-6.12/drm-i915-dg1-fix-power-gate-sequence.patch new file mode 100644 index 00000000000..4af04cdc325 --- /dev/null +++ b/queue-6.12/drm-i915-dg1-fix-power-gate-sequence.patch @@ -0,0 +1,45 @@ +From aeb093bd409cba350f443d5df016e0f70979bc06 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Dec 2024 16:00:19 -0500 +Subject: drm/i915/dg1: Fix power gate sequence. + +From: Rodrigo Vivi + +[ Upstream commit 20e7c5313ffbf11c34a46395345677adbe890bee ] + +sub-pipe PG is not present on DG1. Setting these bits can disable +other power gates and cause GPU hangs on video playbacks. + +VLK: 16314, 4304 + +Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13381 +Fixes: 85a12d7eb8fe ("drm/i915/tgl: Fix Media power gate sequence.") +Cc: Vinay Belgaumkar +Cc: Himal Prasad Ghimiray +Reviewed-by: Vinay Belgaumkar +Reviewed-by: Himal Prasad Ghimiray +Link: https://patchwork.freedesktop.org/patch/msgid/20241219210019.70532-1-rodrigo.vivi@intel.com +Signed-off-by: Rodrigo Vivi +(cherry picked from commit de7061947b4ed4be857d452c60d5fb795831d79e) +Signed-off-by: Tvrtko Ursulin +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/gt/intel_rc6.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c +index c864d101faf9..9378d5901c49 100644 +--- a/drivers/gpu/drm/i915/gt/intel_rc6.c ++++ b/drivers/gpu/drm/i915/gt/intel_rc6.c +@@ -133,7 +133,7 @@ static void gen11_rc6_enable(struct intel_rc6 *rc6) + GEN9_MEDIA_PG_ENABLE | + GEN11_MEDIA_SAMPLER_PG_ENABLE; + +- if (GRAPHICS_VER(gt->i915) >= 12) { ++ if (GRAPHICS_VER(gt->i915) >= 12 && !IS_DG1(gt->i915)) { + for (i = 0; i < I915_MAX_VCS; i++) + if (HAS_ENGINE(gt, _VCS(i))) + pg_enable |= (VDN_HCP_POWERGATE_ENABLE(i) | +-- +2.39.5 + diff --git a/queue-6.12/drm-xe-fix-fault-on-fd-close-after-unbind.patch b/queue-6.12/drm-xe-fix-fault-on-fd-close-after-unbind.patch new file mode 100644 index 00000000000..b3eb897a291 --- /dev/null +++ b/queue-6.12/drm-xe-fix-fault-on-fd-close-after-unbind.patch @@ -0,0 +1,92 @@ +From a16dace81b83bdf6cf185f340f34d8586ff7759d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Dec 2024 21:31:21 -0800 +Subject: drm/xe: Fix fault on fd close after unbind +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lucas De Marchi + +[ Upstream commit fe39b222a4139354d32ff9d46b88757f63f71d63 ] + +If userspace holds an fd open, unbinds the device and then closes it, +the driver shouldn't try to access the hardware. Protect it by using +drm_dev_enter()/drm_dev_exit(). This fixes the following page fault: + +<6> [IGT] xe_wedged: exiting, ret=98 +<1> BUG: unable to handle page fault for address: ffffc901bc5e508c +<1> #PF: supervisor read access in kernel mode +<1> #PF: error_code(0x0000) - not-present page +... +<4> xe_lrc_update_timestamp+0x1c/0xd0 [xe] +<4> xe_exec_queue_update_run_ticks+0x50/0xb0 [xe] +<4> xe_exec_queue_fini+0x16/0xb0 [xe] +<4> __guc_exec_queue_fini_async+0xc4/0x190 [xe] +<4> guc_exec_queue_fini_async+0xa0/0xe0 [xe] +<4> guc_exec_queue_fini+0x23/0x40 [xe] +<4> xe_exec_queue_destroy+0xb3/0xf0 [xe] +<4> xe_file_close+0xd4/0x1a0 [xe] +<4> drm_file_free+0x210/0x280 [drm] +<4> drm_close_helper.isra.0+0x6d/0x80 [drm] +<4> drm_release_noglobal+0x20/0x90 [drm] + +Fixes: 514447a12190 ("drm/xe: Stop accumulating LRC timestamp on job_free") +Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/3421 +Reviewed-by: Umesh Nerlige Ramappa +Link: https://patchwork.freedesktop.org/patch/msgid/20241218053122.2730195-1-lucas.demarchi@intel.com +Signed-off-by: Lucas De Marchi +(cherry picked from commit 4ca1fd418338d4d135428a0eb1e16e3b3ce17ee8) +Signed-off-by: Thomas Hellström +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_exec_queue.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c +index fd0f3b3c9101..268cd3123be9 100644 +--- a/drivers/gpu/drm/xe/xe_exec_queue.c ++++ b/drivers/gpu/drm/xe/xe_exec_queue.c +@@ -8,6 +8,7 @@ + #include + + #include ++#include + #include + #include + +@@ -762,9 +763,11 @@ bool xe_exec_queue_is_idle(struct xe_exec_queue *q) + */ + void xe_exec_queue_update_run_ticks(struct xe_exec_queue *q) + { ++ struct xe_device *xe = gt_to_xe(q->gt); + struct xe_file *xef; + struct xe_lrc *lrc; + u32 old_ts, new_ts; ++ int idx; + + /* + * Jobs that are run during driver load may use an exec_queue, but are +@@ -774,6 +777,10 @@ void xe_exec_queue_update_run_ticks(struct xe_exec_queue *q) + if (!q->vm || !q->vm->xef) + return; + ++ /* Synchronize with unbind while holding the xe file open */ ++ if (!drm_dev_enter(&xe->drm, &idx)) ++ return; ++ + xef = q->vm->xef; + + /* +@@ -787,6 +794,8 @@ void xe_exec_queue_update_run_ticks(struct xe_exec_queue *q) + lrc = q->lrc[0]; + new_ts = xe_lrc_update_timestamp(lrc, &old_ts); + xef->run_ticks[q->class] += (new_ts - old_ts) * q->width; ++ ++ drm_dev_exit(idx); + } + + /** +-- +2.39.5 + diff --git a/queue-6.12/drm-xe-pf-use-correct-function-to-check-lmem-provisi.patch b/queue-6.12/drm-xe-pf-use-correct-function-to-check-lmem-provisi.patch new file mode 100644 index 00000000000..6125e75fdb4 --- /dev/null +++ b/queue-6.12/drm-xe-pf-use-correct-function-to-check-lmem-provisi.patch @@ -0,0 +1,43 @@ +From 441612961392df569870a3160afc7b698d9bb67a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Dec 2024 23:32:53 +0100 +Subject: drm/xe/pf: Use correct function to check LMEM provisioning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michal Wajdeczko + +[ Upstream commit af12ba67d09ebe2b31ab997cea1a930864028562 ] + +There is a typo in function call and instead of VF LMEM we were +looking at VF GGTT provisioning. Fix that. + +Fixes: 234670cea9a2 ("drm/xe/pf: Skip fair VFs provisioning if already provisioned") +Signed-off-by: Michal Wajdeczko +Cc: Piotr Piórkowski +Reviewed-by: Himal Prasad Ghimiray +Link: https://patchwork.freedesktop.org/patch/msgid/20241216223253.819-1-michal.wajdeczko@intel.com +(cherry picked from commit a8d0aa0e7fcd20c9f1992688c0f0d07a68287403) +Signed-off-by: Thomas Hellström +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c +index afdb477ecf83..c9ed996b9cb0 100644 +--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c ++++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c +@@ -2038,7 +2038,7 @@ static int pf_validate_vf_config(struct xe_gt *gt, unsigned int vfid) + valid_any = valid_any || (valid_ggtt && is_primary); + + if (IS_DGFX(xe)) { +- bool valid_lmem = pf_get_vf_config_ggtt(primary_gt, vfid); ++ bool valid_lmem = pf_get_vf_config_lmem(primary_gt, vfid); + + valid_any = valid_any || (valid_lmem && is_primary); + valid_all = valid_all && valid_lmem; +-- +2.39.5 + diff --git a/queue-6.12/drm-xe-revert-some-changes-that-break-a-mesa-debug-t.patch b/queue-6.12/drm-xe-revert-some-changes-that-break-a-mesa-debug-t.patch new file mode 100644 index 00000000000..5bd4b232dde --- /dev/null +++ b/queue-6.12/drm-xe-revert-some-changes-that-break-a-mesa-debug-t.patch @@ -0,0 +1,72 @@ +From 4884fcefa0aa86b38290432048544a945b1fbc7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Dec 2024 09:28:33 -0800 +Subject: drm/xe: Revert some changes that break a mesa debug tool +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: John Harrison + +[ Upstream commit a53da2fb25a31f4fb8eaeb93c7b1134fc14fd209 ] + +There is a mesa debug tool for decoding devcoredump files. Recent +changes to improve the devcoredump output broke that tool. So revert +the changes until the tool can be extended to support the new fields. + +Signed-off-by: John Harrison +Fixes: c28fd6c358db ("drm/xe/devcoredump: Improve section headings and add tile info") +Fixes: ec1455ce7e35 ("drm/xe/devcoredump: Add ASCII85 dump helper function") +Cc: John Harrison +Cc: Julia Filipchuk +Cc: Lucas De Marchi +Cc: Thomas Hellström +Cc: Rodrigo Vivi +Cc: intel-xe@lists.freedesktop.org +Reviewed-by: Jonathan Cavitt +Reviewed-by: José Roberto de Souza +Link: https://patchwork.freedesktop.org/patch/msgid/20241213172833.1733376-1-John.C.Harrison@Intel.com +Signed-off-by: Rodrigo Vivi +(cherry picked from commit 70fb86a85dc9fd66014d7eb2fe356f50702ceeb6) +Signed-off-by: Thomas Hellström +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_devcoredump.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c +index c18e463092af..85aa3ab0da3b 100644 +--- a/drivers/gpu/drm/xe/xe_devcoredump.c ++++ b/drivers/gpu/drm/xe/xe_devcoredump.c +@@ -104,7 +104,11 @@ static ssize_t __xe_devcoredump_read(char *buffer, size_t count, + drm_puts(&p, "\n**** GuC CT ****\n"); + xe_guc_ct_snapshot_print(ss->ct, &p); + +- drm_puts(&p, "\n**** Contexts ****\n"); ++ /* ++ * Don't add a new section header here because the mesa debug decoder ++ * tool expects the context information to be in the 'GuC CT' section. ++ */ ++ /* drm_puts(&p, "\n**** Contexts ****\n"); */ + xe_guc_exec_queue_snapshot_print(ss->ge, &p); + + drm_puts(&p, "\n**** Job ****\n"); +@@ -358,6 +362,15 @@ void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix, + char buff[ASCII85_BUFSZ], *line_buff; + size_t line_pos = 0; + ++ /* ++ * Splitting blobs across multiple lines is not compatible with the mesa ++ * debug decoder tool. Note that even dropping the explicit '\n' below ++ * doesn't help because the GuC log is so big some underlying implementation ++ * still splits the lines at 512K characters. So just bail completely for ++ * the moment. ++ */ ++ return; ++ + #define DMESG_MAX_LINE_LEN 800 + #define MIN_SPACE (ASCII85_BUFSZ + 2) /* 85 + "\n\0" */ + +-- +2.39.5 + diff --git a/queue-6.12/eth-bcmsysport-fix-call-balance-of-priv-clk-handling.patch b/queue-6.12/eth-bcmsysport-fix-call-balance-of-priv-clk-handling.patch new file mode 100644 index 00000000000..41cee754f14 --- /dev/null +++ b/queue-6.12/eth-bcmsysport-fix-call-balance-of-priv-clk-handling.patch @@ -0,0 +1,82 @@ +From 914e896a343faff9adb6c8aa4d8672f52375db56 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Dec 2024 15:30:07 +0300 +Subject: eth: bcmsysport: fix call balance of priv->clk handling routines + +From: Vitalii Mordan + +[ Upstream commit b255ef45fcc2141c1bf98456796abb956d843a27 ] + +Check the return value of clk_prepare_enable to ensure that priv->clk has +been successfully enabled. + +If priv->clk was not enabled during bcm_sysport_probe, bcm_sysport_resume, +or bcm_sysport_open, it must not be disabled in any subsequent execution +paths. + +Fixes: 31bc72d97656 ("net: systemport: fetch and use clock resources") +Signed-off-by: Vitalii Mordan +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20241227123007.2333397-1-mordan@ispras.ru +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bcmsysport.c | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c +index 0a68b526e4a8..2b784ced0645 100644 +--- a/drivers/net/ethernet/broadcom/bcmsysport.c ++++ b/drivers/net/ethernet/broadcom/bcmsysport.c +@@ -1967,7 +1967,11 @@ static int bcm_sysport_open(struct net_device *dev) + unsigned int i; + int ret; + +- clk_prepare_enable(priv->clk); ++ ret = clk_prepare_enable(priv->clk); ++ if (ret) { ++ netdev_err(dev, "could not enable priv clock\n"); ++ return ret; ++ } + + /* Reset UniMAC */ + umac_reset(priv); +@@ -2625,7 +2629,11 @@ static int bcm_sysport_probe(struct platform_device *pdev) + goto err_deregister_notifier; + } + +- clk_prepare_enable(priv->clk); ++ ret = clk_prepare_enable(priv->clk); ++ if (ret) { ++ dev_err(&pdev->dev, "could not enable priv clock\n"); ++ goto err_deregister_netdev; ++ } + + priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK; + dev_info(&pdev->dev, +@@ -2639,6 +2647,8 @@ static int bcm_sysport_probe(struct platform_device *pdev) + + return 0; + ++err_deregister_netdev: ++ unregister_netdev(dev); + err_deregister_notifier: + unregister_netdevice_notifier(&priv->netdev_notifier); + err_deregister_fixed_link: +@@ -2808,7 +2818,12 @@ static int __maybe_unused bcm_sysport_resume(struct device *d) + if (!netif_running(dev)) + return 0; + +- clk_prepare_enable(priv->clk); ++ ret = clk_prepare_enable(priv->clk); ++ if (ret) { ++ netdev_err(dev, "could not enable priv clock\n"); ++ return ret; ++ } ++ + if (priv->wolopts) + clk_disable_unprepare(priv->wol_clk); + +-- +2.39.5 + diff --git a/queue-6.12/ila-serialize-calls-to-nf_register_net_hooks.patch b/queue-6.12/ila-serialize-calls-to-nf_register_net_hooks.patch new file mode 100644 index 00000000000..34f6357e9c8 --- /dev/null +++ b/queue-6.12/ila-serialize-calls-to-nf_register_net_hooks.patch @@ -0,0 +1,113 @@ +From 69da1e85447e96fbdf74de7d25eba1cfdfd3681a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Dec 2024 16:28:49 +0000 +Subject: ila: serialize calls to nf_register_net_hooks() + +From: Eric Dumazet + +[ Upstream commit 260466b576bca0081a7d4acecc8e93687aa22d0e ] + +syzbot found a race in ila_add_mapping() [1] + +commit 031ae72825ce ("ila: call nf_unregister_net_hooks() sooner") +attempted to fix a similar issue. + +Looking at the syzbot repro, we have concurrent ILA_CMD_ADD commands. + +Add a mutex to make sure at most one thread is calling nf_register_net_hooks(). + +[1] + BUG: KASAN: slab-use-after-free in rht_key_hashfn include/linux/rhashtable.h:159 [inline] + BUG: KASAN: slab-use-after-free in __rhashtable_lookup.constprop.0+0x426/0x550 include/linux/rhashtable.h:604 +Read of size 4 at addr ffff888028f40008 by task dhcpcd/5501 + +CPU: 1 UID: 0 PID: 5501 Comm: dhcpcd Not tainted 6.13.0-rc4-syzkaller-00054-gd6ef8b40d075 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 +Call Trace: + + __dump_stack lib/dump_stack.c:94 [inline] + dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120 + print_address_description mm/kasan/report.c:378 [inline] + print_report+0xc3/0x620 mm/kasan/report.c:489 + kasan_report+0xd9/0x110 mm/kasan/report.c:602 + rht_key_hashfn include/linux/rhashtable.h:159 [inline] + __rhashtable_lookup.constprop.0+0x426/0x550 include/linux/rhashtable.h:604 + rhashtable_lookup include/linux/rhashtable.h:646 [inline] + rhashtable_lookup_fast include/linux/rhashtable.h:672 [inline] + ila_lookup_wildcards net/ipv6/ila/ila_xlat.c:127 [inline] + ila_xlat_addr net/ipv6/ila/ila_xlat.c:652 [inline] + ila_nf_input+0x1ee/0x620 net/ipv6/ila/ila_xlat.c:185 + nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline] + nf_hook_slow+0xbb/0x200 net/netfilter/core.c:626 + nf_hook.constprop.0+0x42e/0x750 include/linux/netfilter.h:269 + NF_HOOK include/linux/netfilter.h:312 [inline] + ipv6_rcv+0xa4/0x680 net/ipv6/ip6_input.c:309 + __netif_receive_skb_one_core+0x12e/0x1e0 net/core/dev.c:5672 + __netif_receive_skb+0x1d/0x160 net/core/dev.c:5785 + process_backlog+0x443/0x15f0 net/core/dev.c:6117 + __napi_poll.constprop.0+0xb7/0x550 net/core/dev.c:6883 + napi_poll net/core/dev.c:6952 [inline] + net_rx_action+0xa94/0x1010 net/core/dev.c:7074 + handle_softirqs+0x213/0x8f0 kernel/softirq.c:561 + __do_softirq kernel/softirq.c:595 [inline] + invoke_softirq kernel/softirq.c:435 [inline] + __irq_exit_rcu+0x109/0x170 kernel/softirq.c:662 + irq_exit_rcu+0x9/0x30 kernel/softirq.c:678 + instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1049 [inline] + sysvec_apic_timer_interrupt+0xa4/0xc0 arch/x86/kernel/apic/apic.c:1049 + +Fixes: 7f00feaf1076 ("ila: Add generic ILA translation facility") +Reported-by: syzbot+47e761d22ecf745f72b9@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/6772c9ae.050a0220.2f3838.04c7.GAE@google.com/T/#u +Signed-off-by: Eric Dumazet +Cc: Florian Westphal +Cc: Tom Herbert +Link: https://patch.msgid.link/20241230162849.2795486-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/ila/ila_xlat.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c +index 534a4498e280..fff09f5a796a 100644 +--- a/net/ipv6/ila/ila_xlat.c ++++ b/net/ipv6/ila/ila_xlat.c +@@ -200,6 +200,8 @@ static const struct nf_hook_ops ila_nf_hook_ops[] = { + }, + }; + ++static DEFINE_MUTEX(ila_mutex); ++ + static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp) + { + struct ila_net *ilan = net_generic(net, ila_net_id); +@@ -207,16 +209,20 @@ static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp) + spinlock_t *lock = ila_get_lock(ilan, xp->ip.locator_match); + int err = 0, order; + +- if (!ilan->xlat.hooks_registered) { ++ if (!READ_ONCE(ilan->xlat.hooks_registered)) { + /* We defer registering net hooks in the namespace until the + * first mapping is added. + */ +- err = nf_register_net_hooks(net, ila_nf_hook_ops, +- ARRAY_SIZE(ila_nf_hook_ops)); ++ mutex_lock(&ila_mutex); ++ if (!ilan->xlat.hooks_registered) { ++ err = nf_register_net_hooks(net, ila_nf_hook_ops, ++ ARRAY_SIZE(ila_nf_hook_ops)); ++ if (!err) ++ WRITE_ONCE(ilan->xlat.hooks_registered, true); ++ } ++ mutex_unlock(&ila_mutex); + if (err) + return err; +- +- ilan->xlat.hooks_registered = true; + } + + ila = kzalloc(sizeof(*ila), GFP_KERNEL); +-- +2.39.5 + diff --git a/queue-6.12/io_uring-net-always-initialize-kmsg-msg.msg_inq-upfr.patch b/queue-6.12/io_uring-net-always-initialize-kmsg-msg.msg_inq-upfr.patch new file mode 100644 index 00000000000..9855f741ffb --- /dev/null +++ b/queue-6.12/io_uring-net-always-initialize-kmsg-msg.msg_inq-upfr.patch @@ -0,0 +1,66 @@ +From d6f148858b3a93e8df54ec2998f4691033965770 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Jan 2025 16:32:51 -0700 +Subject: io_uring/net: always initialize kmsg->msg.msg_inq upfront + +From: Jens Axboe + +[ Upstream commit c6e60a0a68b7e6b3c7e33863a16e8e88ba9eee6f ] + +syzbot reports that ->msg_inq may get used uinitialized from the +following path: + +BUG: KMSAN: uninit-value in io_recv_buf_select io_uring/net.c:1094 [inline] +BUG: KMSAN: uninit-value in io_recv+0x930/0x1f90 io_uring/net.c:1158 + io_recv_buf_select io_uring/net.c:1094 [inline] + io_recv+0x930/0x1f90 io_uring/net.c:1158 + io_issue_sqe+0x420/0x2130 io_uring/io_uring.c:1740 + io_queue_sqe io_uring/io_uring.c:1950 [inline] + io_req_task_submit+0xfa/0x1d0 io_uring/io_uring.c:1374 + io_handle_tw_list+0x55f/0x5c0 io_uring/io_uring.c:1057 + tctx_task_work_run+0x109/0x3e0 io_uring/io_uring.c:1121 + tctx_task_work+0x6d/0xc0 io_uring/io_uring.c:1139 + task_work_run+0x268/0x310 kernel/task_work.c:239 + io_run_task_work+0x43a/0x4a0 io_uring/io_uring.h:343 + io_cqring_wait io_uring/io_uring.c:2527 [inline] + __do_sys_io_uring_enter io_uring/io_uring.c:3439 [inline] + __se_sys_io_uring_enter+0x204f/0x4ce0 io_uring/io_uring.c:3330 + __x64_sys_io_uring_enter+0x11f/0x1a0 io_uring/io_uring.c:3330 + x64_sys_call+0xce5/0x3c30 arch/x86/include/generated/asm/syscalls_64.h:427 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +and it is correct, as it's never initialized upfront. Hence the first +submission can end up using it uninitialized, if the recv wasn't +successful and the networking stack didn't honor ->msg_get_inq being set +and filling in the output value of ->msg_inq as requested. + +Set it to 0 upfront when it's allocated, just to silence this KMSAN +warning. There's no side effect of using it uninitialized, it'll just +potentially cause the next receive to use a recv value hint that's not +accurate. + +Fixes: c6f32c7d9e09 ("io_uring/net: get rid of ->prep_async() for receive side") +Reported-by: syzbot+068ff190354d2f74892f@syzkaller.appspotmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/net.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/io_uring/net.c b/io_uring/net.c +index 18507658a921..7f549be9abd1 100644 +--- a/io_uring/net.c ++++ b/io_uring/net.c +@@ -748,6 +748,7 @@ static int io_recvmsg_prep_setup(struct io_kiocb *req) + if (req->opcode == IORING_OP_RECV) { + kmsg->msg.msg_name = NULL; + kmsg->msg.msg_namelen = 0; ++ kmsg->msg.msg_inq = 0; + kmsg->msg.msg_control = NULL; + kmsg->msg.msg_get_inq = 1; + kmsg->msg.msg_controllen = 0; +-- +2.39.5 + diff --git a/queue-6.12/net-dsa-microchip-fix-ksz9477-set_ageing_time-functi.patch b/queue-6.12/net-dsa-microchip-fix-ksz9477-set_ageing_time-functi.patch new file mode 100644 index 00000000000..fa5ea34f74b --- /dev/null +++ b/queue-6.12/net-dsa-microchip-fix-ksz9477-set_ageing_time-functi.patch @@ -0,0 +1,125 @@ +From b167ce9c565bf33ca6de5d1f275b6a7d7f7a4fd2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Dec 2024 18:02:23 -0800 +Subject: net: dsa: microchip: Fix KSZ9477 set_ageing_time function + +From: Tristram Ha + +[ Upstream commit 262bfba8ab820641c8cfbbf03b86d6c00242c078 ] + +The aging count is not a simple 11-bit value but comprises a 3-bit +multiplier and an 8-bit second count. The code tries to use the +original multiplier which is 4 as the second count is still 300 seconds +by default. + +Fixes: 2c119d9982b1 ("net: dsa: microchip: add the support for set_ageing_time") +Signed-off-by: Tristram Ha +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20241218020224.70590-2-Tristram.Ha@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/microchip/ksz9477.c | 47 +++++++++++++++++++------ + drivers/net/dsa/microchip/ksz9477_reg.h | 4 +-- + 2 files changed, 37 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c +index 0ba658a72d8f..22556d339d6e 100644 +--- a/drivers/net/dsa/microchip/ksz9477.c ++++ b/drivers/net/dsa/microchip/ksz9477.c +@@ -2,7 +2,7 @@ + /* + * Microchip KSZ9477 switch driver main logic + * +- * Copyright (C) 2017-2019 Microchip Technology Inc. ++ * Copyright (C) 2017-2024 Microchip Technology Inc. + */ + + #include +@@ -983,26 +983,51 @@ void ksz9477_get_caps(struct ksz_device *dev, int port, + int ksz9477_set_ageing_time(struct ksz_device *dev, unsigned int msecs) + { + u32 secs = msecs / 1000; +- u8 value; +- u8 data; ++ u8 data, mult, value; ++ u32 max_val; + int ret; + +- value = FIELD_GET(SW_AGE_PERIOD_7_0_M, secs); ++#define MAX_TIMER_VAL ((1 << 8) - 1) + +- ret = ksz_write8(dev, REG_SW_LUE_CTRL_3, value); +- if (ret < 0) +- return ret; ++ /* The aging timer comprises a 3-bit multiplier and an 8-bit second ++ * value. Either of them cannot be zero. The maximum timer is then ++ * 7 * 255 = 1785 seconds. ++ */ ++ if (!secs) ++ secs = 1; + +- data = FIELD_GET(SW_AGE_PERIOD_10_8_M, secs); ++ /* Return error if too large. */ ++ else if (secs > 7 * MAX_TIMER_VAL) ++ return -EINVAL; + + ret = ksz_read8(dev, REG_SW_LUE_CTRL_0, &value); + if (ret < 0) + return ret; + +- value &= ~SW_AGE_CNT_M; +- value |= FIELD_PREP(SW_AGE_CNT_M, data); ++ /* Check whether there is need to update the multiplier. */ ++ mult = FIELD_GET(SW_AGE_CNT_M, value); ++ max_val = MAX_TIMER_VAL; ++ if (mult > 0) { ++ /* Try to use the same multiplier already in the register as ++ * the hardware default uses multiplier 4 and 75 seconds for ++ * 300 seconds. ++ */ ++ max_val = DIV_ROUND_UP(secs, mult); ++ if (max_val > MAX_TIMER_VAL || max_val * mult != secs) ++ max_val = MAX_TIMER_VAL; ++ } ++ ++ data = DIV_ROUND_UP(secs, max_val); ++ if (mult != data) { ++ value &= ~SW_AGE_CNT_M; ++ value |= FIELD_PREP(SW_AGE_CNT_M, data); ++ ret = ksz_write8(dev, REG_SW_LUE_CTRL_0, value); ++ if (ret < 0) ++ return ret; ++ } + +- return ksz_write8(dev, REG_SW_LUE_CTRL_0, value); ++ value = DIV_ROUND_UP(secs, data); ++ return ksz_write8(dev, REG_SW_LUE_CTRL_3, value); + } + + void ksz9477_port_queue_split(struct ksz_device *dev, int port) +diff --git a/drivers/net/dsa/microchip/ksz9477_reg.h b/drivers/net/dsa/microchip/ksz9477_reg.h +index 04235c22bf40..ff579920078e 100644 +--- a/drivers/net/dsa/microchip/ksz9477_reg.h ++++ b/drivers/net/dsa/microchip/ksz9477_reg.h +@@ -2,7 +2,7 @@ + /* + * Microchip KSZ9477 register definitions + * +- * Copyright (C) 2017-2018 Microchip Technology Inc. ++ * Copyright (C) 2017-2024 Microchip Technology Inc. + */ + + #ifndef __KSZ9477_REGS_H +@@ -165,8 +165,6 @@ + #define SW_VLAN_ENABLE BIT(7) + #define SW_DROP_INVALID_VID BIT(6) + #define SW_AGE_CNT_M GENMASK(5, 3) +-#define SW_AGE_CNT_S 3 +-#define SW_AGE_PERIOD_10_8_M GENMASK(10, 8) + #define SW_RESV_MCAST_ENABLE BIT(2) + #define SW_HASH_OPTION_M 0x03 + #define SW_HASH_OPTION_CRC 1 +-- +2.39.5 + diff --git a/queue-6.12/net-dsa-microchip-fix-lan937x-set_ageing_time-functi.patch b/queue-6.12/net-dsa-microchip-fix-lan937x-set_ageing_time-functi.patch new file mode 100644 index 00000000000..1d8b183b871 --- /dev/null +++ b/queue-6.12/net-dsa-microchip-fix-lan937x-set_ageing_time-functi.patch @@ -0,0 +1,145 @@ +From d3d093e1b07c57eaabda722e5581844a11160957 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Dec 2024 18:02:24 -0800 +Subject: net: dsa: microchip: Fix LAN937X set_ageing_time function + +From: Tristram Ha + +[ Upstream commit bb9869043438af5b94230f94fb4c39206525d758 ] + +The aging count is not a simple 20-bit value but comprises a 3-bit +multiplier and a 20-bit second time. The code tries to use the +original multiplier which is 4 as the second count is still 300 seconds +by default. + +As the 20-bit number is now too large for practical use there is an option +to interpret it as microseconds instead of seconds. + +Fixes: 2c119d9982b1 ("net: dsa: microchip: add the support for set_ageing_time") +Signed-off-by: Tristram Ha +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20241218020224.70590-3-Tristram.Ha@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/microchip/lan937x_main.c | 62 ++++++++++++++++++++++-- + drivers/net/dsa/microchip/lan937x_reg.h | 9 ++-- + 2 files changed, 65 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c +index 824d9309a3d3..7fe127a075de 100644 +--- a/drivers/net/dsa/microchip/lan937x_main.c ++++ b/drivers/net/dsa/microchip/lan937x_main.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Microchip LAN937X switch driver main logic +- * Copyright (C) 2019-2022 Microchip Technology Inc. ++ * Copyright (C) 2019-2024 Microchip Technology Inc. + */ + #include + #include +@@ -260,10 +260,66 @@ int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu) + + int lan937x_set_ageing_time(struct ksz_device *dev, unsigned int msecs) + { +- u32 secs = msecs / 1000; +- u32 value; ++ u8 data, mult, value8; ++ bool in_msec = false; ++ u32 max_val, value; ++ u32 secs = msecs; + int ret; + ++#define MAX_TIMER_VAL ((1 << 20) - 1) ++ ++ /* The aging timer comprises a 3-bit multiplier and a 20-bit second ++ * value. Either of them cannot be zero. The maximum timer is then ++ * 7 * 1048575 = 7340025 seconds. As this value is too large for ++ * practical use it can be interpreted as microseconds, making the ++ * maximum timer 7340 seconds with finer control. This allows for ++ * maximum 122 minutes compared to 29 minutes in KSZ9477 switch. ++ */ ++ if (msecs % 1000) ++ in_msec = true; ++ else ++ secs /= 1000; ++ if (!secs) ++ secs = 1; ++ ++ /* Return error if too large. */ ++ else if (secs > 7 * MAX_TIMER_VAL) ++ return -EINVAL; ++ ++ /* Configure how to interpret the number value. */ ++ ret = ksz_rmw8(dev, REG_SW_LUE_CTRL_2, SW_AGE_CNT_IN_MICROSEC, ++ in_msec ? SW_AGE_CNT_IN_MICROSEC : 0); ++ if (ret < 0) ++ return ret; ++ ++ ret = ksz_read8(dev, REG_SW_LUE_CTRL_0, &value8); ++ if (ret < 0) ++ return ret; ++ ++ /* Check whether there is need to update the multiplier. */ ++ mult = FIELD_GET(SW_AGE_CNT_M, value8); ++ max_val = MAX_TIMER_VAL; ++ if (mult > 0) { ++ /* Try to use the same multiplier already in the register as ++ * the hardware default uses multiplier 4 and 75 seconds for ++ * 300 seconds. ++ */ ++ max_val = DIV_ROUND_UP(secs, mult); ++ if (max_val > MAX_TIMER_VAL || max_val * mult != secs) ++ max_val = MAX_TIMER_VAL; ++ } ++ ++ data = DIV_ROUND_UP(secs, max_val); ++ if (mult != data) { ++ value8 &= ~SW_AGE_CNT_M; ++ value8 |= FIELD_PREP(SW_AGE_CNT_M, data); ++ ret = ksz_write8(dev, REG_SW_LUE_CTRL_0, value8); ++ if (ret < 0) ++ return ret; ++ } ++ ++ secs = DIV_ROUND_UP(secs, data); ++ + value = FIELD_GET(SW_AGE_PERIOD_7_0_M, secs); + + ret = ksz_write8(dev, REG_SW_AGE_PERIOD__1, value); +diff --git a/drivers/net/dsa/microchip/lan937x_reg.h b/drivers/net/dsa/microchip/lan937x_reg.h +index 2f22a9d01de3..35269f74a314 100644 +--- a/drivers/net/dsa/microchip/lan937x_reg.h ++++ b/drivers/net/dsa/microchip/lan937x_reg.h +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0 */ + /* Microchip LAN937X switch register definitions +- * Copyright (C) 2019-2021 Microchip Technology Inc. ++ * Copyright (C) 2019-2024 Microchip Technology Inc. + */ + #ifndef __LAN937X_REG_H + #define __LAN937X_REG_H +@@ -52,8 +52,7 @@ + + #define SW_VLAN_ENABLE BIT(7) + #define SW_DROP_INVALID_VID BIT(6) +-#define SW_AGE_CNT_M 0x7 +-#define SW_AGE_CNT_S 3 ++#define SW_AGE_CNT_M GENMASK(5, 3) + #define SW_RESV_MCAST_ENABLE BIT(2) + + #define REG_SW_LUE_CTRL_1 0x0311 +@@ -66,6 +65,10 @@ + #define SW_FAST_AGING BIT(1) + #define SW_LINK_AUTO_AGING BIT(0) + ++#define REG_SW_LUE_CTRL_2 0x0312 ++ ++#define SW_AGE_CNT_IN_MICROSEC BIT(7) ++ + #define REG_SW_AGE_PERIOD__1 0x0313 + #define SW_AGE_PERIOD_7_0_M GENMASK(7, 0) + +-- +2.39.5 + diff --git a/queue-6.12/net-fix-memory-leak-in-tcp_conn_request.patch b/queue-6.12/net-fix-memory-leak-in-tcp_conn_request.patch new file mode 100644 index 00000000000..e6420ff1d93 --- /dev/null +++ b/queue-6.12/net-fix-memory-leak-in-tcp_conn_request.patch @@ -0,0 +1,64 @@ +From 22c3f0c77fd5691a30ae2a15166d2d39ea67464d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Dec 2024 15:28:59 +0800 +Subject: net: fix memory leak in tcp_conn_request() + +From: Wang Liang + +[ Upstream commit 4f4aa4aa28142d53f8b06585c478476cfe325cfc ] + +If inet_csk_reqsk_queue_hash_add() return false, tcp_conn_request() will +return without free the dst memory, which allocated in af_ops->route_req. + +Here is the kmemleak stack: + +unreferenced object 0xffff8881198631c0 (size 240): + comm "softirq", pid 0, jiffies 4299266571 (age 1802.392s) + hex dump (first 32 bytes): + 00 10 9b 03 81 88 ff ff 80 98 da bc ff ff ff ff ................ + 81 55 18 bb ff ff ff ff 00 00 00 00 00 00 00 00 .U.............. + backtrace: + [] kmem_cache_alloc+0x60c/0xa80 + [] dst_alloc+0x55/0x250 + [] rt_dst_alloc+0x46/0x1d0 + [] __mkroute_output+0x29a/0xa50 + [] ip_route_output_key_hash+0x10b/0x240 + [] ip_route_output_flow+0x1d/0x90 + [] inet_csk_route_req+0x2c5/0x500 + [] tcp_conn_request+0x691/0x12c0 + [] tcp_rcv_state_process+0x3c8/0x11b0 + [] tcp_v4_do_rcv+0x156/0x3b0 + [] tcp_v4_rcv+0x1cf8/0x1d80 + [] ip_protocol_deliver_rcu+0xf6/0x360 + [] ip_local_deliver_finish+0xe6/0x1e0 + [] ip_local_deliver+0xee/0x360 + [] ip_rcv+0xad/0x2f0 + [] __netif_receive_skb_one_core+0x123/0x140 + +Call dst_release() to free the dst memory when +inet_csk_reqsk_queue_hash_add() return false in tcp_conn_request(). + +Fixes: ff46e3b44219 ("Fix race for duplicate reqsk on identical SYN") +Signed-off-by: Wang Liang +Link: https://patch.msgid.link/20241219072859.3783576-1-wangliang74@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp_input.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 2d844e1f867f..2d43b29da15e 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -7328,6 +7328,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, + if (unlikely(!inet_csk_reqsk_queue_hash_add(sk, req, + req->timeout))) { + reqsk_free(req); ++ dst_release(dst); + return 0; + } + +-- +2.39.5 + diff --git a/queue-6.12/net-fix-netns-for-ip_tunnel_init_flow.patch b/queue-6.12/net-fix-netns-for-ip_tunnel_init_flow.patch new file mode 100644 index 00000000000..f59aaef0b05 --- /dev/null +++ b/queue-6.12/net-fix-netns-for-ip_tunnel_init_flow.patch @@ -0,0 +1,71 @@ +From 3bb1a0244edbfe588bd6f689587fd8d620deb2ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Dec 2024 21:03:36 +0800 +Subject: net: Fix netns for ip_tunnel_init_flow() + +From: Xiao Liang + +[ Upstream commit b5a7b661a073727219fedc35f5619f62418ffe72 ] + +The device denoted by tunnel->parms.link resides in the underlay net +namespace. Therefore pass tunnel->net to ip_tunnel_init_flow(). + +Fixes: db53cd3d88dc ("net: Handle l3mdev in ip_tunnel_init_flow") +Signed-off-by: Xiao Liang +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20241219130336.103839-1-shaw.leon@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c | 3 +-- + net/ipv4/ip_tunnel.c | 6 +++--- + 2 files changed, 4 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c +index 4b5fd71c897d..32d2e61f2b82 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c +@@ -423,8 +423,7 @@ mlxsw_sp_span_gretap4_route(const struct net_device *to_dev, + + parms = mlxsw_sp_ipip_netdev_parms4(to_dev); + ip_tunnel_init_flow(&fl4, parms.iph.protocol, *daddrp, *saddrp, +- 0, 0, dev_net(to_dev), parms.link, tun->fwmark, 0, +- 0); ++ 0, 0, tun->net, parms.link, tun->fwmark, 0, 0); + + rt = ip_route_output_key(tun->net, &fl4); + if (IS_ERR(rt)) +diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c +index 25505f9b724c..09b73acf037a 100644 +--- a/net/ipv4/ip_tunnel.c ++++ b/net/ipv4/ip_tunnel.c +@@ -294,7 +294,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev) + + ip_tunnel_init_flow(&fl4, iph->protocol, iph->daddr, + iph->saddr, tunnel->parms.o_key, +- iph->tos & INET_DSCP_MASK, dev_net(dev), ++ iph->tos & INET_DSCP_MASK, tunnel->net, + tunnel->parms.link, tunnel->fwmark, 0, 0); + rt = ip_route_output_key(tunnel->net, &fl4); + +@@ -611,7 +611,7 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, + } + ip_tunnel_init_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src, + tunnel_id_to_key32(key->tun_id), +- tos & INET_DSCP_MASK, dev_net(dev), 0, skb->mark, ++ tos & INET_DSCP_MASK, tunnel->net, 0, skb->mark, + skb_get_hash(skb), key->flow_flags); + + if (!tunnel_hlen) +@@ -774,7 +774,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, + + ip_tunnel_init_flow(&fl4, protocol, dst, tnl_params->saddr, + tunnel->parms.o_key, tos & INET_DSCP_MASK, +- dev_net(dev), READ_ONCE(tunnel->parms.link), ++ tunnel->net, READ_ONCE(tunnel->parms.link), + tunnel->fwmark, skb_get_hash(skb), 0); + + if (ip_tunnel_encap(skb, &tunnel->encap, &protocol, &fl4) < 0) +-- +2.39.5 + diff --git a/queue-6.12/net-llc-reset-skb-transport_header.patch b/queue-6.12/net-llc-reset-skb-transport_header.patch new file mode 100644 index 00000000000..24ba6723ae8 --- /dev/null +++ b/queue-6.12/net-llc-reset-skb-transport_header.patch @@ -0,0 +1,62 @@ +From adcfc807df426376d9e54fbd538d95fc7792be78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Dec 2024 20:07:20 -0500 +Subject: net: llc: reset skb->transport_header + +From: Antonio Pastor + +[ Upstream commit a024e377efed31ecfb39210bed562932321345b3 ] + +802.2+LLC+SNAP frames received by napi_complete_done with GRO and DSA +have skb->transport_header set two bytes short, or pointing 2 bytes +before network_header & skb->data. As snap_rcv expects transport_header +to point to SNAP header (OID:PID) after LLC processing advances offset +over LLC header (llc_rcv & llc_fixup_skb), code doesn't find a match +and packet is dropped. + +Between napi_complete_done and snap_rcv, transport_header is not used +until __netif_receive_skb_core, where originally it was being reset. +Commit fda55eca5a33 ("net: introduce skb_transport_header_was_set()") +only does so if not set, on the assumption the value was set correctly +by GRO (and also on assumption that "network stacks usually reset the +transport header anyway"). Afterwards it is moved forward by +llc_fixup_skb. + +Locally generated traffic shows up at __netif_receive_skb_core with no +transport_header set and is processed without issue. On a setup with +GRO but no DSA, transport_header and network_header are both set to +point to skb->data which is also correct. + +As issue is LLC specific, to avoid impacting non-LLC traffic, and to +follow up on original assumption made on previous code change, +llc_fixup_skb to reset the offset after skb pull. llc_fixup_skb +assumes the LLC header is at skb->data, and by definition SNAP header +immediately follows. + +Fixes: fda55eca5a33 ("net: introduce skb_transport_header_was_set()") +Signed-off-by: Antonio Pastor +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20241225010723.2830290-1-antonio.pastor@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/llc/llc_input.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c +index 51bccfb00a9c..61b0159b2fbe 100644 +--- a/net/llc/llc_input.c ++++ b/net/llc/llc_input.c +@@ -124,8 +124,8 @@ static inline int llc_fixup_skb(struct sk_buff *skb) + if (unlikely(!pskb_may_pull(skb, llc_len))) + return 0; + +- skb->transport_header += llc_len; + skb_pull(skb, llc_len); ++ skb_reset_transport_header(skb); + if (skb->protocol == htons(ETH_P_802_2)) { + __be16 pdulen; + s32 data_size; +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5-dr-select-msix-vector-0-for-completion-queu.patch b/queue-6.12/net-mlx5-dr-select-msix-vector-0-for-completion-queu.patch new file mode 100644 index 00000000000..183e0a501a7 --- /dev/null +++ b/queue-6.12/net-mlx5-dr-select-msix-vector-0-for-completion-queu.patch @@ -0,0 +1,58 @@ +From 1ea8218ea5934ee798c0ead7e25f40b1990bfe79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Dec 2024 10:15:02 +0200 +Subject: net/mlx5: DR, select MSIX vector 0 for completion queue creation + +From: Shahar Shitrit + +[ Upstream commit 050a4c011b0dfeb91664a5d7bd3647ff38db08ce ] + +When creating a software steering completion queue (CQ), an arbitrary +MSIX vector n is selected. This results in the CQ sharing the same +Ethernet traffic channel n associated with the chosen vector. However, +the value of n is often unpredictable, which can introduce complications +for interrupt monitoring and verification tools. + +Moreover, SW steering uses polling rather than event-driven interrupts. +Therefore, there is no need to select any MSIX vector other than the +existing vector 0 for CQ creation. + +In light of these factors, and to enhance predictability, we modify the +code to consistently select MSIX vector 0 for CQ creation. + +Fixes: 297cccebdc5a ("net/mlx5: DR, Expose an internal API to issue RDMA operations") +Signed-off-by: Shahar Shitrit +Reviewed-by: Yevgeny Kliteynik +Signed-off-by: Tariq Toukan +Link: https://patch.msgid.link/20241220081505.1286093-2-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c +index 6fa06ba2d346..f57c84e5128b 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c +@@ -1067,7 +1067,6 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, + int inlen, err, eqn; + void *cqc, *in; + __be64 *pas; +- int vector; + u32 i; + + cq = kzalloc(sizeof(*cq), GFP_KERNEL); +@@ -1096,8 +1095,7 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, + if (!in) + goto err_cqwq; + +- vector = raw_smp_processor_id() % mlx5_comp_vectors_max(mdev); +- err = mlx5_comp_eqn_get(mdev, vector, &eqn); ++ err = mlx5_comp_eqn_get(mdev, 0, &eqn); + if (err) { + kvfree(in); + goto err_cqwq; +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5e-keep-netdev-when-leave-switchdev-for-devli.patch b/queue-6.12/net-mlx5e-keep-netdev-when-leave-switchdev-for-devli.patch new file mode 100644 index 00000000000..75822ff8b4a --- /dev/null +++ b/queue-6.12/net-mlx5e-keep-netdev-when-leave-switchdev-for-devli.patch @@ -0,0 +1,131 @@ +From c8325cc94ab4d199518ae84171a717aff4481a17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Dec 2024 10:15:05 +0200 +Subject: net/mlx5e: Keep netdev when leave switchdev for devlink set legacy + only + +From: Jianbo Liu + +[ Upstream commit 2a4f56fbcc473d8faeb29b73082df39efbe5893c ] + +In the cited commit, when changing from switchdev to legacy mode, +uplink representor's netdev is kept, and its profile is replaced with +nic profile, so netdev is detached from old profile, then attach to +new profile. + +During profile change, the hardware resources allocated by the old +profile will be cleaned up. However, the cleanup is relying on the +related kernel modules. And they may need to flush themselves first, +which is triggered by netdev events, for example, NETDEV_UNREGISTER. +However, netdev is kept, or netdev_register is called after the +cleanup, which may cause troubles because the resources are still +referred by kernel modules. + +The same process applies to all the caes when uplink is leaving +switchdev mode, including devlink eswitch mode set legacy, driver +unload and devlink reload. For the first one, it can be blocked and +returns failure to users, whenever possible. But it's hard for the +others. Besides, the attachment to nic profile is unnecessary as the +netdev will be unregistered anyway for such cases. + +So in this patch, the original behavior is kept only for devlink +eswitch set mode legacy. For the others, moves netdev unregistration +before the profile change. + +Fixes: 7a9fb35e8c3a ("net/mlx5e: Do not reload ethernet ports when changing eswitch mode") +Signed-off-by: Jianbo Liu +Signed-off-by: Tariq Toukan +Link: https://patch.msgid.link/20241220081505.1286093-5-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/en_main.c | 19 +++++++++++++++++-- + .../net/ethernet/mellanox/mlx5/core/en_rep.c | 15 +++++++++++++++ + .../mellanox/mlx5/core/eswitch_offloads.c | 2 ++ + include/linux/mlx5/driver.h | 1 + + 4 files changed, 35 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index c14bef83d84d..62b8a7c1c6b5 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -6510,8 +6510,23 @@ static void _mlx5e_remove(struct auxiliary_device *adev) + + mlx5_core_uplink_netdev_set(mdev, NULL); + mlx5e_dcbnl_delete_app(priv); +- unregister_netdev(priv->netdev); +- _mlx5e_suspend(adev, false); ++ /* When unload driver, the netdev is in registered state ++ * if it's from legacy mode. If from switchdev mode, it ++ * is already unregistered before changing to NIC profile. ++ */ ++ if (priv->netdev->reg_state == NETREG_REGISTERED) { ++ unregister_netdev(priv->netdev); ++ _mlx5e_suspend(adev, false); ++ } else { ++ struct mlx5_core_dev *pos; ++ int i; ++ ++ if (test_bit(MLX5E_STATE_DESTROYING, &priv->state)) ++ mlx5_sd_for_each_dev(i, mdev, pos) ++ mlx5e_destroy_mdev_resources(pos); ++ else ++ _mlx5e_suspend(adev, true); ++ } + /* Avoid cleanup if profile rollback failed. */ + if (priv->profile) + priv->profile->cleanup(priv); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +index 92094bf60d59..0657d1076535 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +@@ -1508,6 +1508,21 @@ mlx5e_vport_uplink_rep_unload(struct mlx5e_rep_priv *rpriv) + + priv = netdev_priv(netdev); + ++ /* This bit is set when using devlink to change eswitch mode from ++ * switchdev to legacy. As need to keep uplink netdev ifindex, we ++ * detach uplink representor profile and attach NIC profile only. ++ * The netdev will be unregistered later when unload NIC auxiliary ++ * driver for this case. ++ * We explicitly block devlink eswitch mode change if any IPSec rules ++ * offloaded, but can't block other cases, such as driver unload ++ * and devlink reload. We have to unregister netdev before profile ++ * change for those cases. This is to avoid resource leak because ++ * the offloaded rules don't have the chance to be unoffloaded before ++ * cleanup which is triggered by detach uplink representor profile. ++ */ ++ if (!(priv->mdev->priv.flags & MLX5_PRIV_FLAGS_SWITCH_LEGACY)) ++ unregister_netdev(netdev); ++ + mlx5e_netdev_attach_nic_profile(priv); + } + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +index 3cf695425f0a..3950b1d4b3d8 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +@@ -3759,6 +3759,8 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode, + esw->eswitch_operation_in_progress = true; + up_write(&esw->mode_lock); + ++ if (mode == DEVLINK_ESWITCH_MODE_LEGACY) ++ esw->dev->priv.flags |= MLX5_PRIV_FLAGS_SWITCH_LEGACY; + mlx5_eswitch_disable_locked(esw); + if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV) { + if (mlx5_devlink_trap_get_num_active(esw->dev)) { +diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h +index a9fca765b3d1..82c7056e2759 100644 +--- a/include/linux/mlx5/driver.h ++++ b/include/linux/mlx5/driver.h +@@ -555,6 +555,7 @@ enum { + * creation/deletion on drivers rescan. Unset during device attach. + */ + MLX5_PRIV_FLAGS_DETACH = 1 << 2, ++ MLX5_PRIV_FLAGS_SWITCH_LEGACY = 1 << 3, + }; + + struct mlx5_adev { +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5e-macsec-maintain-tx-sa-from-encoding_sa.patch b/queue-6.12/net-mlx5e-macsec-maintain-tx-sa-from-encoding_sa.patch new file mode 100644 index 00000000000..0a938f5e25a --- /dev/null +++ b/queue-6.12/net-mlx5e-macsec-maintain-tx-sa-from-encoding_sa.patch @@ -0,0 +1,63 @@ +From b56c4919847e5b22a0983e48e4c4bc94afc2805d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Dec 2024 10:15:03 +0200 +Subject: net/mlx5e: macsec: Maintain TX SA from encoding_sa + +From: Dragos Tatulea + +[ Upstream commit 8c6254479b3d5bd788d2b5fefaa48fb194331ed0 ] + +In MACsec, it is possible to create multiple active TX SAs on a SC, +but only one such SA can be used at a time for transmission. This SA +is selected through the encoding_sa link parameter. + +When there are 2 or more active TX SAs configured (encoding_sa=0): + ip macsec add macsec0 tx sa 0 pn 1 on key 00 + ip macsec add macsec0 tx sa 1 pn 1 on key 00 + +... the traffic should be still sent via TX SA 0 as the encoding_sa was +not changed. However, the driver ignores the encoding_sa and overrides +it to SA 1 by installing the flow steering id of the newly created TX SA +into the SCI -> flow steering id hash map. The future packet tx +descriptors will point to the incorrect flow steering rule (SA 1). + +This patch fixes the issue by avoiding the creation of the flow steering +rule for an active TX SA that is not the encoding_sa. The driver side +tx_sa object and the FW side macsec object are still created. When the +encoding_sa link parameter is changed to another active TX SA, only the +new flow steering rule will be created in the mlx5e_macsec_upd_txsa() +handler. + +Fixes: 8ff0ac5be144 ("net/mlx5: Add MACsec offload Tx command support") +Signed-off-by: Dragos Tatulea +Reviewed-by: Cosmin Ratiu +Reviewed-by: Lior Nahmanson +Signed-off-by: Tariq Toukan +Link: https://patch.msgid.link/20241220081505.1286093-3-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +index cc9bcc420032..6ab02f3fc291 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +@@ -339,9 +339,13 @@ static int mlx5e_macsec_init_sa_fs(struct macsec_context *ctx, + { + struct mlx5e_priv *priv = macsec_netdev_priv(ctx->netdev); + struct mlx5_macsec_fs *macsec_fs = priv->mdev->macsec_fs; ++ const struct macsec_tx_sc *tx_sc = &ctx->secy->tx_sc; + struct mlx5_macsec_rule_attrs rule_attrs; + union mlx5_macsec_rule *macsec_rule; + ++ if (is_tx && tx_sc->encoding_sa != sa->assoc_num) ++ return 0; ++ + rule_attrs.macsec_obj_id = sa->macsec_obj_id; + rule_attrs.sci = sa->sci; + rule_attrs.assoc_num = sa->assoc_num; +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5e-skip-restore-tc-rules-for-vport-rep-withou.patch b/queue-6.12/net-mlx5e-skip-restore-tc-rules-for-vport-rep-withou.patch new file mode 100644 index 00000000000..1bc2c424b93 --- /dev/null +++ b/queue-6.12/net-mlx5e-skip-restore-tc-rules-for-vport-rep-withou.patch @@ -0,0 +1,78 @@ +From 6c1c71a279b8a41ec68654798660cfd4e08b592b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Dec 2024 10:15:04 +0200 +Subject: net/mlx5e: Skip restore TC rules for vport rep without loaded flag + +From: Jianbo Liu + +[ Upstream commit 5a03b368562a7ff5f5f1f63b5adf8309cbdbd5be ] + +During driver unload, unregister_netdev is called after unloading +vport rep. So, the mlx5e_rep_priv is already freed while trying to get +rpriv->netdev, or walk rpriv->tc_ht, which results in use-after-free. +So add the checking to make sure access the data of vport rep which is +still loaded. + +Fixes: d1569537a837 ("net/mlx5e: Modify and restore TC rules for IPSec TX rules") +Signed-off-by: Jianbo Liu +Reviewed-by: Saeed Mahameed +Signed-off-by: Tariq Toukan +Link: https://patch.msgid.link/20241220081505.1286093-4-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c | 6 +++--- + drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 3 +++ + drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 3 --- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c +index 5a0047bdcb51..ed977ae75fab 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c +@@ -150,11 +150,11 @@ void mlx5_esw_ipsec_restore_dest_uplink(struct mlx5_core_dev *mdev) + unsigned long i; + int err; + +- xa_for_each(&esw->offloads.vport_reps, i, rep) { +- rpriv = rep->rep_data[REP_ETH].priv; +- if (!rpriv || !rpriv->netdev) ++ mlx5_esw_for_each_rep(esw, i, rep) { ++ if (atomic_read(&rep->rep_data[REP_ETH].state) != REP_LOADED) + continue; + ++ rpriv = rep->rep_data[REP_ETH].priv; + rhashtable_walk_enter(&rpriv->tc_ht, &iter); + rhashtable_walk_start(&iter); + while ((flow = rhashtable_walk_next(&iter)) != NULL) { +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +index f44b4c7ebcfd..48fd0400ffd4 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +@@ -716,6 +716,9 @@ void mlx5e_tc_clean_fdb_peer_flows(struct mlx5_eswitch *esw); + MLX5_CAP_GEN_2((esw->dev), ec_vf_vport_base) +\ + (last) - 1) + ++#define mlx5_esw_for_each_rep(esw, i, rep) \ ++ xa_for_each(&((esw)->offloads.vport_reps), i, rep) ++ + struct mlx5_eswitch *__must_check + mlx5_devlink_eswitch_get(struct devlink *devlink); + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +index 8cf61ae8b89d..3cf695425f0a 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +@@ -53,9 +53,6 @@ + #include "lag/lag.h" + #include "en/tc/post_meter.h" + +-#define mlx5_esw_for_each_rep(esw, i, rep) \ +- xa_for_each(&((esw)->offloads.vport_reps), i, rep) +- + /* There are two match-all miss flows, one for unicast dst mac and + * one for multicast. + */ +-- +2.39.5 + diff --git a/queue-6.12/net-mv643xx_eth-fix-an-of-node-reference-leak.patch b/queue-6.12/net-mv643xx_eth-fix-an-of-node-reference-leak.patch new file mode 100644 index 00000000000..0c4705918bb --- /dev/null +++ b/queue-6.12/net-mv643xx_eth-fix-an-of-node-reference-leak.patch @@ -0,0 +1,70 @@ +From 708a616eb12252764531064d74a335e56c01e9bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 21 Dec 2024 17:14:48 +0900 +Subject: net: mv643xx_eth: fix an OF node reference leak + +From: Joe Hattori + +[ Upstream commit ad5c318086e2e23b577eca33559c5ebf89bc7eb9 ] + +Current implementation of mv643xx_eth_shared_of_add_port() calls +of_parse_phandle(), but does not release the refcount on error. Call +of_node_put() in the error path and in mv643xx_eth_shared_of_remove(). + +This bug was found by an experimental verification tool that I am +developing. + +Fixes: 76723bca2802 ("net: mv643xx_eth: add DT parsing support") +Signed-off-by: Joe Hattori +Link: https://patch.msgid.link/20241221081448.3313163-1-joe@pf.is.s.u-tokyo.ac.jp +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/mv643xx_eth.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c +index 9e80899546d9..83b9905666e2 100644 +--- a/drivers/net/ethernet/marvell/mv643xx_eth.c ++++ b/drivers/net/ethernet/marvell/mv643xx_eth.c +@@ -2708,9 +2708,15 @@ static struct platform_device *port_platdev[3]; + + static void mv643xx_eth_shared_of_remove(void) + { ++ struct mv643xx_eth_platform_data *pd; + int n; + + for (n = 0; n < 3; n++) { ++ if (!port_platdev[n]) ++ continue; ++ pd = dev_get_platdata(&port_platdev[n]->dev); ++ if (pd) ++ of_node_put(pd->phy_node); + platform_device_del(port_platdev[n]); + port_platdev[n] = NULL; + } +@@ -2773,8 +2779,10 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev, + } + + ppdev = platform_device_alloc(MV643XX_ETH_NAME, dev_num); +- if (!ppdev) +- return -ENOMEM; ++ if (!ppdev) { ++ ret = -ENOMEM; ++ goto put_err; ++ } + ppdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + ppdev->dev.of_node = pnp; + +@@ -2796,6 +2804,8 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev, + + port_err: + platform_device_put(ppdev); ++put_err: ++ of_node_put(ppd.phy_node); + return ret; + } + +-- +2.39.5 + diff --git a/queue-6.12/net-phy-micrel-dynamically-control-external-clock-of.patch b/queue-6.12/net-phy-micrel-dynamically-control-external-clock-of.patch new file mode 100644 index 00000000000..62a59582272 --- /dev/null +++ b/queue-6.12/net-phy-micrel-dynamically-control-external-clock-of.patch @@ -0,0 +1,285 @@ +From 81ab7c7637ac79c50f9899cad707b6b085e14dff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Dec 2024 14:35:00 +0800 +Subject: net: phy: micrel: Dynamically control external clock of KSZ PHY + +From: Wei Fang + +[ Upstream commit 25c6a5ab151fb9c886552bf5aa7cbf2a5c6e96af ] + +On the i.MX6ULL-14x14-EVK board, enet1_ref and enet2_ref are used as the +clock sources for two external KSZ PHYs. However, after closing the two +FEC ports, the clk_enable_count of the enet1_ref and enet2_ref clocks is +not 0. The root cause is that since the commit 985329462723 ("net: phy: +micrel: use devm_clk_get_optional_enabled for the rmii-ref clock"), the +external clock of KSZ PHY has been enabled when the PHY driver probes, +and it can only be disabled when the PHY driver is removed. This causes +the clock to continue working when the system is suspended or the network +port is down. + +Although Heiko explained in the commit message that the patch was because +some clock suppliers need to enable the clock to get the valid clock rate +, it seems that the simple fix is to disable the clock after getting the +clock rate to solve the current problem. This is indeed true, but we need +to admit that Heiko's patch has been applied for more than a year, and we +cannot guarantee whether there are platforms that only enable rmii-ref in +the KSZ PHY driver during this period. If this is the case, disabling +rmii-ref will cause RMII on these platforms to not work. + +Secondly, commit 99ac4cbcc2a5 ("net: phy: micrel: allow usage of generic +ethernet-phy clock") just simply enables the generic clock permanently, +which seems like the generic clock may only be enabled in the PHY driver. +If we simply disable the generic clock, RMII may not work. If we keep it +as it is, the platform using the generic clock will have the same problem +as the i.MX6ULL platform. + +To solve this problem, the clock is enabled when phy_driver::resume() is +called, and the clock is disabled when phy_driver::suspend() is called. +Since phy_driver::resume() and phy_driver::suspend() are not called in +pairs, an additional clk_enable flag is added. When phy_driver::suspend() +is called, the clock is disabled only if clk_enable is true. Conversely, +when phy_driver::resume() is called, the clock is enabled if clk_enable +is false. + +The changes that introduced the problem were only a few lines, while the +current fix is about a hundred lines, which seems out of proportion, but +it is necessary because kszphy_probe() is used by multiple KSZ PHYs and +we need to fix all of them. + +Fixes: 985329462723 ("net: phy: micrel: use devm_clk_get_optional_enabled for the rmii-ref clock") +Fixes: 99ac4cbcc2a5 ("net: phy: micrel: allow usage of generic ethernet-phy clock") +Signed-off-by: Wei Fang +Reviewed-by: Andrew Lunn +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20241217063500.1424011-1-wei.fang@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/micrel.c | 114 ++++++++++++++++++++++++++++++++++----- + 1 file changed, 101 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c +index 65b0a3115e14..64926240b007 100644 +--- a/drivers/net/phy/micrel.c ++++ b/drivers/net/phy/micrel.c +@@ -432,10 +432,12 @@ struct kszphy_ptp_priv { + struct kszphy_priv { + struct kszphy_ptp_priv ptp_priv; + const struct kszphy_type *type; ++ struct clk *clk; + int led_mode; + u16 vct_ctrl1000; + bool rmii_ref_clk_sel; + bool rmii_ref_clk_sel_val; ++ bool clk_enable; + u64 stats[ARRAY_SIZE(kszphy_hw_stats)]; + }; + +@@ -2052,6 +2054,46 @@ static void kszphy_get_stats(struct phy_device *phydev, + data[i] = kszphy_get_stat(phydev, i); + } + ++static void kszphy_enable_clk(struct phy_device *phydev) ++{ ++ struct kszphy_priv *priv = phydev->priv; ++ ++ if (!priv->clk_enable && priv->clk) { ++ clk_prepare_enable(priv->clk); ++ priv->clk_enable = true; ++ } ++} ++ ++static void kszphy_disable_clk(struct phy_device *phydev) ++{ ++ struct kszphy_priv *priv = phydev->priv; ++ ++ if (priv->clk_enable && priv->clk) { ++ clk_disable_unprepare(priv->clk); ++ priv->clk_enable = false; ++ } ++} ++ ++static int kszphy_generic_resume(struct phy_device *phydev) ++{ ++ kszphy_enable_clk(phydev); ++ ++ return genphy_resume(phydev); ++} ++ ++static int kszphy_generic_suspend(struct phy_device *phydev) ++{ ++ int ret; ++ ++ ret = genphy_suspend(phydev); ++ if (ret) ++ return ret; ++ ++ kszphy_disable_clk(phydev); ++ ++ return 0; ++} ++ + static int kszphy_suspend(struct phy_device *phydev) + { + /* Disable PHY Interrupts */ +@@ -2061,7 +2103,7 @@ static int kszphy_suspend(struct phy_device *phydev) + phydev->drv->config_intr(phydev); + } + +- return genphy_suspend(phydev); ++ return kszphy_generic_suspend(phydev); + } + + static void kszphy_parse_led_mode(struct phy_device *phydev) +@@ -2092,7 +2134,9 @@ static int kszphy_resume(struct phy_device *phydev) + { + int ret; + +- genphy_resume(phydev); ++ ret = kszphy_generic_resume(phydev); ++ if (ret) ++ return ret; + + /* After switching from power-down to normal mode, an internal global + * reset is automatically generated. Wait a minimum of 1 ms before +@@ -2114,6 +2158,24 @@ static int kszphy_resume(struct phy_device *phydev) + return 0; + } + ++/* Because of errata DS80000700A, receiver error following software ++ * power down. Suspend and resume callbacks only disable and enable ++ * external rmii reference clock. ++ */ ++static int ksz8041_resume(struct phy_device *phydev) ++{ ++ kszphy_enable_clk(phydev); ++ ++ return 0; ++} ++ ++static int ksz8041_suspend(struct phy_device *phydev) ++{ ++ kszphy_disable_clk(phydev); ++ ++ return 0; ++} ++ + static int ksz9477_resume(struct phy_device *phydev) + { + int ret; +@@ -2161,7 +2223,10 @@ static int ksz8061_resume(struct phy_device *phydev) + if (!(ret & BMCR_PDOWN)) + return 0; + +- genphy_resume(phydev); ++ ret = kszphy_generic_resume(phydev); ++ if (ret) ++ return ret; ++ + usleep_range(1000, 2000); + + /* Re-program the value after chip is reset. */ +@@ -2179,6 +2244,11 @@ static int ksz8061_resume(struct phy_device *phydev) + return 0; + } + ++static int ksz8061_suspend(struct phy_device *phydev) ++{ ++ return kszphy_suspend(phydev); ++} ++ + static int kszphy_probe(struct phy_device *phydev) + { + const struct kszphy_type *type = phydev->drv->driver_data; +@@ -2219,10 +2289,14 @@ static int kszphy_probe(struct phy_device *phydev) + } else if (!clk) { + /* unnamed clock from the generic ethernet-phy binding */ + clk = devm_clk_get_optional_enabled(&phydev->mdio.dev, NULL); +- if (IS_ERR(clk)) +- return PTR_ERR(clk); + } + ++ if (IS_ERR(clk)) ++ return PTR_ERR(clk); ++ ++ clk_disable_unprepare(clk); ++ priv->clk = clk; ++ + if (ksz8041_fiber_mode(phydev)) + phydev->port = PORT_FIBRE; + +@@ -5292,6 +5366,21 @@ static int lan8841_probe(struct phy_device *phydev) + return 0; + } + ++static int lan8804_resume(struct phy_device *phydev) ++{ ++ return kszphy_resume(phydev); ++} ++ ++static int lan8804_suspend(struct phy_device *phydev) ++{ ++ return kszphy_generic_suspend(phydev); ++} ++ ++static int lan8841_resume(struct phy_device *phydev) ++{ ++ return kszphy_generic_resume(phydev); ++} ++ + static int lan8841_suspend(struct phy_device *phydev) + { + struct kszphy_priv *priv = phydev->priv; +@@ -5300,7 +5389,7 @@ static int lan8841_suspend(struct phy_device *phydev) + if (ptp_priv->ptp_clock) + ptp_cancel_worker_sync(ptp_priv->ptp_clock); + +- return genphy_suspend(phydev); ++ return kszphy_generic_suspend(phydev); + } + + static struct phy_driver ksphy_driver[] = { +@@ -5360,9 +5449,8 @@ static struct phy_driver ksphy_driver[] = { + .get_sset_count = kszphy_get_sset_count, + .get_strings = kszphy_get_strings, + .get_stats = kszphy_get_stats, +- /* No suspend/resume callbacks because of errata DS80000700A, +- * receiver error following software power down. +- */ ++ .suspend = ksz8041_suspend, ++ .resume = ksz8041_resume, + }, { + .phy_id = PHY_ID_KSZ8041RNLI, + .phy_id_mask = MICREL_PHY_ID_MASK, +@@ -5438,7 +5526,7 @@ static struct phy_driver ksphy_driver[] = { + .soft_reset = genphy_soft_reset, + .config_intr = kszphy_config_intr, + .handle_interrupt = kszphy_handle_interrupt, +- .suspend = kszphy_suspend, ++ .suspend = ksz8061_suspend, + .resume = ksz8061_resume, + }, { + .phy_id = PHY_ID_KSZ9021, +@@ -5509,8 +5597,8 @@ static struct phy_driver ksphy_driver[] = { + .get_sset_count = kszphy_get_sset_count, + .get_strings = kszphy_get_strings, + .get_stats = kszphy_get_stats, +- .suspend = genphy_suspend, +- .resume = kszphy_resume, ++ .suspend = lan8804_suspend, ++ .resume = lan8804_resume, + .config_intr = lan8804_config_intr, + .handle_interrupt = lan8804_handle_interrupt, + }, { +@@ -5528,7 +5616,7 @@ static struct phy_driver ksphy_driver[] = { + .get_strings = kszphy_get_strings, + .get_stats = kszphy_get_stats, + .suspend = lan8841_suspend, +- .resume = genphy_resume, ++ .resume = lan8841_resume, + .cable_test_start = lan8814_cable_test_start, + .cable_test_get_status = ksz886x_cable_test_get_status, + }, { +-- +2.39.5 + diff --git a/queue-6.12/net-pse-pd-tps23881-fix-power-on-off-issue.patch b/queue-6.12/net-pse-pd-tps23881-fix-power-on-off-issue.patch new file mode 100644 index 00000000000..a7e245909f9 --- /dev/null +++ b/queue-6.12/net-pse-pd-tps23881-fix-power-on-off-issue.patch @@ -0,0 +1,72 @@ +From a461f73d6e147b6ebbc7106a418565c2ae8b94ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Dec 2024 18:04:00 +0100 +Subject: net: pse-pd: tps23881: Fix power on/off issue + +From: Kory Maincent + +[ Upstream commit 75221e96101fa93390d3db5c23e026f5e3565d9b ] + +An issue was present in the initial driver implementation. The driver +read the power status of all channels before toggling the bit of the +desired one. Using the power status register as a base value introduced +a problem, because only the bit corresponding to the concerned channel ID +should be set in the write-only power enable register. This led to cases +where disabling power for one channel also powered off other channels. + +This patch removes the power status read and ensures the value is +limited to the bit matching the channel index of the PI. + +Fixes: 20e6d190ffe1 ("net: pse-pd: Add TI TPS23881 PSE controller driver") +Signed-off-by: Kory Maincent +Acked-by: Oleksij Rempel +Link: https://patch.msgid.link/20241220170400.291705-1-kory.maincent@bootlin.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/pse-pd/tps23881.c | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/pse-pd/tps23881.c b/drivers/net/pse-pd/tps23881.c +index 5c4e88be46ee..8797ca1a8a21 100644 +--- a/drivers/net/pse-pd/tps23881.c ++++ b/drivers/net/pse-pd/tps23881.c +@@ -64,15 +64,11 @@ static int tps23881_pi_enable(struct pse_controller_dev *pcdev, int id) + if (id >= TPS23881_MAX_CHANS) + return -ERANGE; + +- ret = i2c_smbus_read_word_data(client, TPS23881_REG_PW_STATUS); +- if (ret < 0) +- return ret; +- + chan = priv->port[id].chan[0]; + if (chan < 4) +- val = (u16)(ret | BIT(chan)); ++ val = BIT(chan); + else +- val = (u16)(ret | BIT(chan + 4)); ++ val = BIT(chan + 4); + + if (priv->port[id].is_4p) { + chan = priv->port[id].chan[1]; +@@ -100,15 +96,11 @@ static int tps23881_pi_disable(struct pse_controller_dev *pcdev, int id) + if (id >= TPS23881_MAX_CHANS) + return -ERANGE; + +- ret = i2c_smbus_read_word_data(client, TPS23881_REG_PW_STATUS); +- if (ret < 0) +- return ret; +- + chan = priv->port[id].chan[0]; + if (chan < 4) +- val = (u16)(ret | BIT(chan + 4)); ++ val = BIT(chan + 4); + else +- val = (u16)(ret | BIT(chan + 8)); ++ val = BIT(chan + 8); + + if (priv->port[id].is_4p) { + chan = priv->port[id].chan[1]; +-- +2.39.5 + diff --git a/queue-6.12/net-reenable-netif_f_ipv6_csum-offload-for-big-tcp-p.patch b/queue-6.12/net-reenable-netif_f_ipv6_csum-offload-for-big-tcp-p.patch new file mode 100644 index 00000000000..b6ac338ae65 --- /dev/null +++ b/queue-6.12/net-reenable-netif_f_ipv6_csum-offload-for-big-tcp-p.patch @@ -0,0 +1,83 @@ +From 414fb0df2dcf61f1909c7aab4f0ebc6eecf3ee96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Jan 2025 11:47:40 -0500 +Subject: net: reenable NETIF_F_IPV6_CSUM offload for BIG TCP packets + +From: Willem de Bruijn + +[ Upstream commit 68e068cabd2c6c533ef934c2e5151609cf6ecc6d ] + +The blamed commit disabled hardware offoad of IPv6 packets with +extension headers on devices that advertise NETIF_F_IPV6_CSUM, +based on the definition of that feature in skbuff.h: + + * * - %NETIF_F_IPV6_CSUM + * - Driver (device) is only able to checksum plain + * TCP or UDP packets over IPv6. These are specifically + * unencapsulated packets of the form IPv6|TCP or + * IPv6|UDP where the Next Header field in the IPv6 + * header is either TCP or UDP. IPv6 extension headers + * are not supported with this feature. This feature + * cannot be set in features for a device with + * NETIF_F_HW_CSUM also set. This feature is being + * DEPRECATED (see below). + +The change causes skb_warn_bad_offload to fire for BIG TCP +packets. + +[ 496.310233] WARNING: CPU: 13 PID: 23472 at net/core/dev.c:3129 skb_warn_bad_offload+0xc4/0xe0 + +[ 496.310297] ? skb_warn_bad_offload+0xc4/0xe0 +[ 496.310300] skb_checksum_help+0x129/0x1f0 +[ 496.310303] skb_csum_hwoffload_help+0x150/0x1b0 +[ 496.310306] validate_xmit_skb+0x159/0x270 +[ 496.310309] validate_xmit_skb_list+0x41/0x70 +[ 496.310312] sch_direct_xmit+0x5c/0x250 +[ 496.310317] __qdisc_run+0x388/0x620 + +BIG TCP introduced an IPV6_TLV_JUMBO IPv6 extension header to +communicate packet length, as this is an IPv6 jumbogram. But, the +feature is only enabled on devices that support BIG TCP TSO. The +header is only present for PF_PACKET taps like tcpdump, and not +transmitted by physical devices. + +For this specific case of extension headers that are not +transmitted, return to the situation before the blamed commit +and support hardware offload. + +ipv6_has_hopopt_jumbo() tests not only whether this header is present, +but also that it is the only extension header before a terminal (L4) +header. + +Fixes: 04c20a9356f2 ("net: skip offload for NETIF_F_IPV6_CSUM if ipv6 header contains extension") +Reported-by: syzbot +Reported-by: Eric Dumazet +Closes: https://lore.kernel.org/netdev/CANn89iK1hdC3Nt8KPhOtTF8vCPc1AHDCtse_BTNki1pWxAByTQ@mail.gmail.com/ +Signed-off-by: Willem de Bruijn +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20250101164909.1331680-1-willemdebruijn.kernel@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/dev.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/core/dev.c b/net/core/dev.c +index 8453e14d301b..f3fa8353d262 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -3640,8 +3640,10 @@ int skb_csum_hwoffload_help(struct sk_buff *skb, + + if (features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) { + if (vlan_get_protocol(skb) == htons(ETH_P_IPV6) && +- skb_network_header_len(skb) != sizeof(struct ipv6hdr)) ++ skb_network_header_len(skb) != sizeof(struct ipv6hdr) && ++ !ipv6_has_hopopt_jumbo(skb)) + goto sw_checksum; ++ + switch (skb->csum_offset) { + case offsetof(struct tcphdr, check): + case offsetof(struct udphdr, check): +-- +2.39.5 + diff --git a/queue-6.12/net-restrict-so_reuseport-to-inet-sockets.patch b/queue-6.12/net-restrict-so_reuseport-to-inet-sockets.patch new file mode 100644 index 00000000000..c703d10b7e5 --- /dev/null +++ b/queue-6.12/net-restrict-so_reuseport-to-inet-sockets.patch @@ -0,0 +1,87 @@ +From c71048b38907547b630b98bbaf4c08f799887789 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Dec 2024 16:05:27 +0000 +Subject: net: restrict SO_REUSEPORT to inet sockets + +From: Eric Dumazet + +[ Upstream commit 5b0af621c3f6ef9261cf6067812f2fd9943acb4b ] + +After blamed commit, crypto sockets could accidentally be destroyed +from RCU call back, as spotted by zyzbot [1]. + +Trying to acquire a mutex in RCU callback is not allowed. + +Restrict SO_REUSEPORT socket option to inet sockets. + +v1 of this patch supported TCP, UDP and SCTP sockets, +but fcnal-test.sh test needed RAW and ICMP support. + +[1] +BUG: sleeping function called from invalid context at kernel/locking/mutex.c:562 +in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 24, name: ksoftirqd/1 +preempt_count: 100, expected: 0 +RCU nest depth: 0, expected: 0 +1 lock held by ksoftirqd/1/24: + #0: ffffffff8e937ba0 (rcu_callback){....}-{0:0}, at: rcu_lock_acquire include/linux/rcupdate.h:337 [inline] + #0: ffffffff8e937ba0 (rcu_callback){....}-{0:0}, at: rcu_do_batch kernel/rcu/tree.c:2561 [inline] + #0: ffffffff8e937ba0 (rcu_callback){....}-{0:0}, at: rcu_core+0xa37/0x17a0 kernel/rcu/tree.c:2823 +Preemption disabled at: + [] softirq_handle_begin kernel/softirq.c:402 [inline] + [] handle_softirqs+0x128/0x9b0 kernel/softirq.c:537 +CPU: 1 UID: 0 PID: 24 Comm: ksoftirqd/1 Not tainted 6.13.0-rc3-syzkaller-00174-ga024e377efed #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 +Call Trace: + + __dump_stack lib/dump_stack.c:94 [inline] + dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 + __might_resched+0x5d4/0x780 kernel/sched/core.c:8758 + __mutex_lock_common kernel/locking/mutex.c:562 [inline] + __mutex_lock+0x131/0xee0 kernel/locking/mutex.c:735 + crypto_put_default_null_skcipher+0x18/0x70 crypto/crypto_null.c:179 + aead_release+0x3d/0x50 crypto/algif_aead.c:489 + alg_do_release crypto/af_alg.c:118 [inline] + alg_sock_destruct+0x86/0xc0 crypto/af_alg.c:502 + __sk_destruct+0x58/0x5f0 net/core/sock.c:2260 + rcu_do_batch kernel/rcu/tree.c:2567 [inline] + rcu_core+0xaaa/0x17a0 kernel/rcu/tree.c:2823 + handle_softirqs+0x2d4/0x9b0 kernel/softirq.c:561 + run_ksoftirqd+0xca/0x130 kernel/softirq.c:950 + smpboot_thread_fn+0x544/0xa30 kernel/smpboot.c:164 + kthread+0x2f0/0x390 kernel/kthread.c:389 + ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147 + ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 + + +Fixes: 8c7138b33e5c ("net: Unpublish sk from sk_reuseport_cb before call_rcu") +Reported-by: syzbot+b3e02953598f447d4d2a@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/6772f2f4.050a0220.2f3838.04cb.GAE@google.com/T/#u +Signed-off-by: Eric Dumazet +Cc: Martin KaFai Lau +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20241231160527.3994168-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/sock.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/net/core/sock.c b/net/core/sock.c +index da50df485090..a83f64a1d96a 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1300,7 +1300,10 @@ int sk_setsockopt(struct sock *sk, int level, int optname, + sk->sk_reuse = (valbool ? SK_CAN_REUSE : SK_NO_REUSE); + break; + case SO_REUSEPORT: +- sk->sk_reuseport = valbool; ++ if (valbool && !sk_is_inet(sk)) ++ ret = -EOPNOTSUPP; ++ else ++ sk->sk_reuseport = valbool; + break; + case SO_DONTROUTE: + sock_valbool_flag(sk, SOCK_LOCALROUTE, valbool); +-- +2.39.5 + diff --git a/queue-6.12/net-sfc-correct-key_len-for-efx_tc_ct_zone_ht_params.patch b/queue-6.12/net-sfc-correct-key_len-for-efx_tc_ct_zone_ht_params.patch new file mode 100644 index 00000000000..3050e24d071 --- /dev/null +++ b/queue-6.12/net-sfc-correct-key_len-for-efx_tc_ct_zone_ht_params.patch @@ -0,0 +1,45 @@ +From 1179279fe27e231962218e68613cd2040fafc639 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Dec 2024 17:37:09 +0800 +Subject: net: sfc: Correct key_len for efx_tc_ct_zone_ht_params + +From: Liang Jie + +[ Upstream commit a8620de72e5676993ec3a3b975f7c10908f5f60f ] + +In efx_tc_ct_zone_ht_params, the key_len was previously set to +offsetof(struct efx_tc_ct_zone, linkage). This calculation is incorrect +because it includes any padding between the zone field and the linkage +field due to structure alignment, which can vary between systems. + +This patch updates key_len to use sizeof_field(struct efx_tc_ct_zone, zone) +, ensuring that the hash table correctly uses the zone as the key. This fix +prevents potential hash lookup errors and improves connection tracking +reliability. + +Fixes: c3bb5c6acd4e ("sfc: functions to register for conntrack zone offload") +Signed-off-by: Liang Jie +Acked-by: Edward Cree +Link: https://patch.msgid.link/20241230093709.3226854-1-buaajxlj@163.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/sfc/tc_conntrack.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/sfc/tc_conntrack.c b/drivers/net/ethernet/sfc/tc_conntrack.c +index d90206f27161..c0603f54cec3 100644 +--- a/drivers/net/ethernet/sfc/tc_conntrack.c ++++ b/drivers/net/ethernet/sfc/tc_conntrack.c +@@ -16,7 +16,7 @@ static int efx_tc_flow_block(enum tc_setup_type type, void *type_data, + void *cb_priv); + + static const struct rhashtable_params efx_tc_ct_zone_ht_params = { +- .key_len = offsetof(struct efx_tc_ct_zone, linkage), ++ .key_len = sizeof_field(struct efx_tc_ct_zone, zone), + .key_offset = 0, + .head_offset = offsetof(struct efx_tc_ct_zone, linkage), + }; +-- +2.39.5 + diff --git a/queue-6.12/net-stmmac-restructure-the-error-path-of-stmmac_prob.patch b/queue-6.12/net-stmmac-restructure-the-error-path-of-stmmac_prob.patch new file mode 100644 index 00000000000..27b4be74e35 --- /dev/null +++ b/queue-6.12/net-stmmac-restructure-the-error-path-of-stmmac_prob.patch @@ -0,0 +1,128 @@ +From 8e6812bdb1ccb7c393c45fd681ed575aa53663b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Dec 2024 11:41:19 +0900 +Subject: net: stmmac: restructure the error path of stmmac_probe_config_dt() + +From: Joe Hattori + +[ Upstream commit 2b6ffcd7873b7e8a62c3e15a6f305bfc747c466b ] + +Current implementation of stmmac_probe_config_dt() does not release the +OF node reference obtained by of_parse_phandle() in some error paths. +The problem is that some error paths call stmmac_remove_config_dt() to +clean up but others use and unwind ladder. These two types of error +handling have not kept in sync and have been a recurring source of bugs. +Re-write the error handling in stmmac_probe_config_dt() to use an unwind +ladder. Consequently, stmmac_remove_config_dt() is not needed anymore, +thus remove it. + +This bug was found by an experimental verification tool that I am +developing. + +Fixes: 4838a5405028 ("net: stmmac: Fix wrapper drivers not detecting PHY") +Signed-off-by: Joe Hattori +Link: https://patch.msgid.link/20241219024119.2017012-1-joe@pf.is.s.u-tokyo.ac.jp +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../ethernet/stmicro/stmmac/stmmac_platform.c | 43 ++++++++----------- + 1 file changed, 17 insertions(+), 26 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +index ad868e8d195d..aaf008bdbbcd 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +@@ -405,22 +405,6 @@ static int stmmac_of_get_mac_mode(struct device_node *np) + return -ENODEV; + } + +-/** +- * stmmac_remove_config_dt - undo the effects of stmmac_probe_config_dt() +- * @pdev: platform_device structure +- * @plat: driver data platform structure +- * +- * Release resources claimed by stmmac_probe_config_dt(). +- */ +-static void stmmac_remove_config_dt(struct platform_device *pdev, +- struct plat_stmmacenet_data *plat) +-{ +- clk_disable_unprepare(plat->stmmac_clk); +- clk_disable_unprepare(plat->pclk); +- of_node_put(plat->phy_node); +- of_node_put(plat->mdio_node); +-} +- + /** + * stmmac_probe_config_dt - parse device-tree driver parameters + * @pdev: platform_device structure +@@ -490,8 +474,10 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) + dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n"); + + rc = stmmac_mdio_setup(plat, np, &pdev->dev); +- if (rc) +- return ERR_PTR(rc); ++ if (rc) { ++ ret = ERR_PTR(rc); ++ goto error_put_phy; ++ } + + of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size); + +@@ -580,8 +566,8 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) + dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), + GFP_KERNEL); + if (!dma_cfg) { +- stmmac_remove_config_dt(pdev, plat); +- return ERR_PTR(-ENOMEM); ++ ret = ERR_PTR(-ENOMEM); ++ goto error_put_mdio; + } + plat->dma_cfg = dma_cfg; + +@@ -609,8 +595,8 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) + + rc = stmmac_mtl_setup(pdev, plat); + if (rc) { +- stmmac_remove_config_dt(pdev, plat); +- return ERR_PTR(rc); ++ ret = ERR_PTR(rc); ++ goto error_put_mdio; + } + + /* clock setup */ +@@ -662,6 +648,10 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) + clk_disable_unprepare(plat->pclk); + error_pclk_get: + clk_disable_unprepare(plat->stmmac_clk); ++error_put_mdio: ++ of_node_put(plat->mdio_node); ++error_put_phy: ++ of_node_put(plat->phy_node); + + return ret; + } +@@ -670,16 +660,17 @@ static void devm_stmmac_remove_config_dt(void *data) + { + struct plat_stmmacenet_data *plat = data; + +- /* Platform data argument is unused */ +- stmmac_remove_config_dt(NULL, plat); ++ clk_disable_unprepare(plat->stmmac_clk); ++ clk_disable_unprepare(plat->pclk); ++ of_node_put(plat->mdio_node); ++ of_node_put(plat->phy_node); + } + + /** + * devm_stmmac_probe_config_dt + * @pdev: platform_device structure + * @mac: MAC address to use +- * Description: Devres variant of stmmac_probe_config_dt(). Does not require +- * the user to call stmmac_remove_config_dt() at driver detach. ++ * Description: Devres variant of stmmac_probe_config_dt(). + */ + struct plat_stmmacenet_data * + devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) +-- +2.39.5 + diff --git a/queue-6.12/net-ti-icssg-prueth-fix-clearing-of-iep_cmp_cfg-regi.patch b/queue-6.12/net-ti-icssg-prueth-fix-clearing-of-iep_cmp_cfg-regi.patch new file mode 100644 index 00000000000..aa5618a6a6f --- /dev/null +++ b/queue-6.12/net-ti-icssg-prueth-fix-clearing-of-iep_cmp_cfg-regi.patch @@ -0,0 +1,61 @@ +From bb830e356c30baa20ec9d3002cdc0997cf160f3c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Dec 2024 20:45:50 +0530 +Subject: net: ti: icssg-prueth: Fix clearing of IEP_CMP_CFG registers during + iep_init + +From: Meghana Malladi + +[ Upstream commit 9b115361248dc6cce182a2dc030c1c70b0a9639e ] + +When ICSSG interfaces are brought down and brought up again, the +pru cores are shut down and booted again, flushing out all the memories +and start again in a clean state. Hence it is expected that the +IEP_CMP_CFG register needs to be flushed during iep_init() to ensure +that the existing residual configuration doesn't cause any unusual +behavior. If the register is not cleared, existing IEP_CMP_CFG set for +CMP1 will result in SYNC0_OUT signal based on the SYNC_OUT register values. + +After bringing the interface up, calling PPS enable doesn't work as +the driver believes PPS is already enabled, (iep->pps_enabled is not +cleared during interface bring down) and driver will just return true +even though there is no signal. Fix this by disabling pps and perout. + +Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver") +Signed-off-by: Meghana Malladi +Reviewed-by: Roger Quadros +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/ti/icssg/icss_iep.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c +index 5d6d1cf78e93..768578c0d958 100644 +--- a/drivers/net/ethernet/ti/icssg/icss_iep.c ++++ b/drivers/net/ethernet/ti/icssg/icss_iep.c +@@ -215,6 +215,9 @@ static void icss_iep_enable_shadow_mode(struct icss_iep *iep) + for (cmp = IEP_MIN_CMP; cmp < IEP_MAX_CMP; cmp++) { + regmap_update_bits(iep->map, ICSS_IEP_CMP_STAT_REG, + IEP_CMP_STATUS(cmp), IEP_CMP_STATUS(cmp)); ++ ++ regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG, ++ IEP_CMP_CFG_CMP_EN(cmp), 0); + } + + /* enable reset counter on CMP0 event */ +@@ -780,6 +783,11 @@ int icss_iep_exit(struct icss_iep *iep) + } + icss_iep_disable(iep); + ++ if (iep->pps_enabled) ++ icss_iep_pps_enable(iep, false); ++ else if (iep->perout_enabled) ++ icss_iep_perout_enable(iep, NULL, false); ++ + return 0; + } + EXPORT_SYMBOL_GPL(icss_iep_exit); +-- +2.39.5 + diff --git a/queue-6.12/net-ti-icssg-prueth-fix-firmware-load-sequence.patch b/queue-6.12/net-ti-icssg-prueth-fix-firmware-load-sequence.patch new file mode 100644 index 00000000000..54ecb109422 --- /dev/null +++ b/queue-6.12/net-ti-icssg-prueth-fix-firmware-load-sequence.patch @@ -0,0 +1,706 @@ +From c673e922db3a373fbbdc39bd2929314a1f09f397 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Dec 2024 20:45:49 +0530 +Subject: net: ti: icssg-prueth: Fix firmware load sequence. + +From: MD Danish Anwar + +[ Upstream commit 9facce84f4062f782ebde18daa7006a23d40b607 ] + +Timesync related operations are ran in PRU0 cores for both ICSSG SLICE0 +and SLICE1. Currently whenever any ICSSG interface comes up we load the +respective firmwares to PRU cores and whenever interface goes down, we +stop the resective cores. Due to this, when SLICE0 goes down while +SLICE1 is still active, PRU0 firmwares are unloaded and PRU0 core is +stopped. This results in clock jump for SLICE1 interface as the timesync +related operations are no longer running. + +As there are interdependencies between SLICE0 and SLICE1 firmwares, +fix this by running both PRU0 and PRU1 firmwares as long as at least 1 +ICSSG interface is up. Add new flag in prueth struct to check if all +firmwares are running and remove the old flag (fw_running). + +Use emacs_initialized as reference count to load the firmwares for the +first and last interface up/down. Moving init_emac_mode and fw_offload_mode +API outside of icssg_config to icssg_common_start API as they need +to be called only once per firmware boot. + +Change prueth_emac_restart() to return error code and add error prints +inside the caller of this functions in case of any failures. + +Move prueth_emac_stop() from common to sr1 driver. +sr1 and sr2 drivers have different logic handling for stopping +the firmwares. While sr1 driver is dependent on emac structure +to stop the corresponding pru cores for that slice, for sr2 +all the pru cores of both the slices are stopped and is not +dependent on emac. So the prueth_emac_stop() function is no +longer common and can be moved to sr1 driver. + +Fixes: c1e0230eeaab ("net: ti: icss-iep: Add IEP driver") +Signed-off-by: MD Danish Anwar +Signed-off-by: Meghana Malladi +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/ti/icssg/icssg_common.c | 25 -- + drivers/net/ethernet/ti/icssg/icssg_config.c | 41 ++- + drivers/net/ethernet/ti/icssg/icssg_config.h | 1 + + drivers/net/ethernet/ti/icssg/icssg_prueth.c | 261 ++++++++++++------ + drivers/net/ethernet/ti/icssg/icssg_prueth.h | 5 +- + .../net/ethernet/ti/icssg/icssg_prueth_sr1.c | 24 +- + 6 files changed, 236 insertions(+), 121 deletions(-) + +diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c +index fdebeb2f84e0..74f0f200a89d 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_common.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_common.c +@@ -855,31 +855,6 @@ irqreturn_t prueth_rx_irq(int irq, void *dev_id) + } + EXPORT_SYMBOL_GPL(prueth_rx_irq); + +-void prueth_emac_stop(struct prueth_emac *emac) +-{ +- struct prueth *prueth = emac->prueth; +- int slice; +- +- switch (emac->port_id) { +- case PRUETH_PORT_MII0: +- slice = ICSS_SLICE0; +- break; +- case PRUETH_PORT_MII1: +- slice = ICSS_SLICE1; +- break; +- default: +- netdev_err(emac->ndev, "invalid port\n"); +- return; +- } +- +- emac->fw_running = 0; +- if (!emac->is_sr1) +- rproc_shutdown(prueth->txpru[slice]); +- rproc_shutdown(prueth->rtu[slice]); +- rproc_shutdown(prueth->pru[slice]); +-} +-EXPORT_SYMBOL_GPL(prueth_emac_stop); +- + void prueth_cleanup_tx_ts(struct prueth_emac *emac) + { + int i; +diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c +index 5d2491c2943a..ddfd1c02a885 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_config.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_config.c +@@ -397,7 +397,7 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac) + return 0; + } + +-static void icssg_init_emac_mode(struct prueth *prueth) ++void icssg_init_emac_mode(struct prueth *prueth) + { + /* When the device is configured as a bridge and it is being brought + * back to the emac mode, the host mac address has to be set as 0. +@@ -406,9 +406,6 @@ static void icssg_init_emac_mode(struct prueth *prueth) + int i; + u8 mac[ETH_ALEN] = { 0 }; + +- if (prueth->emacs_initialized) +- return; +- + /* Set VLAN TABLE address base */ + regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK, + addr << SMEM_VLAN_OFFSET); +@@ -423,15 +420,13 @@ static void icssg_init_emac_mode(struct prueth *prueth) + /* Clear host MAC address */ + icssg_class_set_host_mac_addr(prueth->miig_rt, mac); + } ++EXPORT_SYMBOL_GPL(icssg_init_emac_mode); + +-static void icssg_init_fw_offload_mode(struct prueth *prueth) ++void icssg_init_fw_offload_mode(struct prueth *prueth) + { + u32 addr = prueth->shram.pa + EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET; + int i; + +- if (prueth->emacs_initialized) +- return; +- + /* Set VLAN TABLE address base */ + regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK, + addr << SMEM_VLAN_OFFSET); +@@ -448,6 +443,7 @@ static void icssg_init_fw_offload_mode(struct prueth *prueth) + icssg_class_set_host_mac_addr(prueth->miig_rt, prueth->hw_bridge_dev->dev_addr); + icssg_set_pvid(prueth, prueth->default_vlan, PRUETH_PORT_HOST); + } ++EXPORT_SYMBOL_GPL(icssg_init_fw_offload_mode); + + int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice) + { +@@ -455,11 +451,6 @@ int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice) + struct icssg_flow_cfg __iomem *flow_cfg; + int ret; + +- if (prueth->is_switch_mode || prueth->is_hsr_offload_mode) +- icssg_init_fw_offload_mode(prueth); +- else +- icssg_init_emac_mode(prueth); +- + memset_io(config, 0, TAS_GATE_MASK_LIST0); + icssg_miig_queues_init(prueth, slice); + +@@ -786,3 +777,27 @@ void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port) + writel(pvid, prueth->shram.va + EMAC_ICSSG_SWITCH_PORT0_DEFAULT_VLAN_OFFSET); + } + EXPORT_SYMBOL_GPL(icssg_set_pvid); ++ ++int emac_fdb_flow_id_updated(struct prueth_emac *emac) ++{ ++ struct mgmt_cmd_rsp fdb_cmd_rsp = { 0 }; ++ int slice = prueth_emac_slice(emac); ++ struct mgmt_cmd fdb_cmd = { 0 }; ++ int ret; ++ ++ fdb_cmd.header = ICSSG_FW_MGMT_CMD_HEADER; ++ fdb_cmd.type = ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW; ++ fdb_cmd.seqnum = ++(emac->prueth->icssg_hwcmdseq); ++ fdb_cmd.param = 0; ++ ++ fdb_cmd.param |= (slice << 4); ++ fdb_cmd.cmd_args[0] = 0; ++ ++ ret = icssg_send_fdb_msg(emac, &fdb_cmd, &fdb_cmd_rsp); ++ if (ret) ++ return ret; ++ ++ WARN_ON(fdb_cmd.seqnum != fdb_cmd_rsp.seqnum); ++ return fdb_cmd_rsp.status == 1 ? 0 : -EINVAL; ++} ++EXPORT_SYMBOL_GPL(emac_fdb_flow_id_updated); +diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/ethernet/ti/icssg/icssg_config.h +index 92c2deaa3068..c884e9fa099e 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_config.h ++++ b/drivers/net/ethernet/ti/icssg/icssg_config.h +@@ -55,6 +55,7 @@ struct icssg_rxq_ctx { + #define ICSSG_FW_MGMT_FDB_CMD_TYPE 0x03 + #define ICSSG_FW_MGMT_CMD_TYPE 0x04 + #define ICSSG_FW_MGMT_PKT 0x80000000 ++#define ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW 0x05 + + struct icssg_r30_cmd { + u32 cmd[4]; +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +index fe2fd1bfc904..cb11635a8d12 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +@@ -164,11 +164,26 @@ static struct icssg_firmwares icssg_emac_firmwares[] = { + } + }; + +-static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac) ++static int prueth_start(struct rproc *rproc, const char *fw_name) ++{ ++ int ret; ++ ++ ret = rproc_set_firmware(rproc, fw_name); ++ if (ret) ++ return ret; ++ return rproc_boot(rproc); ++} ++ ++static void prueth_shutdown(struct rproc *rproc) ++{ ++ rproc_shutdown(rproc); ++} ++ ++static int prueth_emac_start(struct prueth *prueth) + { + struct icssg_firmwares *firmwares; + struct device *dev = prueth->dev; +- int slice, ret; ++ int ret, slice; + + if (prueth->is_switch_mode) + firmwares = icssg_switch_firmwares; +@@ -177,49 +192,126 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac) + else + firmwares = icssg_emac_firmwares; + +- slice = prueth_emac_slice(emac); +- if (slice < 0) { +- netdev_err(emac->ndev, "invalid port\n"); +- return -EINVAL; ++ for (slice = 0; slice < PRUETH_NUM_MACS; slice++) { ++ ret = prueth_start(prueth->pru[slice], firmwares[slice].pru); ++ if (ret) { ++ dev_err(dev, "failed to boot PRU%d: %d\n", slice, ret); ++ goto unwind_slices; ++ } ++ ++ ret = prueth_start(prueth->rtu[slice], firmwares[slice].rtu); ++ if (ret) { ++ dev_err(dev, "failed to boot RTU%d: %d\n", slice, ret); ++ rproc_shutdown(prueth->pru[slice]); ++ goto unwind_slices; ++ } ++ ++ ret = prueth_start(prueth->txpru[slice], firmwares[slice].txpru); ++ if (ret) { ++ dev_err(dev, "failed to boot TX_PRU%d: %d\n", slice, ret); ++ rproc_shutdown(prueth->rtu[slice]); ++ rproc_shutdown(prueth->pru[slice]); ++ goto unwind_slices; ++ } + } + +- ret = icssg_config(prueth, emac, slice); +- if (ret) +- return ret; ++ return 0; + +- ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru); +- ret = rproc_boot(prueth->pru[slice]); +- if (ret) { +- dev_err(dev, "failed to boot PRU%d: %d\n", slice, ret); +- return -EINVAL; ++unwind_slices: ++ while (--slice >= 0) { ++ prueth_shutdown(prueth->txpru[slice]); ++ prueth_shutdown(prueth->rtu[slice]); ++ prueth_shutdown(prueth->pru[slice]); + } + +- ret = rproc_set_firmware(prueth->rtu[slice], firmwares[slice].rtu); +- ret = rproc_boot(prueth->rtu[slice]); +- if (ret) { +- dev_err(dev, "failed to boot RTU%d: %d\n", slice, ret); +- goto halt_pru; ++ return ret; ++} ++ ++static void prueth_emac_stop(struct prueth *prueth) ++{ ++ int slice; ++ ++ for (slice = 0; slice < PRUETH_NUM_MACS; slice++) { ++ prueth_shutdown(prueth->txpru[slice]); ++ prueth_shutdown(prueth->rtu[slice]); ++ prueth_shutdown(prueth->pru[slice]); + } ++} ++ ++static int prueth_emac_common_start(struct prueth *prueth) ++{ ++ struct prueth_emac *emac; ++ int ret = 0; ++ int slice; ++ ++ if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1]) ++ return -EINVAL; ++ ++ /* clear SMEM and MSMC settings for all slices */ ++ memset_io(prueth->msmcram.va, 0, prueth->msmcram.size); ++ memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS); ++ ++ icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false); ++ icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false); ++ ++ if (prueth->is_switch_mode || prueth->is_hsr_offload_mode) ++ icssg_init_fw_offload_mode(prueth); ++ else ++ icssg_init_emac_mode(prueth); ++ ++ for (slice = 0; slice < PRUETH_NUM_MACS; slice++) { ++ emac = prueth->emac[slice]; ++ if (!emac) ++ continue; ++ ret = icssg_config(prueth, emac, slice); ++ if (ret) ++ goto disable_class; ++ } ++ ++ ret = prueth_emac_start(prueth); ++ if (ret) ++ goto disable_class; + +- ret = rproc_set_firmware(prueth->txpru[slice], firmwares[slice].txpru); +- ret = rproc_boot(prueth->txpru[slice]); ++ emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] : ++ prueth->emac[ICSS_SLICE1]; ++ ret = icss_iep_init(emac->iep, &prueth_iep_clockops, ++ emac, IEP_DEFAULT_CYCLE_TIME_NS); + if (ret) { +- dev_err(dev, "failed to boot TX_PRU%d: %d\n", slice, ret); +- goto halt_rtu; ++ dev_err(prueth->dev, "Failed to initialize IEP module\n"); ++ goto stop_pruss; + } + +- emac->fw_running = 1; + return 0; + +-halt_rtu: +- rproc_shutdown(prueth->rtu[slice]); ++stop_pruss: ++ prueth_emac_stop(prueth); + +-halt_pru: +- rproc_shutdown(prueth->pru[slice]); ++disable_class: ++ icssg_class_disable(prueth->miig_rt, ICSS_SLICE0); ++ icssg_class_disable(prueth->miig_rt, ICSS_SLICE1); + + return ret; + } + ++static int prueth_emac_common_stop(struct prueth *prueth) ++{ ++ struct prueth_emac *emac; ++ ++ if (!prueth->emac[ICSS_SLICE0] && !prueth->emac[ICSS_SLICE1]) ++ return -EINVAL; ++ ++ icssg_class_disable(prueth->miig_rt, ICSS_SLICE0); ++ icssg_class_disable(prueth->miig_rt, ICSS_SLICE1); ++ ++ prueth_emac_stop(prueth); ++ ++ emac = prueth->emac[ICSS_SLICE0] ? prueth->emac[ICSS_SLICE0] : ++ prueth->emac[ICSS_SLICE1]; ++ icss_iep_exit(emac->iep); ++ ++ return 0; ++} ++ + /* called back by PHY layer if there is change in link state of hw port*/ + static void emac_adjust_link(struct net_device *ndev) + { +@@ -374,9 +466,6 @@ static void prueth_iep_settime(void *clockops_data, u64 ns) + u32 cycletime; + int timeout; + +- if (!emac->fw_running) +- return; +- + sc_descp = emac->prueth->shram.va + TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET; + + cycletime = IEP_DEFAULT_CYCLE_TIME_NS; +@@ -543,23 +632,17 @@ static int emac_ndo_open(struct net_device *ndev) + { + struct prueth_emac *emac = netdev_priv(ndev); + int ret, i, num_data_chn = emac->tx_ch_num; ++ struct icssg_flow_cfg __iomem *flow_cfg; + struct prueth *prueth = emac->prueth; + int slice = prueth_emac_slice(emac); + struct device *dev = prueth->dev; + int max_rx_flows; + int rx_flow; + +- /* clear SMEM and MSMC settings for all slices */ +- if (!prueth->emacs_initialized) { +- memset_io(prueth->msmcram.va, 0, prueth->msmcram.size); +- memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS); +- } +- + /* set h/w MAC as user might have re-configured */ + ether_addr_copy(emac->mac_addr, ndev->dev_addr); + + icssg_class_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); +- icssg_class_default(prueth->miig_rt, slice, 0, false); + icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); + + /* Notify the stack of the actual queue counts. */ +@@ -597,18 +680,23 @@ static int emac_ndo_open(struct net_device *ndev) + goto cleanup_napi; + } + +- /* reset and start PRU firmware */ +- ret = prueth_emac_start(prueth, emac); +- if (ret) +- goto free_rx_irq; ++ if (!prueth->emacs_initialized) { ++ ret = prueth_emac_common_start(prueth); ++ if (ret) ++ goto free_rx_irq; ++ } + +- icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu); ++ flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET; ++ writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow); ++ ret = emac_fdb_flow_id_updated(emac); + +- if (!prueth->emacs_initialized) { +- ret = icss_iep_init(emac->iep, &prueth_iep_clockops, +- emac, IEP_DEFAULT_CYCLE_TIME_NS); ++ if (ret) { ++ netdev_err(ndev, "Failed to update Rx Flow ID %d", ret); ++ goto stop; + } + ++ icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu); ++ + ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq, + IRQF_ONESHOT, dev_name(dev), emac); + if (ret) +@@ -653,7 +741,8 @@ static int emac_ndo_open(struct net_device *ndev) + free_tx_ts_irq: + free_irq(emac->tx_ts_irq, emac); + stop: +- prueth_emac_stop(emac); ++ if (!prueth->emacs_initialized) ++ prueth_emac_common_stop(prueth); + free_rx_irq: + free_irq(emac->rx_chns.irq[rx_flow], emac); + cleanup_napi: +@@ -689,8 +778,6 @@ static int emac_ndo_stop(struct net_device *ndev) + if (ndev->phydev) + phy_stop(ndev->phydev); + +- icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac)); +- + if (emac->prueth->is_hsr_offload_mode) + __dev_mc_unsync(ndev, icssg_prueth_hsr_del_mcast); + else +@@ -728,11 +815,9 @@ static int emac_ndo_stop(struct net_device *ndev) + /* Destroying the queued work in ndo_stop() */ + cancel_delayed_work_sync(&emac->stats_work); + +- if (prueth->emacs_initialized == 1) +- icss_iep_exit(emac->iep); +- + /* stop PRUs */ +- prueth_emac_stop(emac); ++ if (prueth->emacs_initialized == 1) ++ prueth_emac_common_stop(prueth); + + free_irq(emac->tx_ts_irq, emac); + +@@ -1010,10 +1095,11 @@ static void prueth_offload_fwd_mark_update(struct prueth *prueth) + } + } + +-static void prueth_emac_restart(struct prueth *prueth) ++static int prueth_emac_restart(struct prueth *prueth) + { + struct prueth_emac *emac0 = prueth->emac[PRUETH_MAC0]; + struct prueth_emac *emac1 = prueth->emac[PRUETH_MAC1]; ++ int ret; + + /* Detach the net_device for both PRUeth ports*/ + if (netif_running(emac0->ndev)) +@@ -1022,36 +1108,46 @@ static void prueth_emac_restart(struct prueth *prueth) + netif_device_detach(emac1->ndev); + + /* Disable both PRUeth ports */ +- icssg_set_port_state(emac0, ICSSG_EMAC_PORT_DISABLE); +- icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE); ++ ret = icssg_set_port_state(emac0, ICSSG_EMAC_PORT_DISABLE); ++ ret |= icssg_set_port_state(emac1, ICSSG_EMAC_PORT_DISABLE); ++ if (ret) ++ return ret; + + /* Stop both pru cores for both PRUeth ports*/ +- prueth_emac_stop(emac0); +- prueth->emacs_initialized--; +- prueth_emac_stop(emac1); +- prueth->emacs_initialized--; ++ ret = prueth_emac_common_stop(prueth); ++ if (ret) { ++ dev_err(prueth->dev, "Failed to stop the firmwares"); ++ return ret; ++ } + + /* Start both pru cores for both PRUeth ports */ +- prueth_emac_start(prueth, emac0); +- prueth->emacs_initialized++; +- prueth_emac_start(prueth, emac1); +- prueth->emacs_initialized++; ++ ret = prueth_emac_common_start(prueth); ++ if (ret) { ++ dev_err(prueth->dev, "Failed to start the firmwares"); ++ return ret; ++ } + + /* Enable forwarding for both PRUeth ports */ +- icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD); +- icssg_set_port_state(emac1, ICSSG_EMAC_PORT_FORWARD); ++ ret = icssg_set_port_state(emac0, ICSSG_EMAC_PORT_FORWARD); ++ ret |= icssg_set_port_state(emac1, ICSSG_EMAC_PORT_FORWARD); + + /* Attache net_device for both PRUeth ports */ + netif_device_attach(emac0->ndev); + netif_device_attach(emac1->ndev); ++ ++ return ret; + } + + static void icssg_change_mode(struct prueth *prueth) + { + struct prueth_emac *emac; +- int mac; ++ int mac, ret; + +- prueth_emac_restart(prueth); ++ ret = prueth_emac_restart(prueth); ++ if (ret) { ++ dev_err(prueth->dev, "Failed to restart the firmwares, aborting the process"); ++ return; ++ } + + for (mac = PRUETH_MAC0; mac < PRUETH_NUM_MACS; mac++) { + emac = prueth->emac[mac]; +@@ -1130,13 +1226,18 @@ static void prueth_netdevice_port_unlink(struct net_device *ndev) + { + struct prueth_emac *emac = netdev_priv(ndev); + struct prueth *prueth = emac->prueth; ++ int ret; + + prueth->br_members &= ~BIT(emac->port_id); + + if (prueth->is_switch_mode) { + prueth->is_switch_mode = false; + emac->port_vlan = 0; +- prueth_emac_restart(prueth); ++ ret = prueth_emac_restart(prueth); ++ if (ret) { ++ dev_err(prueth->dev, "Failed to restart the firmwares, aborting the process"); ++ return; ++ } + } + + prueth_offload_fwd_mark_update(prueth); +@@ -1185,6 +1286,7 @@ static void prueth_hsr_port_unlink(struct net_device *ndev) + struct prueth *prueth = emac->prueth; + struct prueth_emac *emac0; + struct prueth_emac *emac1; ++ int ret; + + emac0 = prueth->emac[PRUETH_MAC0]; + emac1 = prueth->emac[PRUETH_MAC1]; +@@ -1195,7 +1297,11 @@ static void prueth_hsr_port_unlink(struct net_device *ndev) + emac0->port_vlan = 0; + emac1->port_vlan = 0; + prueth->hsr_dev = NULL; +- prueth_emac_restart(prueth); ++ ret = prueth_emac_restart(prueth); ++ if (ret) { ++ dev_err(prueth->dev, "Failed to restart the firmwares, aborting the process"); ++ return; ++ } + netdev_dbg(ndev, "Disabling HSR Offload mode\n"); + } + } +@@ -1370,13 +1476,10 @@ static int prueth_probe(struct platform_device *pdev) + prueth->pa_stats = NULL; + } + +- if (eth0_node) { ++ if (eth0_node || eth1_node) { + ret = prueth_get_cores(prueth, ICSS_SLICE0, false); + if (ret) + goto put_cores; +- } +- +- if (eth1_node) { + ret = prueth_get_cores(prueth, ICSS_SLICE1, false); + if (ret) + goto put_cores; +@@ -1575,14 +1678,12 @@ static int prueth_probe(struct platform_device *pdev) + pruss_put(prueth->pruss); + + put_cores: +- if (eth1_node) { +- prueth_put_cores(prueth, ICSS_SLICE1); +- of_node_put(eth1_node); +- } +- +- if (eth0_node) { ++ if (eth0_node || eth1_node) { + prueth_put_cores(prueth, ICSS_SLICE0); + of_node_put(eth0_node); ++ ++ prueth_put_cores(prueth, ICSS_SLICE1); ++ of_node_put(eth1_node); + } + + return ret; +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +index f5c1d473e9f9..5473315ea204 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +@@ -140,7 +140,6 @@ struct prueth_rx_chn { + /* data for each emac port */ + struct prueth_emac { + bool is_sr1; +- bool fw_running; + struct prueth *prueth; + struct net_device *ndev; + u8 mac_addr[6]; +@@ -361,6 +360,8 @@ int icssg_set_port_state(struct prueth_emac *emac, + enum icssg_port_state_cmd state); + void icssg_config_set_speed(struct prueth_emac *emac); + void icssg_config_half_duplex(struct prueth_emac *emac); ++void icssg_init_emac_mode(struct prueth *prueth); ++void icssg_init_fw_offload_mode(struct prueth *prueth); + + /* Buffer queue helpers */ + int icssg_queue_pop(struct prueth *prueth, u8 queue); +@@ -377,6 +378,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask, + u8 untag_mask, bool add); + u16 icssg_get_pvid(struct prueth_emac *emac); + void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port); ++int emac_fdb_flow_id_updated(struct prueth_emac *emac); + #define prueth_napi_to_tx_chn(pnapi) \ + container_of(pnapi, struct prueth_tx_chn, napi_tx) + +@@ -407,7 +409,6 @@ void emac_rx_timestamp(struct prueth_emac *emac, + struct sk_buff *skb, u32 *psdata); + enum netdev_tx icssg_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev); + irqreturn_t prueth_rx_irq(int irq, void *dev_id); +-void prueth_emac_stop(struct prueth_emac *emac); + void prueth_cleanup_tx_ts(struct prueth_emac *emac); + int icssg_napi_rx_poll(struct napi_struct *napi_rx, int budget); + int prueth_prepare_rx_chan(struct prueth_emac *emac, +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c +index 292f04d29f4f..f88cdc8f012f 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c +@@ -440,7 +440,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac) + goto halt_pru; + } + +- emac->fw_running = 1; + return 0; + + halt_pru: +@@ -449,6 +448,29 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac) + return ret; + } + ++static void prueth_emac_stop(struct prueth_emac *emac) ++{ ++ struct prueth *prueth = emac->prueth; ++ int slice; ++ ++ switch (emac->port_id) { ++ case PRUETH_PORT_MII0: ++ slice = ICSS_SLICE0; ++ break; ++ case PRUETH_PORT_MII1: ++ slice = ICSS_SLICE1; ++ break; ++ default: ++ netdev_err(emac->ndev, "invalid port\n"); ++ return; ++ } ++ ++ if (!emac->is_sr1) ++ rproc_shutdown(prueth->txpru[slice]); ++ rproc_shutdown(prueth->rtu[slice]); ++ rproc_shutdown(prueth->pru[slice]); ++} ++ + /** + * emac_ndo_open - EMAC device open + * @ndev: network adapter device +-- +2.39.5 + diff --git a/queue-6.12/net-wwan-iosm-properly-check-for-valid-exec-stage-in.patch b/queue-6.12/net-wwan-iosm-properly-check-for-valid-exec-stage-in.patch new file mode 100644 index 00000000000..953332f7323 --- /dev/null +++ b/queue-6.12/net-wwan-iosm-properly-check-for-valid-exec-stage-in.patch @@ -0,0 +1,47 @@ +From 4e8661bf696abd8b22f100cb08e518df08400952 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 29 Dec 2024 17:46:58 +0100 +Subject: net: wwan: iosm: Properly check for valid exec stage in + ipc_mmio_init() + +From: Maciej S. Szmigiero + +[ Upstream commit a7af435df0e04cfb4a4004136d597c42639a2ae7 ] + +ipc_mmio_init() used the post-decrement operator in its loop continuing +condition of "retries" counter being "> 0", which meant that when this +condition caused loop exit "retries" counter reached -1. + +But the later valid exec stage failure check only tests for "retries" +counter being exactly zero, so it didn't trigger in this case (but +would wrongly trigger if the code reaches a valid exec stage in the +very last loop iteration). + +Fix this by using the pre-decrement operator instead, so the loop counter +is exactly zero on valid exec stage failure. + +Fixes: dc0514f5d828 ("net: iosm: mmio scratchpad") +Signed-off-by: Maciej S. Szmigiero +Link: https://patch.msgid.link/8b19125a825f9dcdd81c667c1e5c48ba28d505a6.1735490770.git.mail@maciej.szmigiero.name +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/wwan/iosm/iosm_ipc_mmio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wwan/iosm/iosm_ipc_mmio.c b/drivers/net/wwan/iosm/iosm_ipc_mmio.c +index 63eb08c43c05..6764c13530b9 100644 +--- a/drivers/net/wwan/iosm/iosm_ipc_mmio.c ++++ b/drivers/net/wwan/iosm/iosm_ipc_mmio.c +@@ -104,7 +104,7 @@ struct iosm_mmio *ipc_mmio_init(void __iomem *mmio, struct device *dev) + break; + + msleep(20); +- } while (retries-- > 0); ++ } while (--retries > 0); + + if (!retries) { + dev_err(ipc_mmio->dev, "invalid exec stage %X", stage); +-- +2.39.5 + diff --git a/queue-6.12/net-wwan-t7xx-fix-fsm-command-timeout-issue.patch b/queue-6.12/net-wwan-t7xx-fix-fsm-command-timeout-issue.patch new file mode 100644 index 00000000000..2df5c0c4349 --- /dev/null +++ b/queue-6.12/net-wwan-t7xx-fix-fsm-command-timeout-issue.patch @@ -0,0 +1,141 @@ +From d37e6b3e07f00dc547068995790f3afb376c8991 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Dec 2024 12:15:52 +0800 +Subject: net: wwan: t7xx: Fix FSM command timeout issue + +From: Jinjian Song + +[ Upstream commit 4f619d518db9cd1a933c3a095a5f95d0c1584ae8 ] + +When driver processes the internal state change command, it use an +asynchronous thread to process the command operation. If the main +thread detects that the task has timed out, the asynchronous thread +will panic when executing the completion notification because the +main thread completion object has been released. + +BUG: unable to handle page fault for address: fffffffffffffff8 +PGD 1f283a067 P4D 1f283a067 PUD 1f283c067 PMD 0 +Oops: 0000 [#1] PREEMPT SMP NOPTI +RIP: 0010:complete_all+0x3e/0xa0 +[...] +Call Trace: + + ? __die_body+0x68/0xb0 + ? page_fault_oops+0x379/0x3e0 + ? exc_page_fault+0x69/0xa0 + ? asm_exc_page_fault+0x22/0x30 + ? complete_all+0x3e/0xa0 + fsm_main_thread+0xa3/0x9c0 [mtk_t7xx (HASH:1400 5)] + ? __pfx_autoremove_wake_function+0x10/0x10 + kthread+0xd8/0x110 + ? __pfx_fsm_main_thread+0x10/0x10 [mtk_t7xx (HASH:1400 5)] + ? __pfx_kthread+0x10/0x10 + ret_from_fork+0x38/0x50 + ? __pfx_kthread+0x10/0x10 + ret_from_fork_asm+0x1b/0x30 + +[...] +CR2: fffffffffffffff8 +---[ end trace 0000000000000000 ]--- + +Use the reference counter to ensure safe release as Sergey suggests: +https://lore.kernel.org/all/da90f64c-260a-4329-87bf-1f9ff20a5951@gmail.com/ + +Fixes: 13e920d93e37 ("net: wwan: t7xx: Add core components") +Signed-off-by: Jinjian Song +Acked-by: Sergey Ryazanov +Link: https://patch.msgid.link/20241224041552.8711-1-jinjian.song@fibocom.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/wwan/t7xx/t7xx_state_monitor.c | 26 ++++++++++++++-------- + drivers/net/wwan/t7xx/t7xx_state_monitor.h | 5 +++-- + 2 files changed, 20 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c +index 3931c7a13f5a..cbdbb91e8381 100644 +--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c ++++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c +@@ -104,14 +104,21 @@ void t7xx_fsm_broadcast_state(struct t7xx_fsm_ctl *ctl, enum md_state state) + fsm_state_notify(ctl->md, state); + } + ++static void fsm_release_command(struct kref *ref) ++{ ++ struct t7xx_fsm_command *cmd = container_of(ref, typeof(*cmd), refcnt); ++ ++ kfree(cmd); ++} ++ + static void fsm_finish_command(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd, int result) + { + if (cmd->flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) { +- *cmd->ret = result; +- complete_all(cmd->done); ++ cmd->result = result; ++ complete_all(&cmd->done); + } + +- kfree(cmd); ++ kref_put(&cmd->refcnt, fsm_release_command); + } + + static void fsm_del_kf_event(struct t7xx_fsm_event *event) +@@ -475,7 +482,6 @@ static int fsm_main_thread(void *data) + + int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id, unsigned int flag) + { +- DECLARE_COMPLETION_ONSTACK(done); + struct t7xx_fsm_command *cmd; + unsigned long flags; + int ret; +@@ -487,11 +493,13 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id + INIT_LIST_HEAD(&cmd->entry); + cmd->cmd_id = cmd_id; + cmd->flag = flag; ++ kref_init(&cmd->refcnt); + if (flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) { +- cmd->done = &done; +- cmd->ret = &ret; ++ init_completion(&cmd->done); ++ kref_get(&cmd->refcnt); + } + ++ kref_get(&cmd->refcnt); + spin_lock_irqsave(&ctl->command_lock, flags); + list_add_tail(&cmd->entry, &ctl->command_queue); + spin_unlock_irqrestore(&ctl->command_lock, flags); +@@ -501,11 +509,11 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id + if (flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) { + unsigned long wait_ret; + +- wait_ret = wait_for_completion_timeout(&done, ++ wait_ret = wait_for_completion_timeout(&cmd->done, + msecs_to_jiffies(FSM_CMD_TIMEOUT_MS)); +- if (!wait_ret) +- return -ETIMEDOUT; + ++ ret = wait_ret ? cmd->result : -ETIMEDOUT; ++ kref_put(&cmd->refcnt, fsm_release_command); + return ret; + } + +diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.h b/drivers/net/wwan/t7xx/t7xx_state_monitor.h +index 7b0a9baf488c..6e0601bb752e 100644 +--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.h ++++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.h +@@ -110,8 +110,9 @@ struct t7xx_fsm_command { + struct list_head entry; + enum t7xx_fsm_cmd_state cmd_id; + unsigned int flag; +- struct completion *done; +- int *ret; ++ struct completion done; ++ int result; ++ struct kref refcnt; + }; + + struct t7xx_fsm_notifier { +-- +2.39.5 + diff --git a/queue-6.12/netdev-genl-avoid-empty-messages-in-napi-get.patch b/queue-6.12/netdev-genl-avoid-empty-messages-in-napi-get.patch new file mode 100644 index 00000000000..013e8ebe1d8 --- /dev/null +++ b/queue-6.12/netdev-genl-avoid-empty-messages-in-napi-get.patch @@ -0,0 +1,44 @@ +From b15d870b78b8ba0c172fce91caae4ddca7db5905 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Dec 2024 19:28:32 -0800 +Subject: netdev-genl: avoid empty messages in napi get + +From: Jakub Kicinski + +[ Upstream commit 4a25201aa46ce88e8e31f9ccdec0e4e3dd6bb736 ] + +Empty netlink responses from do() are not correct (as opposed to +dump() where not dumping anything is perfectly fine). +We should return an error if the target object does not exist, +in this case if the netdev is down we "hide" the NAPI instances. + +Fixes: 27f91aaf49b3 ("netdev-genl: Add netlink framework functions for napi") +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20241219032833.1165433-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/netdev-genl.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c +index 7ce22f40db5b..d58270b48cb2 100644 +--- a/net/core/netdev-genl.c ++++ b/net/core/netdev-genl.c +@@ -228,8 +228,12 @@ int netdev_nl_napi_get_doit(struct sk_buff *skb, struct genl_info *info) + rcu_read_unlock(); + rtnl_unlock(); + +- if (err) ++ if (err) { ++ goto err_free_msg; ++ } else if (!rsp->len) { ++ err = -ENOENT; + goto err_free_msg; ++ } + + return genlmsg_reply(rsp, info); + +-- +2.39.5 + diff --git a/queue-6.12/netfilter-nft_set_hash-unaligned-atomic-read-on-stru.patch b/queue-6.12/netfilter-nft_set_hash-unaligned-atomic-read-on-stru.patch new file mode 100644 index 00000000000..75a0ecd81de --- /dev/null +++ b/queue-6.12/netfilter-nft_set_hash-unaligned-atomic-read-on-stru.patch @@ -0,0 +1,96 @@ +From 7ddda8cade93b0a4c76588bb46c9e82e310902c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 21 Dec 2024 00:29:20 +0100 +Subject: netfilter: nft_set_hash: unaligned atomic read on struct nft_set_ext + +From: Pablo Neira Ayuso + +[ Upstream commit 542ed8145e6f9392e3d0a86a0e9027d2ffd183e4 ] + +Access to genmask field in struct nft_set_ext results in unaligned +atomic read: + +[ 72.130109] Unable to handle kernel paging request at virtual address ffff0000c2bb708c +[ 72.131036] Mem abort info: +[ 72.131213] ESR = 0x0000000096000021 +[ 72.131446] EC = 0x25: DABT (current EL), IL = 32 bits +[ 72.132209] SET = 0, FnV = 0 +[ 72.133216] EA = 0, S1PTW = 0 +[ 72.134080] FSC = 0x21: alignment fault +[ 72.135593] Data abort info: +[ 72.137194] ISV = 0, ISS = 0x00000021, ISS2 = 0x00000000 +[ 72.142351] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 +[ 72.145989] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 +[ 72.150115] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000237d27000 +[ 72.154893] [ffff0000c2bb708c] pgd=0000000000000000, p4d=180000023ffff403, pud=180000023f84b403, pmd=180000023f835403, ++pte=0068000102bb7707 +[ 72.163021] Internal error: Oops: 0000000096000021 [#1] SMP +[...] +[ 72.170041] CPU: 7 UID: 0 PID: 54 Comm: kworker/7:0 Tainted: G E 6.13.0-rc3+ #2 +[ 72.170509] Tainted: [E]=UNSIGNED_MODULE +[ 72.170720] Hardware name: QEMU QEMU Virtual Machine, BIOS edk2-stable202302-for-qemu 03/01/2023 +[ 72.171192] Workqueue: events_power_efficient nft_rhash_gc [nf_tables] +[ 72.171552] pstate: 21400005 (nzCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) +[ 72.171915] pc : nft_rhash_gc+0x200/0x2d8 [nf_tables] +[ 72.172166] lr : nft_rhash_gc+0x128/0x2d8 [nf_tables] +[ 72.172546] sp : ffff800081f2bce0 +[ 72.172724] x29: ffff800081f2bd40 x28: ffff0000c2bb708c x27: 0000000000000038 +[ 72.173078] x26: ffff0000c6780ef0 x25: ffff0000c643df00 x24: ffff0000c6778f78 +[ 72.173431] x23: 000000000000001a x22: ffff0000c4b1f000 x21: ffff0000c6780f78 +[ 72.173782] x20: ffff0000c2bb70dc x19: ffff0000c2bb7080 x18: 0000000000000000 +[ 72.174135] x17: ffff0000c0a4e1c0 x16: 0000000000003000 x15: 0000ac26d173b978 +[ 72.174485] x14: ffffffffffffffff x13: 0000000000000030 x12: ffff0000c6780ef0 +[ 72.174841] x11: 0000000000000000 x10: ffff800081f2bcf8 x9 : ffff0000c3000000 +[ 72.175193] x8 : 00000000000004be x7 : 0000000000000000 x6 : 0000000000000000 +[ 72.175544] x5 : 0000000000000040 x4 : ffff0000c3000010 x3 : 0000000000000000 +[ 72.175871] x2 : 0000000000003a98 x1 : ffff0000c2bb708c x0 : 0000000000000004 +[ 72.176207] Call trace: +[ 72.176316] nft_rhash_gc+0x200/0x2d8 [nf_tables] (P) +[ 72.176653] process_one_work+0x178/0x3d0 +[ 72.176831] worker_thread+0x200/0x3f0 +[ 72.176995] kthread+0xe8/0xf8 +[ 72.177130] ret_from_fork+0x10/0x20 +[ 72.177289] Code: 54fff984 d503201f d2800080 91003261 (f820303f) +[ 72.177557] ---[ end trace 0000000000000000 ]--- + +Align struct nft_set_ext to word size to address this and +documentation it. + +pahole reports that this increases the size of elements for rhash and +pipapo in 8 bytes on x86_64. + +Fixes: 7ffc7481153b ("netfilter: nft_set_hash: skip duplicated elements pending gc run") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_tables.h | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index 91ae20cb7648..471c353d32a4 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -733,15 +733,18 @@ struct nft_set_ext_tmpl { + /** + * struct nft_set_ext - set extensions + * +- * @genmask: generation mask ++ * @genmask: generation mask, but also flags (see NFT_SET_ELEM_DEAD_BIT) + * @offset: offsets of individual extension types + * @data: beginning of extension data ++ * ++ * This structure must be aligned to word size, otherwise atomic bitops ++ * on genmask field can cause alignment failure on some archs. + */ + struct nft_set_ext { + u8 genmask; + u8 offset[NFT_SET_EXT_NUM]; + char data[]; +-}; ++} __aligned(BITS_PER_LONG / 8); + + static inline void nft_set_ext_prepare(struct nft_set_ext_tmpl *tmpl) + { +-- +2.39.5 + diff --git a/queue-6.12/netrom-check-buffer-length-before-accessing-it.patch b/queue-6.12/netrom-check-buffer-length-before-accessing-it.patch new file mode 100644 index 00000000000..e42b79eafcc --- /dev/null +++ b/queue-6.12/netrom-check-buffer-length-before-accessing-it.patch @@ -0,0 +1,105 @@ +From cd1845f6f501d3266898ff3d6e94e00290eb6915 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Dec 2024 08:23:07 +0000 +Subject: netrom: check buffer length before accessing it + +From: Ilya Shchipletsov + +[ Upstream commit a4fd163aed2edd967a244499754dec991d8b4c7d ] + +Syzkaller reports an uninit value read from ax25cmp when sending raw message +through ieee802154 implementation. + +===================================================== +BUG: KMSAN: uninit-value in ax25cmp+0x3a5/0x460 net/ax25/ax25_addr.c:119 + ax25cmp+0x3a5/0x460 net/ax25/ax25_addr.c:119 + nr_dev_get+0x20e/0x450 net/netrom/nr_route.c:601 + nr_route_frame+0x1a2/0xfc0 net/netrom/nr_route.c:774 + nr_xmit+0x5a/0x1c0 net/netrom/nr_dev.c:144 + __netdev_start_xmit include/linux/netdevice.h:4940 [inline] + netdev_start_xmit include/linux/netdevice.h:4954 [inline] + xmit_one net/core/dev.c:3548 [inline] + dev_hard_start_xmit+0x247/0xa10 net/core/dev.c:3564 + __dev_queue_xmit+0x33b8/0x5130 net/core/dev.c:4349 + dev_queue_xmit include/linux/netdevice.h:3134 [inline] + raw_sendmsg+0x654/0xc10 net/ieee802154/socket.c:299 + ieee802154_sock_sendmsg+0x91/0xc0 net/ieee802154/socket.c:96 + sock_sendmsg_nosec net/socket.c:730 [inline] + __sock_sendmsg net/socket.c:745 [inline] + ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2584 + ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2638 + __sys_sendmsg net/socket.c:2667 [inline] + __do_sys_sendmsg net/socket.c:2676 [inline] + __se_sys_sendmsg net/socket.c:2674 [inline] + __x64_sys_sendmsg+0x307/0x490 net/socket.c:2674 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0x44/0x110 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x63/0x6b + +Uninit was created at: + slab_post_alloc_hook+0x129/0xa70 mm/slab.h:768 + slab_alloc_node mm/slub.c:3478 [inline] + kmem_cache_alloc_node+0x5e9/0xb10 mm/slub.c:3523 + kmalloc_reserve+0x13d/0x4a0 net/core/skbuff.c:560 + __alloc_skb+0x318/0x740 net/core/skbuff.c:651 + alloc_skb include/linux/skbuff.h:1286 [inline] + alloc_skb_with_frags+0xc8/0xbd0 net/core/skbuff.c:6334 + sock_alloc_send_pskb+0xa80/0xbf0 net/core/sock.c:2780 + sock_alloc_send_skb include/net/sock.h:1884 [inline] + raw_sendmsg+0x36d/0xc10 net/ieee802154/socket.c:282 + ieee802154_sock_sendmsg+0x91/0xc0 net/ieee802154/socket.c:96 + sock_sendmsg_nosec net/socket.c:730 [inline] + __sock_sendmsg net/socket.c:745 [inline] + ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2584 + ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2638 + __sys_sendmsg net/socket.c:2667 [inline] + __do_sys_sendmsg net/socket.c:2676 [inline] + __se_sys_sendmsg net/socket.c:2674 [inline] + __x64_sys_sendmsg+0x307/0x490 net/socket.c:2674 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0x44/0x110 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x63/0x6b + +CPU: 0 PID: 5037 Comm: syz-executor166 Not tainted 6.7.0-rc7-syzkaller-00003-gfbafc3e621c3 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023 +===================================================== + +This issue occurs because the skb buffer is too small, and it's actual +allocation is aligned. This hides an actual issue, which is that nr_route_frame +does not validate the buffer size before using it. + +Fix this issue by checking skb->len before accessing any fields in skb->data. + +Found by Linux Verification Center (linuxtesting.org) with Syzkaller. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Co-developed-by: Nikita Marushkin +Signed-off-by: Nikita Marushkin +Signed-off-by: Ilya Shchipletsov +Link: https://patch.msgid.link/20241219082308.3942-1-rabbelkin@mail.ru +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/netrom/nr_route.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c +index 2b5e246b8d9a..b94cb2ffbaf8 100644 +--- a/net/netrom/nr_route.c ++++ b/net/netrom/nr_route.c +@@ -754,6 +754,12 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25) + int ret; + struct sk_buff *skbn; + ++ /* ++ * Reject malformed packets early. Check that it contains at least 2 ++ * addresses and 1 byte more for Time-To-Live ++ */ ++ if (skb->len < 2 * sizeof(ax25_address) + 1) ++ return 0; + + nr_src = (ax25_address *)(skb->data + 0); + nr_dest = (ax25_address *)(skb->data + 7); +-- +2.39.5 + diff --git a/queue-6.12/nvme-pci-512-byte-aligned-dma-pool-segment-quirk.patch b/queue-6.12/nvme-pci-512-byte-aligned-dma-pool-segment-quirk.patch new file mode 100644 index 00000000000..d08e838343c --- /dev/null +++ b/queue-6.12/nvme-pci-512-byte-aligned-dma-pool-segment-quirk.patch @@ -0,0 +1,100 @@ +From 1bb5a249056beb369ab2f871a1ee727a6fb3d47d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Nov 2024 19:50:00 +0000 +Subject: nvme-pci: 512 byte aligned dma pool segment quirk +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Robert Beckett + +[ Upstream commit ebefac5647968679f6ef5803e5d35a71997d20fa ] + +We initially introduced a quick fix limiting the queue depth to 1 as +experimentation showed that it fixed data corruption on 64GB steamdecks. + +Further experimentation revealed corruption only happens when the last +PRP data element aligns to the end of the page boundary. The device +appears to treat this as a PRP chain to a new list instead of the data +element that it actually is. This implementation is in violation of the +spec. Encountering this errata with the Linux driver requires the host +request a 128k transfer and coincidently be handed the last small pool +dma buffer within a page. + +The QD1 quirk effectly works around this because the last data PRP +always was at a 248 byte offset from the page start, so it never +appeared at the end of the page, but comes at the expense of throttling +IO and wasting the remainder of the PRP page beyond 256 bytes. Also to +note, the MDTS on these devices is small enough that the "large" prp +pool can hold enough PRP elements to never reach the end, so that pool +is not a problem either. + +Introduce a new quirk to ensure the small pool is always aligned such +that the last PRP element can't appear a the end of the page. This comes +at the expense of wasting 256 bytes per small pool page allocated. + +Link: https://lore.kernel.org/linux-nvme/20241113043151.GA20077@lst.de/T/#u +Fixes: 83bdfcbdbe5d ("nvme-pci: qdepth 1 quirk") +Cc: Paweł Anikiel +Signed-off-by: Robert Beckett +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/nvme.h | 5 +++++ + drivers/nvme/host/pci.c | 9 +++++++-- + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index 093cb423f536..61bba5513de0 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -173,6 +173,11 @@ enum nvme_quirks { + * MSI (but not MSI-X) interrupts are broken and never fire. + */ + NVME_QUIRK_BROKEN_MSI = (1 << 21), ++ ++ /* ++ * Align dma pool segment size to 512 bytes ++ */ ++ NVME_QUIRK_DMAPOOL_ALIGN_512 = (1 << 22), + }; + + /* +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 55af3dfbc260..76b3f7b396c8 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2690,15 +2690,20 @@ static int nvme_disable_prepare_reset(struct nvme_dev *dev, bool shutdown) + + static int nvme_setup_prp_pools(struct nvme_dev *dev) + { ++ size_t small_align = 256; ++ + dev->prp_page_pool = dma_pool_create("prp list page", dev->dev, + NVME_CTRL_PAGE_SIZE, + NVME_CTRL_PAGE_SIZE, 0); + if (!dev->prp_page_pool) + return -ENOMEM; + ++ if (dev->ctrl.quirks & NVME_QUIRK_DMAPOOL_ALIGN_512) ++ small_align = 512; ++ + /* Optimisation for I/Os between 4k and 128k */ + dev->prp_small_pool = dma_pool_create("prp list 256", dev->dev, +- 256, 256, 0); ++ 256, small_align, 0); + if (!dev->prp_small_pool) { + dma_pool_destroy(dev->prp_page_pool); + return -ENOMEM; +@@ -3446,7 +3451,7 @@ static const struct pci_device_id nvme_id_table[] = { + { PCI_VDEVICE(REDHAT, 0x0010), /* Qemu emulated controller */ + .driver_data = NVME_QUIRK_BOGUS_NID, }, + { PCI_DEVICE(0x1217, 0x8760), /* O2 Micro 64GB Steam Deck */ +- .driver_data = NVME_QUIRK_QDEPTH_ONE }, ++ .driver_data = NVME_QUIRK_DMAPOOL_ALIGN_512, }, + { PCI_DEVICE(0x126f, 0x2262), /* Silicon Motion generic */ + .driver_data = NVME_QUIRK_NO_DEEPEST_PS | + NVME_QUIRK_BOGUS_NID, }, +-- +2.39.5 + diff --git a/queue-6.12/nvmet-don-t-overflow-subsysnqn.patch b/queue-6.12/nvmet-don-t-overflow-subsysnqn.patch new file mode 100644 index 00000000000..655320cad71 --- /dev/null +++ b/queue-6.12/nvmet-don-t-overflow-subsysnqn.patch @@ -0,0 +1,70 @@ +From 0f8c6504f80e96e7eae467c327516dfc8ed7d6ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Dec 2024 10:49:57 -0800 +Subject: nvmet: Don't overflow subsysnqn + +From: Leo Stone + +[ Upstream commit 4db3d750ac7e894278ef1cb1c53cc7d883060496 ] + +nvmet_root_discovery_nqn_store treats the subsysnqn string like a fixed +size buffer, even though it is dynamically allocated to the size of the +string. + +Create a new string with kstrndup instead of using the old buffer. + +Reported-by: syzbot+ff4aab278fa7e27e0f9e@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=ff4aab278fa7e27e0f9e +Fixes: 95409e277d83 ("nvmet: implement unique discovery NQN") +Signed-off-by: Leo Stone +Reviewed-by: Sagi Grimberg +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/configfs.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c +index 685e89b35d33..cfbab198693b 100644 +--- a/drivers/nvme/target/configfs.c ++++ b/drivers/nvme/target/configfs.c +@@ -2227,12 +2227,17 @@ static ssize_t nvmet_root_discovery_nqn_store(struct config_item *item, + const char *page, size_t count) + { + struct list_head *entry; ++ char *old_nqn, *new_nqn; + size_t len; + + len = strcspn(page, "\n"); + if (!len || len > NVMF_NQN_FIELD_LEN - 1) + return -EINVAL; + ++ new_nqn = kstrndup(page, len, GFP_KERNEL); ++ if (!new_nqn) ++ return -ENOMEM; ++ + down_write(&nvmet_config_sem); + list_for_each(entry, &nvmet_subsystems_group.cg_children) { + struct config_item *item = +@@ -2241,13 +2246,15 @@ static ssize_t nvmet_root_discovery_nqn_store(struct config_item *item, + if (!strncmp(config_item_name(item), page, len)) { + pr_err("duplicate NQN %s\n", config_item_name(item)); + up_write(&nvmet_config_sem); ++ kfree(new_nqn); + return -EINVAL; + } + } +- memset(nvmet_disc_subsys->subsysnqn, 0, NVMF_NQN_FIELD_LEN); +- memcpy(nvmet_disc_subsys->subsysnqn, page, len); ++ old_nqn = nvmet_disc_subsys->subsysnqn; ++ nvmet_disc_subsys->subsysnqn = new_nqn; + up_write(&nvmet_config_sem); + ++ kfree(old_nqn); + return len; + } + +-- +2.39.5 + diff --git a/queue-6.12/rdma-bnxt_re-add-check-for-path-mtu-in-modify_qp.patch b/queue-6.12/rdma-bnxt_re-add-check-for-path-mtu-in-modify_qp.patch new file mode 100644 index 00000000000..8ab763eb1dd --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-add-check-for-path-mtu-in-modify_qp.patch @@ -0,0 +1,64 @@ +From 3e1f1a6966a0e7ad775aefd3a805a7122c23e10a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Dec 2024 14:09:28 +0530 +Subject: RDMA/bnxt_re: Add check for path mtu in modify_qp + +From: Saravanan Vajravel + +[ Upstream commit 798653a0ee30d3cd495099282751c0f248614ae7 ] + +When RDMA app configures path MTU, add a check in modify_qp verb +to make sure that it doesn't go beyond interface MTU. If this +check fails, driver will fail the modify_qp verb. + +Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") +Reviewed-by: Kalesh AP +Signed-off-by: Saravanan Vajravel +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/20241211083931.968831-3-kalesh-anakkur.purayil@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 26 +++++++++++++----------- + 1 file changed, 14 insertions(+), 12 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +index 390162018647..a4134a288077 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -2107,18 +2107,20 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, + } + } + +- if (qp_attr_mask & IB_QP_PATH_MTU) { +- qp->qplib_qp.modify_flags |= +- CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; +- qp->qplib_qp.path_mtu = __from_ib_mtu(qp_attr->path_mtu); +- qp->qplib_qp.mtu = ib_mtu_enum_to_int(qp_attr->path_mtu); +- } else if (qp_attr->qp_state == IB_QPS_RTR) { +- qp->qplib_qp.modify_flags |= +- CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; +- qp->qplib_qp.path_mtu = +- __from_ib_mtu(iboe_get_mtu(rdev->netdev->mtu)); +- qp->qplib_qp.mtu = +- ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu)); ++ if (qp_attr->qp_state == IB_QPS_RTR) { ++ enum ib_mtu qpmtu; ++ ++ qpmtu = iboe_get_mtu(rdev->netdev->mtu); ++ if (qp_attr_mask & IB_QP_PATH_MTU) { ++ if (ib_mtu_enum_to_int(qp_attr->path_mtu) > ++ ib_mtu_enum_to_int(qpmtu)) ++ return -EINVAL; ++ qpmtu = qp_attr->path_mtu; ++ } ++ ++ qp->qplib_qp.modify_flags |= CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; ++ qp->qplib_qp.path_mtu = __from_ib_mtu(qpmtu); ++ qp->qplib_qp.mtu = ib_mtu_enum_to_int(qpmtu); + } + + if (qp_attr_mask & IB_QP_TIMEOUT) { +-- +2.39.5 + diff --git a/queue-6.12/rdma-bnxt_re-add-send-queue-size-check-for-variable-.patch b/queue-6.12/rdma-bnxt_re-add-send-queue-size-check-for-variable-.patch new file mode 100644 index 00000000000..eae2e92aed4 --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-add-send-queue-size-check-for-variable-.patch @@ -0,0 +1,44 @@ +From 150d8ff68abc0a7ab10d1cdef46db1abd7f93c5a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Dec 2024 15:56:47 +0530 +Subject: RDMA/bnxt_re: Add send queue size check for variable wqe + +From: Damodharam Ammepalli + +[ Upstream commit d13be54dc18baee7a3e44349b80755a8c8205d3f ] + +For the fixed WQE case, HW supports 0xFFFF WQEs. +For variable Size WQEs, HW treats this number as +the 16 bytes slots. The maximum supported WQEs +needs to be adjusted based on the number of slots. +Set a maximum WQE limit for variable WQE scenario. + +Fixes: de1d364c3815 ("RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters") +Reviewed-by: Kalesh AP +Signed-off-by: Damodharam Ammepalli +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/20241217102649.1377704-4-kalesh-anakkur.purayil@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/qplib_sp.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +index b273db59454e..3cca7b1395f6 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +@@ -138,6 +138,10 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, + attr->max_qp_wqes -= BNXT_QPLIB_RESERVED_QP_WRS + 1; + } + ++ /* Adjust for max_qp_wqes for variable wqe */ ++ if (cctx->modes.wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE) ++ attr->max_qp_wqes = BNXT_VAR_MAX_WQE - 1; ++ + attr->max_qp_sges = cctx->modes.wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE ? + min_t(u32, sb->max_sge_var_wqe, BNXT_VAR_MAX_SGE) : 6; + attr->max_cq = le32_to_cpu(sb->max_cq); +-- +2.39.5 + diff --git a/queue-6.12/rdma-bnxt_re-avoid-initializing-the-software-queue-f.patch b/queue-6.12/rdma-bnxt_re-avoid-initializing-the-software-queue-f.patch new file mode 100644 index 00000000000..694b9100b8b --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-avoid-initializing-the-software-queue-f.patch @@ -0,0 +1,101 @@ +From 445b040705998d0f18338c85a78fd3a2b048105a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Dec 2024 13:24:13 +0530 +Subject: RDMA/bnxt_re: Avoid initializing the software queue for user queues + +From: Selvin Xavier + +[ Upstream commit 5effcacc8a8f3eb2a9f069d7e81a9ac793598dfb ] + +Software Queues to hold the WRs needs to be created +for only kernel queues. Avoid allocating the unnecessary +memory for user Queues. + +Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") +Fixes: 159fb4ceacd7 ("RDMA/bnxt_re: introduce a function to allocate swq") +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/20241204075416.478431-3-kalesh-anakkur.purayil@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/qplib_fp.c | 42 +++++++++++++----------- + 1 file changed, 23 insertions(+), 19 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +index be374d8ed430..5938db37220d 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +@@ -658,13 +658,6 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, + rc = bnxt_qplib_alloc_init_hwq(&srq->hwq, &hwq_attr); + if (rc) + return rc; +- +- srq->swq = kcalloc(srq->hwq.max_elements, sizeof(*srq->swq), +- GFP_KERNEL); +- if (!srq->swq) { +- rc = -ENOMEM; +- goto fail; +- } + srq->dbinfo.flags = 0; + bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req, + CMDQ_BASE_OPCODE_CREATE_SRQ, +@@ -693,9 +686,17 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, + spin_lock_init(&srq->lock); + srq->start_idx = 0; + srq->last_idx = srq->hwq.max_elements - 1; +- for (idx = 0; idx < srq->hwq.max_elements; idx++) +- srq->swq[idx].next_idx = idx + 1; +- srq->swq[srq->last_idx].next_idx = -1; ++ if (!srq->hwq.is_user) { ++ srq->swq = kcalloc(srq->hwq.max_elements, sizeof(*srq->swq), ++ GFP_KERNEL); ++ if (!srq->swq) { ++ rc = -ENOMEM; ++ goto fail; ++ } ++ for (idx = 0; idx < srq->hwq.max_elements; idx++) ++ srq->swq[idx].next_idx = idx + 1; ++ srq->swq[srq->last_idx].next_idx = -1; ++ } + + srq->id = le32_to_cpu(resp.xid); + srq->dbinfo.hwq = &srq->hwq; +@@ -1041,13 +1042,14 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + if (rc) + return rc; + +- rc = bnxt_qplib_alloc_init_swq(sq); +- if (rc) +- goto fail_sq; +- +- if (psn_sz) +- bnxt_qplib_init_psn_ptr(qp, psn_sz); ++ if (!sq->hwq.is_user) { ++ rc = bnxt_qplib_alloc_init_swq(sq); ++ if (rc) ++ goto fail_sq; + ++ if (psn_sz) ++ bnxt_qplib_init_psn_ptr(qp, psn_sz); ++ } + req.sq_size = cpu_to_le32(bnxt_qplib_set_sq_size(sq, qp->wqe_mode)); + pbl = &sq->hwq.pbl[PBL_LVL_0]; + req.sq_pbl = cpu_to_le64(pbl->pg_map_arr[0]); +@@ -1073,9 +1075,11 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr); + if (rc) + goto sq_swq; +- rc = bnxt_qplib_alloc_init_swq(rq); +- if (rc) +- goto fail_rq; ++ if (!rq->hwq.is_user) { ++ rc = bnxt_qplib_alloc_init_swq(rq); ++ if (rc) ++ goto fail_rq; ++ } + + req.rq_size = cpu_to_le32(rq->max_wqe); + pbl = &rq->hwq.pbl[PBL_LVL_0]; +-- +2.39.5 + diff --git a/queue-6.12/rdma-bnxt_re-avoid-sending-the-modify-qp-workaround-.patch b/queue-6.12/rdma-bnxt_re-avoid-sending-the-modify-qp-workaround-.patch new file mode 100644 index 00000000000..a8dc884e679 --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-avoid-sending-the-modify-qp-workaround-.patch @@ -0,0 +1,51 @@ +From 52fffb0892432012918706d488e4cc511b6c9510 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Dec 2024 13:24:14 +0530 +Subject: RDMA/bnxt_re: Avoid sending the modify QP workaround for latest + adapters + +From: Kashyap Desai + +[ Upstream commit 064c22408a73b9e945139b64614c534cbbefb591 ] + +The workaround to modify the UD QP from RTS to RTS is required +only for older adapters. Issuing this for latest adapters can caus +some unexpected behavior. Fix it + +Fixes: 1801d87b3598 ("RDMA/bnxt_re: Support new 5760X P7 devices") +Signed-off-by: Kashyap Desai +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/20241204075416.478431-4-kalesh-anakkur.purayil@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +index 160096792224..390162018647 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -2763,7 +2763,8 @@ static int bnxt_re_post_send_shadow_qp(struct bnxt_re_dev *rdev, + wr = wr->next; + } + bnxt_qplib_post_send_db(&qp->qplib_qp); +- bnxt_ud_qp_hw_stall_workaround(qp); ++ if (!bnxt_qplib_is_chip_gen_p5_p7(qp->rdev->chip_ctx)) ++ bnxt_ud_qp_hw_stall_workaround(qp); + spin_unlock_irqrestore(&qp->sq_lock, flags); + return rc; + } +@@ -2875,7 +2876,8 @@ int bnxt_re_post_send(struct ib_qp *ib_qp, const struct ib_send_wr *wr, + wr = wr->next; + } + bnxt_qplib_post_send_db(&qp->qplib_qp); +- bnxt_ud_qp_hw_stall_workaround(qp); ++ if (!bnxt_qplib_is_chip_gen_p5_p7(qp->rdev->chip_ctx)) ++ bnxt_ud_qp_hw_stall_workaround(qp); + spin_unlock_irqrestore(&qp->sq_lock, flags); + + return rc; +-- +2.39.5 + diff --git a/queue-6.12/rdma-bnxt_re-disable-use-of-reserved-wqes.patch b/queue-6.12/rdma-bnxt_re-disable-use-of-reserved-wqes.patch new file mode 100644 index 00000000000..6e55a463f3a --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-disable-use-of-reserved-wqes.patch @@ -0,0 +1,48 @@ +From 2e96ebbec457878e3287b0355cd34e21f1f508b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Dec 2024 15:56:46 +0530 +Subject: RDMA/bnxt_re: Disable use of reserved wqes + +From: Kalesh AP + +[ Upstream commit d5a38bf2f35979537c526acbc56bc435ed40685f ] + +Disabling the reserved wqes logic for Gen P5/P7 devices +because this workaround is required only for legacy devices. + +Fixes: ecb53febfcad ("RDMA/bnxt_en: Enable RDMA driver support for 57500 chip") +Signed-off-by: Kalesh AP +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/20241217102649.1377704-3-kalesh-anakkur.purayil@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/qplib_sp.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +index 63706d6d121c..b273db59454e 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +@@ -130,11 +130,13 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, + sb->max_qp_init_rd_atom > BNXT_QPLIB_MAX_OUT_RD_ATOM ? + BNXT_QPLIB_MAX_OUT_RD_ATOM : sb->max_qp_init_rd_atom; + attr->max_qp_wqes = le16_to_cpu(sb->max_qp_wr) - 1; +- /* +- * 128 WQEs needs to be reserved for the HW (8916). Prevent +- * reporting the max number +- */ +- attr->max_qp_wqes -= BNXT_QPLIB_RESERVED_QP_WRS + 1; ++ if (!bnxt_qplib_is_chip_gen_p5_p7(rcfw->res->cctx)) { ++ /* ++ * 128 WQEs needs to be reserved for the HW (8916). Prevent ++ * reporting the max number on legacy devices ++ */ ++ attr->max_qp_wqes -= BNXT_QPLIB_RESERVED_QP_WRS + 1; ++ } + + attr->max_qp_sges = cctx->modes.wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE ? + min_t(u32, sb->max_sge_var_wqe, BNXT_VAR_MAX_SGE) : 6; +-- +2.39.5 + diff --git a/queue-6.12/rdma-bnxt_re-fix-error-recovery-sequence.patch b/queue-6.12/rdma-bnxt_re-fix-error-recovery-sequence.patch new file mode 100644 index 00000000000..61681dc5d84 --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-fix-error-recovery-sequence.patch @@ -0,0 +1,85 @@ +From 1d50e02bc105749ff67fb061160b796294bac9bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Dec 2024 08:20:08 +0530 +Subject: RDMA/bnxt_re: Fix error recovery sequence + +From: Kalesh AP + +[ Upstream commit e6178bf78d0378c2d397a6aafaf4882d0af643fa ] + +Fixed to return ENXIO from __send_message_basic_sanity() +to indicate that device is in error state. In the case of +ERR_DEVICE_DETACHED state, the driver should not post the +commands to the firmware as it will time out eventually. + +Removed bnxt_re_modify_qp() call from bnxt_re_dev_stop() +as it is a no-op. + +Fixes: cc5b9b48d447 ("RDMA/bnxt_re: Recover the device when FW error is detected") +Signed-off-by: Kalesh AP +Signed-off-by: Kashyap Desai +Link: https://patch.msgid.link/20241231025008.2267162-1-kalesh-anakkur.purayil@broadcom.com +Reviewed-by: Selvin Xavier +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/main.c | 8 +------- + drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 5 +++-- + 2 files changed, 4 insertions(+), 9 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c +index 2ac8ddbed576..8abd1b723f8f 100644 +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -1435,11 +1435,8 @@ static bool bnxt_re_is_qp1_or_shadow_qp(struct bnxt_re_dev *rdev, + + static void bnxt_re_dev_stop(struct bnxt_re_dev *rdev) + { +- int mask = IB_QP_STATE; +- struct ib_qp_attr qp_attr; + struct bnxt_re_qp *qp; + +- qp_attr.qp_state = IB_QPS_ERR; + mutex_lock(&rdev->qp_lock); + list_for_each_entry(qp, &rdev->qp_list, list) { + /* Modify the state of all QPs except QP1/Shadow QP */ +@@ -1447,12 +1444,9 @@ static void bnxt_re_dev_stop(struct bnxt_re_dev *rdev) + if (qp->qplib_qp.state != + CMDQ_MODIFY_QP_NEW_STATE_RESET && + qp->qplib_qp.state != +- CMDQ_MODIFY_QP_NEW_STATE_ERR) { ++ CMDQ_MODIFY_QP_NEW_STATE_ERR) + bnxt_re_dispatch_event(&rdev->ibdev, &qp->ib_qp, + 1, IB_EVENT_QP_FATAL); +- bnxt_re_modify_qp(&qp->ib_qp, &qp_attr, mask, +- NULL); +- } + } + } + mutex_unlock(&rdev->qp_lock); +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +index e82bd37158ad..7a099580ca8b 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +@@ -424,7 +424,8 @@ static int __send_message_basic_sanity(struct bnxt_qplib_rcfw *rcfw, + + /* Prevent posting if f/w is not in a state to process */ + if (test_bit(ERR_DEVICE_DETACHED, &rcfw->cmdq.flags)) +- return bnxt_qplib_map_rc(opcode); ++ return -ENXIO; ++ + if (test_bit(FIRMWARE_STALL_DETECTED, &cmdq->flags)) + return -ETIMEDOUT; + +@@ -493,7 +494,7 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw, + + rc = __send_message_basic_sanity(rcfw, msg, opcode); + if (rc) +- return rc; ++ return rc == -ENXIO ? bnxt_qplib_map_rc(opcode) : rc; + + rc = __send_message(rcfw, msg, opcode); + if (rc) +-- +2.39.5 + diff --git a/queue-6.12/rdma-bnxt_re-fix-max-sges-for-the-work-request.patch b/queue-6.12/rdma-bnxt_re-fix-max-sges-for-the-work-request.patch new file mode 100644 index 00000000000..818a495b34a --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-fix-max-sges-for-the-work-request.patch @@ -0,0 +1,51 @@ +From 9b5dcc7ca28ba611461aa117070e1f62c5de6855 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Dec 2024 13:24:12 +0530 +Subject: RDMA/bnxt_re: Fix max SGEs for the Work Request + +From: Kashyap Desai + +[ Upstream commit 79d330fbdffd8cee06d8bdf38d82cb62d8363a27 ] + +Gen P7 supports up to 13 SGEs for now. WQE software structure +can hold only 6 now. Since the max send sge is reported as +13, the stack can give requests up to 13 SGEs. This is causing +traffic failures and system crashes. + +Use the define for max SGE supported for variable size. This +will work for both static and variable WQEs. + +Fixes: 227f51743b61 ("RDMA/bnxt_re: Fix the max WQE size for static WQE support") +Signed-off-by: Kashyap Desai +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/20241204075416.478431-2-kalesh-anakkur.purayil@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/qplib_fp.h | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h +index f55958e5fddb..d8c71c024613 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h +@@ -114,7 +114,6 @@ struct bnxt_qplib_sge { + u32 size; + }; + +-#define BNXT_QPLIB_QP_MAX_SGL 6 + struct bnxt_qplib_swq { + u64 wr_id; + int next_idx; +@@ -154,7 +153,7 @@ struct bnxt_qplib_swqe { + #define BNXT_QPLIB_SWQE_FLAGS_UC_FENCE BIT(2) + #define BNXT_QPLIB_SWQE_FLAGS_SOLICIT_EVENT BIT(3) + #define BNXT_QPLIB_SWQE_FLAGS_INLINE BIT(4) +- struct bnxt_qplib_sge sg_list[BNXT_QPLIB_QP_MAX_SGL]; ++ struct bnxt_qplib_sge sg_list[BNXT_VAR_MAX_SGE]; + int num_sge; + /* Max inline data is 96 bytes */ + u32 inline_len; +-- +2.39.5 + diff --git a/queue-6.12/rdma-bnxt_re-fix-max_qp_wrs-reported.patch b/queue-6.12/rdma-bnxt_re-fix-max_qp_wrs-reported.patch new file mode 100644 index 00000000000..322f2ef7d2f --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-fix-max_qp_wrs-reported.patch @@ -0,0 +1,42 @@ +From 4c690749335ea647c50279c3f4d29b00db11ca65 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Dec 2024 15:56:45 +0530 +Subject: RDMA/bnxt_re: Fix max_qp_wrs reported + +From: Selvin Xavier + +[ Upstream commit 40be32303ec829ea12f9883e499bfd3fe9e52baf ] + +While creating qps, driver adds one extra entry to the sq size +passed by the ULPs in order to avoid queue full condition. +When ULPs creates QPs with max_qp_wr reported, driver creates +QP with 1 more than the max_wqes supported by HW. Create QP fails +in this case. To avoid this error, reduce 1 entry in max_qp_wqes +and report it to the stack. + +Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") +Reviewed-by: Kalesh AP +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/20241217102649.1377704-2-kalesh-anakkur.purayil@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/qplib_sp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +index e29fbbdab9fd..63706d6d121c 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +@@ -129,7 +129,7 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, + attr->max_qp_init_rd_atom = + sb->max_qp_init_rd_atom > BNXT_QPLIB_MAX_OUT_RD_ATOM ? + BNXT_QPLIB_MAX_OUT_RD_ATOM : sb->max_qp_init_rd_atom; +- attr->max_qp_wqes = le16_to_cpu(sb->max_qp_wr); ++ attr->max_qp_wqes = le16_to_cpu(sb->max_qp_wr) - 1; + /* + * 128 WQEs needs to be reserved for the HW (8916). Prevent + * reporting the max number +-- +2.39.5 + diff --git a/queue-6.12/rdma-bnxt_re-fix-msn-table-size-for-variable-wqe-mod.patch b/queue-6.12/rdma-bnxt_re-fix-msn-table-size-for-variable-wqe-mod.patch new file mode 100644 index 00000000000..87a60232be7 --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-fix-msn-table-size-for-variable-wqe-mod.patch @@ -0,0 +1,46 @@ +From 429aba870f64484fc1f2e533a90360053a1b2425 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Dec 2024 15:56:48 +0530 +Subject: RDMA/bnxt_re: Fix MSN table size for variable wqe mode + +From: Damodharam Ammepalli + +[ Upstream commit bb839f3ace0fee532a0487b692cc4d868fccb7cf ] + +For variable size wqe mode, the MSN table size should be +half the size of the SQ depth. Fixing this to avoid wrap +around problems in the retransmission path. + +Fixes: de1d364c3815 ("RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters") +Reviewed-by: Kashyap Desai +Reviewed-by: Kalesh AP +Signed-off-by: Damodharam Ammepalli +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/20241217102649.1377704-5-kalesh-anakkur.purayil@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/qplib_fp.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +index f5db29707449..3a34154b0d9d 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +@@ -1032,7 +1032,12 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + : 0; + /* Update msn tbl size */ + if (qp->is_host_msn_tbl && psn_sz) { +- hwq_attr.aux_depth = roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, qp->wqe_mode)); ++ if (qp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ++ hwq_attr.aux_depth = ++ roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, qp->wqe_mode)); ++ else ++ hwq_attr.aux_depth = ++ roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, qp->wqe_mode)) / 2; + qp->msn_tbl_sz = hwq_attr.aux_depth; + qp->msn = 0; + } +-- +2.39.5 + diff --git a/queue-6.12/rdma-bnxt_re-fix-reporting-hw_ver-in-query_device.patch b/queue-6.12/rdma-bnxt_re-fix-reporting-hw_ver-in-query_device.patch new file mode 100644 index 00000000000..6d3f78659d2 --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-fix-reporting-hw_ver-in-query_device.patch @@ -0,0 +1,41 @@ +From 1ec83cae1db87a79290bbf2325015e2ee16e129e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Dec 2024 14:09:31 +0530 +Subject: RDMA/bnxt_re: Fix reporting hw_ver in query_device + +From: Kalesh AP + +[ Upstream commit 7179fe0074a3c962e43a9e51169304c4911989ed ] + +Driver currently populates subsystem_device id in the +"hw_ver" field of ib_attr structure in query_device. + +Updated to populate PCI revision ID. + +Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") +Reviewed-by: Preethi G +Signed-off-by: Kalesh AP +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/20241211083931.968831-6-kalesh-anakkur.purayil@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +index a4134a288077..b20cffcc3e7d 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -156,7 +156,7 @@ int bnxt_re_query_device(struct ib_device *ibdev, + + ib_attr->vendor_id = rdev->en_dev->pdev->vendor; + ib_attr->vendor_part_id = rdev->en_dev->pdev->device; +- ib_attr->hw_ver = rdev->en_dev->pdev->subsystem_device; ++ ib_attr->hw_ver = rdev->en_dev->pdev->revision; + ib_attr->max_qp = dev_attr->max_qp; + ib_attr->max_qp_wr = dev_attr->max_qp_wqes; + ib_attr->device_cap_flags = +-- +2.39.5 + diff --git a/queue-6.12/rdma-bnxt_re-fix-the-check-for-9060-condition.patch b/queue-6.12/rdma-bnxt_re-fix-the-check-for-9060-condition.patch new file mode 100644 index 00000000000..4714489adc5 --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-fix-the-check-for-9060-condition.patch @@ -0,0 +1,46 @@ +From 18e0dfc8bbf04e67e8c4189c8e6188af7e03760a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Dec 2024 14:09:27 +0530 +Subject: RDMA/bnxt_re: Fix the check for 9060 condition + +From: Kalesh AP + +[ Upstream commit 38651476e46e088598354510502c383e932e2297 ] + +The check for 9060 condition should only be made for legacy chips. + +Fixes: 9152e0b722b2 ("RDMA/bnxt_re: HW workarounds for handling specific conditions") +Reviewed-by: Kashyap Desai +Signed-off-by: Kalesh AP +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/20241211083931.968831-2-kalesh-anakkur.purayil@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/qplib_fp.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +index 5938db37220d..f5db29707449 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +@@ -2598,10 +2598,12 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq, + bnxt_qplib_add_flush_qp(qp); + } else { + /* Before we complete, do WA 9060 */ +- if (do_wa9060(qp, cq, cq_cons, sq->swq_last, +- cqe_sq_cons)) { +- *lib_qp = qp; +- goto out; ++ if (!bnxt_qplib_is_chip_gen_p5_p7(qp->cctx)) { ++ if (do_wa9060(qp, cq, cq_cons, sq->swq_last, ++ cqe_sq_cons)) { ++ *lib_qp = qp; ++ goto out; ++ } + } + if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) { + cqe->status = CQ_REQ_STATUS_OK; +-- +2.39.5 + diff --git a/queue-6.12/rdma-bnxt_re-fix-the-locking-while-accessing-the-qp-.patch b/queue-6.12/rdma-bnxt_re-fix-the-locking-while-accessing-the-qp-.patch new file mode 100644 index 00000000000..42b7a78b9b9 --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-fix-the-locking-while-accessing-the-qp-.patch @@ -0,0 +1,43 @@ +From 82003ffe8eb3dc65ac4f422049551f2de2f82356 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Dec 2024 15:56:49 +0530 +Subject: RDMA/bnxt_re: Fix the locking while accessing the QP table + +From: Selvin Xavier + +[ Upstream commit 9272cba0ded71b5a2084da3004ec7806b8cb7fd2 ] + +QP table handling is synchronized with destroy QP and Async +event from the HW. The same needs to be synchronized +during create_qp also. Use the same lock in create_qp also. + +Fixes: 76d3ddff7153 ("RDMA/bnxt_re: synchronize the qp-handle table array") +Fixes: f218d67ef004 ("RDMA/bnxt_re: Allow posting when QPs are in error") +Fixes: 84cf229f4001 ("RDMA/bnxt_re: Fix the qp table indexing") +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/20241217102649.1377704-6-kalesh-anakkur.purayil@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/qplib_fp.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +index 3a34154b0d9d..828e2f980801 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +@@ -1180,9 +1180,11 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + rq->dbinfo.db = qp->dpi->dbr; + rq->dbinfo.max_slot = bnxt_qplib_set_rq_max_slot(rq->wqe_size); + } ++ spin_lock_bh(&rcfw->tbl_lock); + tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw); + rcfw->qp_tbl[tbl_indx].qp_id = qp->id; + rcfw->qp_tbl[tbl_indx].qp_handle = (void *)qp; ++ spin_unlock_bh(&rcfw->tbl_lock); + + return 0; + fail: +-- +2.39.5 + diff --git a/queue-6.12/rdma-bnxt_re-remove-always-true-dattr-validity-check.patch b/queue-6.12/rdma-bnxt_re-remove-always-true-dattr-validity-check.patch new file mode 100644 index 00000000000..b07a581ed20 --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-remove-always-true-dattr-validity-check.patch @@ -0,0 +1,46 @@ +From aca5d75e8c41591c1a7841e5da1a91b6c8b45f7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Nov 2024 15:10:31 +0200 +Subject: RDMA/bnxt_re: Remove always true dattr validity check + +From: Leon Romanovsky + +[ Upstream commit eb867d797d294a00a092b5027d08439da68940b2 ] + +res->dattr is always valid at this point as it was initialized +during device addition in bnxt_re_add_device(). + +This change is fixing the following smatch error: +drivers/infiniband/hw/bnxt_re/qplib_fp.c:1090 bnxt_qplib_create_qp() + error: we previously assumed 'res->dattr' could be null (see line 985) + +Fixes: 07f830ae4913 ("RDMA/bnxt_re: Adds MSN table capability for Gen P7 adapters") +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/r/202411222329.YTrwonWi-lkp@intel.com/ +Link: https://patch.msgid.link/be0d8836b64cba3e479fbcbca717acad04aae02e.1732626579.git.leonro@nvidia.com +Acked-by: Selvin Xavier +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/qplib_fp.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +index 7ad83566ab0f..be374d8ed430 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +@@ -999,9 +999,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + u32 tbl_indx; + u16 nsge; + +- if (res->dattr) +- qp->is_host_msn_tbl = _is_host_msn_table(res->dattr->dev_cap_flags2); +- ++ qp->is_host_msn_tbl = _is_host_msn_table(res->dattr->dev_cap_flags2); + sq->dbinfo.flags = 0; + bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req, + CMDQ_BASE_OPCODE_CREATE_QP, +-- +2.39.5 + diff --git a/queue-6.12/rdma-core-fix-enodev-error-for-iwarp-test-over-vlan.patch b/queue-6.12/rdma-core-fix-enodev-error-for-iwarp-test-over-vlan.patch new file mode 100644 index 00000000000..153f2c2efeb --- /dev/null +++ b/queue-6.12/rdma-core-fix-enodev-error-for-iwarp-test-over-vlan.patch @@ -0,0 +1,66 @@ +From e7ae14ea3233ea69ae967851bee264a590e52c7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Dec 2024 19:30:53 +0530 +Subject: RDMA/core: Fix ENODEV error for iWARP test over vlan + +From: Anumula Murali Mohan Reddy + +[ Upstream commit a4048c83fd87c65657a4acb17d639092d4b6133d ] + +If traffic is over vlan, cma_validate_port() fails to match +net_device ifindex with bound_if_index and results in ENODEV error. +As iWARP gid table is static, it contains entry corresponding to +only one net device which is either real netdev or vlan netdev for +cases like siw attached to a vlan interface. +This patch fixes the issue by assigning bound_if_index with net +device index, if real net device obtained from bound if index matches +with net device retrieved from gid table + +Fixes: f8ef1be816bf ("RDMA/cma: Avoid GID lookups on iWARP devices") +Link: https://lore.kernel.org/all/ZzNgdrjo1kSCGbRz@chelsio.com/ +Signed-off-by: Anumula Murali Mohan Reddy +Signed-off-by: Potnuri Bharat Teja +Link: https://patch.msgid.link/20241203140052.3985-1-anumula@chelsio.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/core/cma.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c +index 64ace0b968f0..91db10515d74 100644 +--- a/drivers/infiniband/core/cma.c ++++ b/drivers/infiniband/core/cma.c +@@ -690,6 +690,7 @@ cma_validate_port(struct ib_device *device, u32 port, + int bound_if_index = dev_addr->bound_dev_if; + int dev_type = dev_addr->dev_type; + struct net_device *ndev = NULL; ++ struct net_device *pdev = NULL; + + if (!rdma_dev_access_netns(device, id_priv->id.route.addr.dev_addr.net)) + goto out; +@@ -714,6 +715,21 @@ cma_validate_port(struct ib_device *device, u32 port, + + rcu_read_lock(); + ndev = rcu_dereference(sgid_attr->ndev); ++ if (ndev->ifindex != bound_if_index) { ++ pdev = dev_get_by_index_rcu(dev_addr->net, bound_if_index); ++ if (pdev) { ++ if (is_vlan_dev(pdev)) { ++ pdev = vlan_dev_real_dev(pdev); ++ if (ndev->ifindex == pdev->ifindex) ++ bound_if_index = pdev->ifindex; ++ } ++ if (is_vlan_dev(ndev)) { ++ pdev = vlan_dev_real_dev(ndev); ++ if (bound_if_index == pdev->ifindex) ++ bound_if_index = ndev->ifindex; ++ } ++ } ++ } + if (!net_eq(dev_net(ndev), dev_addr->net) || + ndev->ifindex != bound_if_index) { + rdma_put_gid_attr(sgid_attr); +-- +2.39.5 + diff --git a/queue-6.12/rdma-hns-fix-accessing-invalid-dip_ctx-during-destro.patch b/queue-6.12/rdma-hns-fix-accessing-invalid-dip_ctx-during-destro.patch new file mode 100644 index 00000000000..a93e356c302 --- /dev/null +++ b/queue-6.12/rdma-hns-fix-accessing-invalid-dip_ctx-during-destro.patch @@ -0,0 +1,39 @@ +From c4f64a9f8b69f5f57092ced102dfecadc323fde5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Dec 2024 13:52:47 +0800 +Subject: RDMA/hns: Fix accessing invalid dip_ctx during destroying QP + +From: Chengchang Tang + +[ Upstream commit 0572eccf239ce4bd89bd531767ec5ab20e249290 ] + +If it fails to modify QP to RTR, dip_ctx will not be attached. And +during detroying QP, the invalid dip_ctx pointer will be accessed. + +Fixes: faa62440a577 ("RDMA/hns: Fix different dgids mapping to the same dip_idx") +Signed-off-by: Chengchang Tang +Signed-off-by: Junxian Huang +Link: https://patch.msgid.link/20241220055249.146943-3-huangjunxian6@hisilicon.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index 697b17cca02e..6dddadb90e02 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -5619,6 +5619,9 @@ static void put_dip_ctx_idx(struct hns_roce_dev *hr_dev, + { + struct hns_roce_dip *hr_dip = hr_qp->dip; + ++ if (!hr_dip) ++ return; ++ + xa_lock(&hr_dev->qp_table.dip_xa); + + hr_dip->qp_cnt--; +-- +2.39.5 + diff --git a/queue-6.12/rdma-hns-fix-mapping-error-of-zero-hop-wqe-buffer.patch b/queue-6.12/rdma-hns-fix-mapping-error-of-zero-hop-wqe-buffer.patch new file mode 100644 index 00000000000..52141679e91 --- /dev/null +++ b/queue-6.12/rdma-hns-fix-mapping-error-of-zero-hop-wqe-buffer.patch @@ -0,0 +1,177 @@ +From e1eae1e138085d23f3c9b4f47d4cdb711a92b986 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Dec 2024 13:52:46 +0800 +Subject: RDMA/hns: Fix mapping error of zero-hop WQE buffer + +From: wenglianfa + +[ Upstream commit 8673a6c2d9e483dfeeef83a1f06f59e05636f4d1 ] + +Due to HW limitation, the three region of WQE buffer must be mapped +and set to HW in a fixed order: SQ buffer, SGE buffer, and RQ buffer. + +Currently when one region is zero-hop while the other two are not, +the zero-hop region will not be mapped. This violate the limitation +above and leads to address error. + +Fixes: 38389eaa4db1 ("RDMA/hns: Add mtr support for mixed multihop addressing") +Signed-off-by: wenglianfa +Signed-off-by: Junxian Huang +Link: https://patch.msgid.link/20241220055249.146943-2-huangjunxian6@hisilicon.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_hem.c | 43 ++++++++++++++++-------- + drivers/infiniband/hw/hns/hns_roce_mr.c | 5 --- + 2 files changed, 29 insertions(+), 19 deletions(-) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c +index f84521be3bea..605562122ecc 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hem.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c +@@ -931,6 +931,7 @@ struct hns_roce_hem_item { + size_t count; /* max ba numbers */ + int start; /* start buf offset in this hem */ + int end; /* end buf offset in this hem */ ++ bool exist_bt; + }; + + /* All HEM items are linked in a tree structure */ +@@ -959,6 +960,7 @@ hem_list_alloc_item(struct hns_roce_dev *hr_dev, int start, int end, int count, + } + } + ++ hem->exist_bt = exist_bt; + hem->count = count; + hem->start = start; + hem->end = end; +@@ -969,22 +971,22 @@ hem_list_alloc_item(struct hns_roce_dev *hr_dev, int start, int end, int count, + } + + static void hem_list_free_item(struct hns_roce_dev *hr_dev, +- struct hns_roce_hem_item *hem, bool exist_bt) ++ struct hns_roce_hem_item *hem) + { +- if (exist_bt) ++ if (hem->exist_bt) + dma_free_coherent(hr_dev->dev, hem->count * BA_BYTE_LEN, + hem->addr, hem->dma_addr); + kfree(hem); + } + + static void hem_list_free_all(struct hns_roce_dev *hr_dev, +- struct list_head *head, bool exist_bt) ++ struct list_head *head) + { + struct hns_roce_hem_item *hem, *temp_hem; + + list_for_each_entry_safe(hem, temp_hem, head, list) { + list_del(&hem->list); +- hem_list_free_item(hr_dev, hem, exist_bt); ++ hem_list_free_item(hr_dev, hem); + } + } + +@@ -1084,6 +1086,10 @@ int hns_roce_hem_list_calc_root_ba(const struct hns_roce_buf_region *regions, + + for (i = 0; i < region_cnt; i++) { + r = (struct hns_roce_buf_region *)®ions[i]; ++ /* when r->hopnum = 0, the region should not occupy root_ba. */ ++ if (!r->hopnum) ++ continue; ++ + if (r->hopnum > 1) { + step = hem_list_calc_ba_range(r->hopnum, 1, unit); + if (step > 0) +@@ -1177,7 +1183,7 @@ static int hem_list_alloc_mid_bt(struct hns_roce_dev *hr_dev, + + err_exit: + for (level = 1; level < hopnum; level++) +- hem_list_free_all(hr_dev, &temp_list[level], true); ++ hem_list_free_all(hr_dev, &temp_list[level]); + + return ret; + } +@@ -1218,16 +1224,26 @@ static int alloc_fake_root_bt(struct hns_roce_dev *hr_dev, void *cpu_base, + { + struct hns_roce_hem_item *hem; + ++ /* This is on the has_mtt branch, if r->hopnum ++ * is 0, there is no root_ba to reuse for the ++ * region's fake hem, so a dma_alloc request is ++ * necessary here. ++ */ + hem = hem_list_alloc_item(hr_dev, r->offset, r->offset + r->count - 1, +- r->count, false); ++ r->count, !r->hopnum); + if (!hem) + return -ENOMEM; + +- hem_list_assign_bt(hem, cpu_base, phy_base); ++ /* The root_ba can be reused only when r->hopnum > 0. */ ++ if (r->hopnum) ++ hem_list_assign_bt(hem, cpu_base, phy_base); + list_add(&hem->list, branch_head); + list_add(&hem->sibling, leaf_head); + +- return r->count; ++ /* If r->hopnum == 0, 0 is returned, ++ * so that the root_bt entry is not occupied. ++ */ ++ return r->hopnum ? r->count : 0; + } + + static int setup_middle_bt(struct hns_roce_dev *hr_dev, void *cpu_base, +@@ -1271,7 +1287,7 @@ setup_root_hem(struct hns_roce_dev *hr_dev, struct hns_roce_hem_list *hem_list, + return -ENOMEM; + + total = 0; +- for (i = 0; i < region_cnt && total < max_ba_num; i++) { ++ for (i = 0; i < region_cnt && total <= max_ba_num; i++) { + r = ®ions[i]; + if (!r->count) + continue; +@@ -1337,9 +1353,9 @@ static int hem_list_alloc_root_bt(struct hns_roce_dev *hr_dev, + region_cnt); + if (ret) { + for (i = 0; i < region_cnt; i++) +- hem_list_free_all(hr_dev, &head.branch[i], false); ++ hem_list_free_all(hr_dev, &head.branch[i]); + +- hem_list_free_all(hr_dev, &head.root, true); ++ hem_list_free_all(hr_dev, &head.root); + } + + return ret; +@@ -1402,10 +1418,9 @@ void hns_roce_hem_list_release(struct hns_roce_dev *hr_dev, + + for (i = 0; i < HNS_ROCE_MAX_BT_REGION; i++) + for (j = 0; j < HNS_ROCE_MAX_BT_LEVEL; j++) +- hem_list_free_all(hr_dev, &hem_list->mid_bt[i][j], +- j != 0); ++ hem_list_free_all(hr_dev, &hem_list->mid_bt[i][j]); + +- hem_list_free_all(hr_dev, &hem_list->root_bt, true); ++ hem_list_free_all(hr_dev, &hem_list->root_bt); + INIT_LIST_HEAD(&hem_list->btm_bt); + hem_list->root_ba = 0; + } +diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c +index bf30b3a65a9b..55b9283bfc6f 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_mr.c ++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c +@@ -814,11 +814,6 @@ int hns_roce_mtr_map(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, + for (i = 0, mapped_cnt = 0; i < mtr->hem_cfg.region_count && + mapped_cnt < page_cnt; i++) { + r = &mtr->hem_cfg.region[i]; +- /* if hopnum is 0, no need to map pages in this region */ +- if (!r->hopnum) { +- mapped_cnt += r->count; +- continue; +- } + + if (r->offset + r->count > page_cnt) { + ret = -EINVAL; +-- +2.39.5 + diff --git a/queue-6.12/rdma-hns-fix-missing-flush-cqe-for-dwqe.patch b/queue-6.12/rdma-hns-fix-missing-flush-cqe-for-dwqe.patch new file mode 100644 index 00000000000..dec4a285d91 --- /dev/null +++ b/queue-6.12/rdma-hns-fix-missing-flush-cqe-for-dwqe.patch @@ -0,0 +1,58 @@ +From 0ffae9889975a2923826b77fe9834d0a85396955 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Dec 2024 13:52:49 +0800 +Subject: RDMA/hns: Fix missing flush CQE for DWQE + +From: Chengchang Tang + +[ Upstream commit e3debdd48423d3d75b9d366399228d7225d902cd ] + +Flush CQE handler has not been called if QP state gets into errored +mode in DWQE path. So, the new added outstanding WQEs will never be +flushed. + +It leads to a hung task timeout when using NFS over RDMA: + __switch_to+0x7c/0xd0 + __schedule+0x350/0x750 + schedule+0x50/0xf0 + schedule_timeout+0x2c8/0x340 + wait_for_common+0xf4/0x2b0 + wait_for_completion+0x20/0x40 + __ib_drain_sq+0x140/0x1d0 [ib_core] + ib_drain_sq+0x98/0xb0 [ib_core] + rpcrdma_xprt_disconnect+0x68/0x270 [rpcrdma] + xprt_rdma_close+0x20/0x60 [rpcrdma] + xprt_autoclose+0x64/0x1cc [sunrpc] + process_one_work+0x1d8/0x4e0 + worker_thread+0x154/0x420 + kthread+0x108/0x150 + ret_from_fork+0x10/0x18 + +Fixes: 01584a5edcc4 ("RDMA/hns: Add support of direct wqe") +Signed-off-by: Chengchang Tang +Signed-off-by: Junxian Huang +Link: https://patch.msgid.link/20241220055249.146943-5-huangjunxian6@hisilicon.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index d0469d27c63c..0144e7210d05 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -670,6 +670,10 @@ static void write_dwqe(struct hns_roce_dev *hr_dev, struct hns_roce_qp *qp, + #define HNS_ROCE_SL_SHIFT 2 + struct hns_roce_v2_rc_send_wqe *rc_sq_wqe = wqe; + ++ if (unlikely(qp->state == IB_QPS_ERR)) { ++ flush_cqe(hr_dev, qp); ++ return; ++ } + /* All kinds of DirectWQE have the same header field layout */ + hr_reg_enable(rc_sq_wqe, RC_SEND_WQE_FLAG); + hr_reg_write(rc_sq_wqe, RC_SEND_WQE_DB_SL_L, qp->sl); +-- +2.39.5 + diff --git a/queue-6.12/rdma-hns-fix-warning-storm-caused-by-invalid-input-i.patch b/queue-6.12/rdma-hns-fix-warning-storm-caused-by-invalid-input-i.patch new file mode 100644 index 00000000000..4f35ffcb147 --- /dev/null +++ b/queue-6.12/rdma-hns-fix-warning-storm-caused-by-invalid-input-i.patch @@ -0,0 +1,47 @@ +From a15f8340483bc328173107a7b57f0d71b2108dcd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Dec 2024 13:52:48 +0800 +Subject: RDMA/hns: Fix warning storm caused by invalid input in IO path + +From: Chengchang Tang + +[ Upstream commit fa5c4ba8cdbfd2c2d6422e001311c8213283ebbf ] + +WARN_ON() is called in the IO path. And it could lead to a warning +storm. Use WARN_ON_ONCE() instead of WARN_ON(). + +Fixes: 12542f1de179 ("RDMA/hns: Refactor process about opcode in post_send()") +Signed-off-by: Chengchang Tang +Signed-off-by: Junxian Huang +Link: https://patch.msgid.link/20241220055249.146943-4-huangjunxian6@hisilicon.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index 6dddadb90e02..d0469d27c63c 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -468,7 +468,7 @@ static inline int set_ud_wqe(struct hns_roce_qp *qp, + valid_num_sge = calc_wr_sge_num(wr, &msg_len); + + ret = set_ud_opcode(ud_sq_wqe, wr); +- if (WARN_ON(ret)) ++ if (WARN_ON_ONCE(ret)) + return ret; + + ud_sq_wqe->msg_len = cpu_to_le32(msg_len); +@@ -572,7 +572,7 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp, + rc_sq_wqe->msg_len = cpu_to_le32(msg_len); + + ret = set_rc_opcode(hr_dev, rc_sq_wqe, wr); +- if (WARN_ON(ret)) ++ if (WARN_ON_ONCE(ret)) + return ret; + + hr_reg_write(rc_sq_wqe, RC_SEND_WQE_SO, +-- +2.39.5 + diff --git a/queue-6.12/rdma-mlx5-enforce-same-type-port-association-for-mul.patch b/queue-6.12/rdma-mlx5-enforce-same-type-port-association-for-mul.patch new file mode 100644 index 00000000000..6df7c73bfa1 --- /dev/null +++ b/queue-6.12/rdma-mlx5-enforce-same-type-port-association-for-mul.patch @@ -0,0 +1,69 @@ +From 54d65797296307bcc042fb16c895f87f94ac46cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Dec 2024 15:45:37 +0200 +Subject: RDMA/mlx5: Enforce same type port association for multiport RoCE + +From: Patrisious Haddad + +[ Upstream commit e05feab22fd7dabcd6d272c4e2401ec1acdfdb9b ] + +Different core device types such as PFs and VFs shouldn't be affiliated +together since they have different capabilities, fix that by enforcing +type check before doing the affiliation. + +Fixes: 32f69e4be269 ("{net, IB}/mlx5: Manage port association for multiport RoCE") +Reviewed-by: Mark Bloch +Signed-off-by: Patrisious Haddad +Link: https://patch.msgid.link/88699500f690dff1c1852c1ddb71f8a1cc8b956e.1733233480.git.leonro@nvidia.com +Reviewed-by: Mateusz Polchlopek +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/mlx5/main.c | 6 ++++-- + include/linux/mlx5/driver.h | 6 ++++++ + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c +index ac20ab3bbabf..35f83aea9516 100644 +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -3631,7 +3631,8 @@ static int mlx5_ib_init_multiport_master(struct mlx5_ib_dev *dev) + list_for_each_entry(mpi, &mlx5_ib_unaffiliated_port_list, + list) { + if (dev->sys_image_guid == mpi->sys_image_guid && +- (mlx5_core_native_port_num(mpi->mdev) - 1) == i) { ++ (mlx5_core_native_port_num(mpi->mdev) - 1) == i && ++ mlx5_core_same_coredev_type(dev->mdev, mpi->mdev)) { + bound = mlx5_ib_bind_slave_port(dev, mpi); + } + +@@ -4776,7 +4777,8 @@ static int mlx5r_mp_probe(struct auxiliary_device *adev, + + mutex_lock(&mlx5_ib_multiport_mutex); + list_for_each_entry(dev, &mlx5_ib_dev_list, ib_dev_list) { +- if (dev->sys_image_guid == mpi->sys_image_guid) ++ if (dev->sys_image_guid == mpi->sys_image_guid && ++ mlx5_core_same_coredev_type(dev->mdev, mpi->mdev)) + bound = mlx5_ib_bind_slave_port(dev, mpi); + + if (bound) { +diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h +index e23c692a34c7..a9fca765b3d1 100644 +--- a/include/linux/mlx5/driver.h ++++ b/include/linux/mlx5/driver.h +@@ -1233,6 +1233,12 @@ static inline bool mlx5_core_is_vf(const struct mlx5_core_dev *dev) + return dev->coredev_type == MLX5_COREDEV_VF; + } + ++static inline bool mlx5_core_same_coredev_type(const struct mlx5_core_dev *dev1, ++ const struct mlx5_core_dev *dev2) ++{ ++ return dev1->coredev_type == dev2->coredev_type; ++} ++ + static inline bool mlx5_core_is_ecpf(const struct mlx5_core_dev *dev) + { + return dev->caps.embedded_cpu; +-- +2.39.5 + diff --git a/queue-6.12/rdma-nldev-set-error-code-in-rdma_nl_notify_event.patch b/queue-6.12/rdma-nldev-set-error-code-in-rdma_nl_notify_event.patch new file mode 100644 index 00000000000..f4a5f102490 --- /dev/null +++ b/queue-6.12/rdma-nldev-set-error-code-in-rdma_nl_notify_event.patch @@ -0,0 +1,41 @@ +From d122db42c0d7ff10f982a3ea310e191d1c028422 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Dec 2024 09:33:10 +0200 +Subject: RDMA/nldev: Set error code in rdma_nl_notify_event + +From: Chiara Meiohas + +[ Upstream commit 13a6691910cc23ea9ba4066e098603088673d5b0 ] + +In case of error set the error code before the goto. + +Fixes: 6ff57a2ea7c2 ("RDMA/nldev: Fix NULL pointer dereferences issue in rdma_nl_notify_event") +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/linux-rdma/a84a2fc3-33b6-46da-a1bd-3343fa07eaf9@stanley.mountain/ +Signed-off-by: Chiara Meiohas +Reviewed-by: Maher Sanalla +Link: https://patch.msgid.link/13eb25961923f5de9eb9ecbbc94e26113d6049ef.1733815944.git.leonro@nvidia.com +Reviewed-by: Kalesh AP +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/core/nldev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c +index 7dc8e2ec62cc..f12189986303 100644 +--- a/drivers/infiniband/core/nldev.c ++++ b/drivers/infiniband/core/nldev.c +@@ -2802,8 +2802,8 @@ int rdma_nl_notify_event(struct ib_device *device, u32 port_num, + enum rdma_nl_notify_event_type type) + { + struct sk_buff *skb; ++ int ret = -EMSGSIZE; + struct net *net; +- int ret = 0; + void *nlh; + + net = read_pnet(&device->coredev.rdma_net); +-- +2.39.5 + diff --git a/queue-6.12/rdma-rtrs-ensure-ib_sge-list-is-accessible.patch b/queue-6.12/rdma-rtrs-ensure-ib_sge-list-is-accessible.patch new file mode 100644 index 00000000000..fb141ea5ae0 --- /dev/null +++ b/queue-6.12/rdma-rtrs-ensure-ib_sge-list-is-accessible.patch @@ -0,0 +1,71 @@ +From 33cdd8ca1d59edce9e9850b2b9545e6243b93c54 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Dec 2024 09:34:16 +0800 +Subject: RDMA/rtrs: Ensure 'ib_sge list' is accessible + +From: Li Zhijian + +[ Upstream commit fb514b31395946022f13a08e06a435f53cf9e8b3 ] + +Move the declaration of the 'ib_sge list' variable outside the +'always_invalidate' block to ensure it remains accessible for use +throughout the function. + +Previously, 'ib_sge list' was declared within the 'always_invalidate' +block, limiting its accessibility, then caused a +'BUG: kernel NULL pointer dereference'[1]. + ? __die_body.cold+0x19/0x27 + ? page_fault_oops+0x15a/0x2d0 + ? search_module_extables+0x19/0x60 + ? search_bpf_extables+0x5f/0x80 + ? exc_page_fault+0x7e/0x180 + ? asm_exc_page_fault+0x26/0x30 + ? memcpy_orig+0xd5/0x140 + rxe_mr_copy+0x1c3/0x200 [rdma_rxe] + ? rxe_pool_get_index+0x4b/0x80 [rdma_rxe] + copy_data+0xa5/0x230 [rdma_rxe] + rxe_requester+0xd9b/0xf70 [rdma_rxe] + ? finish_task_switch.isra.0+0x99/0x2e0 + rxe_sender+0x13/0x40 [rdma_rxe] + do_task+0x68/0x1e0 [rdma_rxe] + process_one_work+0x177/0x330 + worker_thread+0x252/0x390 + ? __pfx_worker_thread+0x10/0x10 + +This change ensures the variable is available for subsequent operations +that require it. + +[1] https://lore.kernel.org/linux-rdma/6a1f3e8f-deb0-49f9-bc69-a9b03ecfcda7@fujitsu.com/ + +Fixes: 9cb837480424 ("RDMA/rtrs: server: main functionality") +Signed-off-by: Li Zhijian +Link: https://patch.msgid.link/20241231013416.1290920-1-lizhijian@fujitsu.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/rtrs/rtrs-srv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +index e83d95647852..ef4abdea3c2d 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +@@ -349,6 +349,7 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id, + struct rtrs_srv_mr *srv_mr; + bool need_inval = false; + enum ib_send_flags flags; ++ struct ib_sge list; + u32 imm; + int err; + +@@ -401,7 +402,6 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id, + imm = rtrs_to_io_rsp_imm(id->msg_id, errno, need_inval); + imm_wr.wr.next = NULL; + if (always_invalidate) { +- struct ib_sge list; + struct rtrs_msg_rkey_rsp *msg; + + srv_mr = &srv_path->mrs[id->msg_id]; +-- +2.39.5 + diff --git a/queue-6.12/rdma-rxe-remove-the-direct-link-to-net_device.patch b/queue-6.12/rdma-rxe-remove-the-direct-link-to-net_device.patch new file mode 100644 index 00000000000..922b2c290eb --- /dev/null +++ b/queue-6.12/rdma-rxe-remove-the-direct-link-to-net_device.patch @@ -0,0 +1,403 @@ +From 1cf56968a89a9b70e96d6a06d91134de36c0c22b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Dec 2024 23:23:25 +0100 +Subject: RDMA/rxe: Remove the direct link to net_device + +From: Zhu Yanjun + +[ Upstream commit 2ac5415022d16d63d912a39a06f32f1f51140261 ] + +The similar patch in siw is in the link: +https://git.kernel.org/rdma/rdma/c/16b87037b48889 + +This problem also occurred in RXE. The following analyze this problem. +In the following Call Traces: +" +BUG: KASAN: slab-use-after-free in dev_get_flags+0x188/0x1d0 net/core/dev.c:8782 +Read of size 4 at addr ffff8880554640b0 by task kworker/1:4/5295 + +CPU: 1 UID: 0 PID: 5295 Comm: kworker/1:4 Not tainted +6.12.0-rc3-syzkaller-00399-g9197b73fd7bb #0 +Hardware name: Google Compute Engine/Google Compute Engine, +BIOS Google 09/13/2024 +Workqueue: infiniband ib_cache_event_task +Call Trace: + + __dump_stack lib/dump_stack.c:94 [inline] + dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 + print_address_description mm/kasan/report.c:377 [inline] + print_report+0x169/0x550 mm/kasan/report.c:488 + kasan_report+0x143/0x180 mm/kasan/report.c:601 + dev_get_flags+0x188/0x1d0 net/core/dev.c:8782 + rxe_query_port+0x12d/0x260 drivers/infiniband/sw/rxe/rxe_verbs.c:60 + __ib_query_port drivers/infiniband/core/device.c:2111 [inline] + ib_query_port+0x168/0x7d0 drivers/infiniband/core/device.c:2143 + ib_cache_update+0x1a9/0xb80 drivers/infiniband/core/cache.c:1494 + ib_cache_event_task+0xf3/0x1e0 drivers/infiniband/core/cache.c:1568 + process_one_work kernel/workqueue.c:3229 [inline] + process_scheduled_works+0xa65/0x1850 kernel/workqueue.c:3310 + worker_thread+0x870/0xd30 kernel/workqueue.c:3391 + kthread+0x2f2/0x390 kernel/kthread.c:389 + ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147 + ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 + +" + +1). In the link [1], + +" + infiniband syz2: set down +" + +This means that on 839.350575, the event ib_cache_event_task was sent andi +queued in ib_wq. + +2). In the link [1], + +" + team0 (unregistering): Port device team_slave_0 removed +" + +It indicates that before 843.251853, the net device should be freed. + +3). In the link [1], + +" + BUG: KASAN: slab-use-after-free in dev_get_flags+0x188/0x1d0 +" + +This means that on 850.559070, this slab-use-after-free problem occurred. + +In all, on 839.350575, the event ib_cache_event_task was sent and queued +in ib_wq, + +before 843.251853, the net device veth was freed. + +on 850.559070, this event was executed, and the mentioned freed net device +was called. Thus, the above call trace occurred. + +[1] https://syzkaller.appspot.com/x/log.txt?x=12e7025f980000 + +Reported-by: syzbot+4b87489410b4efd181bf@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=4b87489410b4efd181bf +Fixes: 8700e3e7c485 ("Soft RoCE driver") +Signed-off-by: Zhu Yanjun +Link: https://patch.msgid.link/20241220222325.2487767-1-yanjun.zhu@linux.dev +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/sw/rxe/rxe.c | 23 +++++++++++++++++++---- + drivers/infiniband/sw/rxe/rxe.h | 3 ++- + drivers/infiniband/sw/rxe/rxe_mcast.c | 22 ++++++++++++++++++++-- + drivers/infiniband/sw/rxe/rxe_net.c | 24 ++++++++++++++++++++---- + drivers/infiniband/sw/rxe/rxe_verbs.c | 26 +++++++++++++++++++++----- + drivers/infiniband/sw/rxe/rxe_verbs.h | 11 ++++++++--- + 6 files changed, 90 insertions(+), 19 deletions(-) + +diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c +index 255677bc12b2..1ba4a0c8726a 100644 +--- a/drivers/infiniband/sw/rxe/rxe.c ++++ b/drivers/infiniband/sw/rxe/rxe.c +@@ -40,6 +40,8 @@ void rxe_dealloc(struct ib_device *ib_dev) + /* initialize rxe device parameters */ + static void rxe_init_device_param(struct rxe_dev *rxe) + { ++ struct net_device *ndev; ++ + rxe->max_inline_data = RXE_MAX_INLINE_DATA; + + rxe->attr.vendor_id = RXE_VENDOR_ID; +@@ -71,8 +73,15 @@ static void rxe_init_device_param(struct rxe_dev *rxe) + rxe->attr.max_fast_reg_page_list_len = RXE_MAX_FMR_PAGE_LIST_LEN; + rxe->attr.max_pkeys = RXE_MAX_PKEYS; + rxe->attr.local_ca_ack_delay = RXE_LOCAL_CA_ACK_DELAY; ++ ++ ndev = rxe_ib_device_get_netdev(&rxe->ib_dev); ++ if (!ndev) ++ return; ++ + addrconf_addr_eui48((unsigned char *)&rxe->attr.sys_image_guid, +- rxe->ndev->dev_addr); ++ ndev->dev_addr); ++ ++ dev_put(ndev); + + rxe->max_ucontext = RXE_MAX_UCONTEXT; + } +@@ -109,10 +118,15 @@ static void rxe_init_port_param(struct rxe_port *port) + static void rxe_init_ports(struct rxe_dev *rxe) + { + struct rxe_port *port = &rxe->port; ++ struct net_device *ndev; + + rxe_init_port_param(port); ++ ndev = rxe_ib_device_get_netdev(&rxe->ib_dev); ++ if (!ndev) ++ return; + addrconf_addr_eui48((unsigned char *)&port->port_guid, +- rxe->ndev->dev_addr); ++ ndev->dev_addr); ++ dev_put(ndev); + spin_lock_init(&port->port_lock); + } + +@@ -167,12 +181,13 @@ void rxe_set_mtu(struct rxe_dev *rxe, unsigned int ndev_mtu) + /* called by ifc layer to create new rxe device. + * The caller should allocate memory for rxe by calling ib_alloc_device. + */ +-int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name) ++int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name, ++ struct net_device *ndev) + { + rxe_init(rxe); + rxe_set_mtu(rxe, mtu); + +- return rxe_register_device(rxe, ibdev_name); ++ return rxe_register_device(rxe, ibdev_name, ndev); + } + + static int rxe_newlink(const char *ibdev_name, struct net_device *ndev) +diff --git a/drivers/infiniband/sw/rxe/rxe.h b/drivers/infiniband/sw/rxe/rxe.h +index d8fb2c7af30a..fe7f97066732 100644 +--- a/drivers/infiniband/sw/rxe/rxe.h ++++ b/drivers/infiniband/sw/rxe/rxe.h +@@ -139,7 +139,8 @@ enum resp_states { + + void rxe_set_mtu(struct rxe_dev *rxe, unsigned int dev_mtu); + +-int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name); ++int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name, ++ struct net_device *ndev); + + void rxe_rcv(struct sk_buff *skb); + +diff --git a/drivers/infiniband/sw/rxe/rxe_mcast.c b/drivers/infiniband/sw/rxe/rxe_mcast.c +index 86cc2e18a7fd..07ff47bae31d 100644 +--- a/drivers/infiniband/sw/rxe/rxe_mcast.c ++++ b/drivers/infiniband/sw/rxe/rxe_mcast.c +@@ -31,10 +31,19 @@ + static int rxe_mcast_add(struct rxe_dev *rxe, union ib_gid *mgid) + { + unsigned char ll_addr[ETH_ALEN]; ++ struct net_device *ndev; ++ int ret; ++ ++ ndev = rxe_ib_device_get_netdev(&rxe->ib_dev); ++ if (!ndev) ++ return -ENODEV; + + ipv6_eth_mc_map((struct in6_addr *)mgid->raw, ll_addr); + +- return dev_mc_add(rxe->ndev, ll_addr); ++ ret = dev_mc_add(ndev, ll_addr); ++ dev_put(ndev); ++ ++ return ret; + } + + /** +@@ -47,10 +56,19 @@ static int rxe_mcast_add(struct rxe_dev *rxe, union ib_gid *mgid) + static int rxe_mcast_del(struct rxe_dev *rxe, union ib_gid *mgid) + { + unsigned char ll_addr[ETH_ALEN]; ++ struct net_device *ndev; ++ int ret; ++ ++ ndev = rxe_ib_device_get_netdev(&rxe->ib_dev); ++ if (!ndev) ++ return -ENODEV; + + ipv6_eth_mc_map((struct in6_addr *)mgid->raw, ll_addr); + +- return dev_mc_del(rxe->ndev, ll_addr); ++ ret = dev_mc_del(ndev, ll_addr); ++ dev_put(ndev); ++ ++ return ret; + } + + /** +diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c +index 75d1407db52d..8cc64ceeb356 100644 +--- a/drivers/infiniband/sw/rxe/rxe_net.c ++++ b/drivers/infiniband/sw/rxe/rxe_net.c +@@ -524,7 +524,16 @@ struct sk_buff *rxe_init_packet(struct rxe_dev *rxe, struct rxe_av *av, + */ + const char *rxe_parent_name(struct rxe_dev *rxe, unsigned int port_num) + { +- return rxe->ndev->name; ++ struct net_device *ndev; ++ char *ndev_name; ++ ++ ndev = rxe_ib_device_get_netdev(&rxe->ib_dev); ++ if (!ndev) ++ return NULL; ++ ndev_name = ndev->name; ++ dev_put(ndev); ++ ++ return ndev_name; + } + + int rxe_net_add(const char *ibdev_name, struct net_device *ndev) +@@ -536,10 +545,9 @@ int rxe_net_add(const char *ibdev_name, struct net_device *ndev) + if (!rxe) + return -ENOMEM; + +- rxe->ndev = ndev; + ib_mark_name_assigned_by_user(&rxe->ib_dev); + +- err = rxe_add(rxe, ndev->mtu, ibdev_name); ++ err = rxe_add(rxe, ndev->mtu, ibdev_name, ndev); + if (err) { + ib_dealloc_device(&rxe->ib_dev); + return err; +@@ -587,10 +595,18 @@ void rxe_port_down(struct rxe_dev *rxe) + + void rxe_set_port_state(struct rxe_dev *rxe) + { +- if (netif_running(rxe->ndev) && netif_carrier_ok(rxe->ndev)) ++ struct net_device *ndev; ++ ++ ndev = rxe_ib_device_get_netdev(&rxe->ib_dev); ++ if (!ndev) ++ return; ++ ++ if (netif_running(ndev) && netif_carrier_ok(ndev)) + rxe_port_up(rxe); + else + rxe_port_down(rxe); ++ ++ dev_put(ndev); + } + + static int rxe_notify(struct notifier_block *not_blk, +diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c +index 5c18f7e342f2..8a5fc20fd186 100644 +--- a/drivers/infiniband/sw/rxe/rxe_verbs.c ++++ b/drivers/infiniband/sw/rxe/rxe_verbs.c +@@ -41,6 +41,7 @@ static int rxe_query_port(struct ib_device *ibdev, + u32 port_num, struct ib_port_attr *attr) + { + struct rxe_dev *rxe = to_rdev(ibdev); ++ struct net_device *ndev; + int err, ret; + + if (port_num != 1) { +@@ -49,6 +50,12 @@ static int rxe_query_port(struct ib_device *ibdev, + goto err_out; + } + ++ ndev = rxe_ib_device_get_netdev(ibdev); ++ if (!ndev) { ++ err = -ENODEV; ++ goto err_out; ++ } ++ + memcpy(attr, &rxe->port.attr, sizeof(*attr)); + + mutex_lock(&rxe->usdev_lock); +@@ -57,13 +64,14 @@ static int rxe_query_port(struct ib_device *ibdev, + + if (attr->state == IB_PORT_ACTIVE) + attr->phys_state = IB_PORT_PHYS_STATE_LINK_UP; +- else if (dev_get_flags(rxe->ndev) & IFF_UP) ++ else if (dev_get_flags(ndev) & IFF_UP) + attr->phys_state = IB_PORT_PHYS_STATE_POLLING; + else + attr->phys_state = IB_PORT_PHYS_STATE_DISABLED; + + mutex_unlock(&rxe->usdev_lock); + ++ dev_put(ndev); + return ret; + + err_out: +@@ -1425,9 +1433,16 @@ static const struct attribute_group rxe_attr_group = { + static int rxe_enable_driver(struct ib_device *ib_dev) + { + struct rxe_dev *rxe = container_of(ib_dev, struct rxe_dev, ib_dev); ++ struct net_device *ndev; ++ ++ ndev = rxe_ib_device_get_netdev(ib_dev); ++ if (!ndev) ++ return -ENODEV; + + rxe_set_port_state(rxe); +- dev_info(&rxe->ib_dev.dev, "added %s\n", netdev_name(rxe->ndev)); ++ dev_info(&rxe->ib_dev.dev, "added %s\n", netdev_name(ndev)); ++ ++ dev_put(ndev); + return 0; + } + +@@ -1495,7 +1510,8 @@ static const struct ib_device_ops rxe_dev_ops = { + INIT_RDMA_OBJ_SIZE(ib_mw, rxe_mw, ibmw), + }; + +-int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name) ++int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name, ++ struct net_device *ndev) + { + int err; + struct ib_device *dev = &rxe->ib_dev; +@@ -1507,13 +1523,13 @@ int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name) + dev->num_comp_vectors = num_possible_cpus(); + dev->local_dma_lkey = 0; + addrconf_addr_eui48((unsigned char *)&dev->node_guid, +- rxe->ndev->dev_addr); ++ ndev->dev_addr); + + dev->uverbs_cmd_mask |= BIT_ULL(IB_USER_VERBS_CMD_POST_SEND) | + BIT_ULL(IB_USER_VERBS_CMD_REQ_NOTIFY_CQ); + + ib_set_device_ops(dev, &rxe_dev_ops); +- err = ib_device_set_netdev(&rxe->ib_dev, rxe->ndev, 1); ++ err = ib_device_set_netdev(&rxe->ib_dev, ndev, 1); + if (err) + return err; + +diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h +index 3c1354f82283..6573ceec0ef5 100644 +--- a/drivers/infiniband/sw/rxe/rxe_verbs.h ++++ b/drivers/infiniband/sw/rxe/rxe_verbs.h +@@ -370,6 +370,7 @@ struct rxe_port { + u32 qp_gsi_index; + }; + ++#define RXE_PORT 1 + struct rxe_dev { + struct ib_device ib_dev; + struct ib_device_attr attr; +@@ -377,8 +378,6 @@ struct rxe_dev { + int max_inline_data; + struct mutex usdev_lock; + +- struct net_device *ndev; +- + struct rxe_pool uc_pool; + struct rxe_pool pd_pool; + struct rxe_pool ah_pool; +@@ -406,6 +405,11 @@ struct rxe_dev { + struct crypto_shash *tfm; + }; + ++static inline struct net_device *rxe_ib_device_get_netdev(struct ib_device *dev) ++{ ++ return ib_device_get_netdev(dev, RXE_PORT); ++} ++ + static inline void rxe_counter_inc(struct rxe_dev *rxe, enum rxe_counters index) + { + atomic64_inc(&rxe->stats_counters[index]); +@@ -471,6 +475,7 @@ static inline struct rxe_pd *rxe_mw_pd(struct rxe_mw *mw) + return to_rpd(mw->ibmw.pd); + } + +-int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name); ++int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name, ++ struct net_device *ndev); + + #endif /* RXE_VERBS_H */ +-- +2.39.5 + diff --git a/queue-6.12/rdma-siw-remove-direct-link-to-net_device.patch b/queue-6.12/rdma-siw-remove-direct-link-to-net_device.patch new file mode 100644 index 00000000000..8deea14a1cc --- /dev/null +++ b/queue-6.12/rdma-siw-remove-direct-link-to-net_device.patch @@ -0,0 +1,268 @@ +From c1670caa81349d02aa354ef37ac8fce5612a5537 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Dec 2024 16:18:48 +0100 +Subject: RDMA/siw: Remove direct link to net_device + +From: Bernard Metzler + +[ Upstream commit 16b87037b48889d21854c8e97aec8a1baf2642b3 ] + +Do not manage a per device direct link to net_device. Rely +on associated ib_devices net_device management, not doubling +the effort locally. A badly managed local link to net_device +was causing a 'KASAN: slab-use-after-free' exception during +siw_query_port() call. + +Fixes: bdcf26bf9b3a ("rdma/siw: network and RDMA core interface") +Reported-by: syzbot+4b87489410b4efd181bf@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=4b87489410b4efd181bf +Signed-off-by: Bernard Metzler +Link: https://patch.msgid.link/20241212151848.564872-1-bmt@zurich.ibm.com +Reviewed-by: Zhu Yanjun +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/sw/siw/siw.h | 7 +++--- + drivers/infiniband/sw/siw/siw_cm.c | 27 ++++++++++++++++----- + drivers/infiniband/sw/siw/siw_main.c | 15 +----------- + drivers/infiniband/sw/siw/siw_verbs.c | 35 ++++++++++++++++++--------- + 4 files changed, 49 insertions(+), 35 deletions(-) + +diff --git a/drivers/infiniband/sw/siw/siw.h b/drivers/infiniband/sw/siw/siw.h +index 86d4d6a2170e..ea5eee50dc39 100644 +--- a/drivers/infiniband/sw/siw/siw.h ++++ b/drivers/infiniband/sw/siw/siw.h +@@ -46,6 +46,9 @@ + */ + #define SIW_IRQ_MAXBURST_SQ_ACTIVE 4 + ++/* There is always only a port 1 per siw device */ ++#define SIW_PORT 1 ++ + struct siw_dev_cap { + int max_qp; + int max_qp_wr; +@@ -69,16 +72,12 @@ struct siw_pd { + + struct siw_device { + struct ib_device base_dev; +- struct net_device *netdev; + struct siw_dev_cap attrs; + + u32 vendor_part_id; + int numa_node; + char raw_gid[ETH_ALEN]; + +- /* physical port state (only one port per device) */ +- enum ib_port_state state; +- + spinlock_t lock; + + struct xarray qp_xa; +diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c +index 86323918a570..708b13993fdf 100644 +--- a/drivers/infiniband/sw/siw/siw_cm.c ++++ b/drivers/infiniband/sw/siw/siw_cm.c +@@ -1759,6 +1759,7 @@ int siw_create_listen(struct iw_cm_id *id, int backlog) + { + struct socket *s; + struct siw_cep *cep = NULL; ++ struct net_device *ndev = NULL; + struct siw_device *sdev = to_siw_dev(id->device); + int addr_family = id->local_addr.ss_family; + int rv = 0; +@@ -1779,9 +1780,15 @@ int siw_create_listen(struct iw_cm_id *id, int backlog) + struct sockaddr_in *laddr = &to_sockaddr_in(id->local_addr); + + /* For wildcard addr, limit binding to current device only */ +- if (ipv4_is_zeronet(laddr->sin_addr.s_addr)) +- s->sk->sk_bound_dev_if = sdev->netdev->ifindex; +- ++ if (ipv4_is_zeronet(laddr->sin_addr.s_addr)) { ++ ndev = ib_device_get_netdev(id->device, SIW_PORT); ++ if (ndev) { ++ s->sk->sk_bound_dev_if = ndev->ifindex; ++ } else { ++ rv = -ENODEV; ++ goto error; ++ } ++ } + rv = s->ops->bind(s, (struct sockaddr *)laddr, + sizeof(struct sockaddr_in)); + } else { +@@ -1797,9 +1804,15 @@ int siw_create_listen(struct iw_cm_id *id, int backlog) + } + + /* For wildcard addr, limit binding to current device only */ +- if (ipv6_addr_any(&laddr->sin6_addr)) +- s->sk->sk_bound_dev_if = sdev->netdev->ifindex; +- ++ if (ipv6_addr_any(&laddr->sin6_addr)) { ++ ndev = ib_device_get_netdev(id->device, SIW_PORT); ++ if (ndev) { ++ s->sk->sk_bound_dev_if = ndev->ifindex; ++ } else { ++ rv = -ENODEV; ++ goto error; ++ } ++ } + rv = s->ops->bind(s, (struct sockaddr *)laddr, + sizeof(struct sockaddr_in6)); + } +@@ -1860,6 +1873,7 @@ int siw_create_listen(struct iw_cm_id *id, int backlog) + } + list_add_tail(&cep->listenq, (struct list_head *)id->provider_data); + cep->state = SIW_EPSTATE_LISTENING; ++ dev_put(ndev); + + siw_dbg(id->device, "Listen at laddr %pISp\n", &id->local_addr); + +@@ -1879,6 +1893,7 @@ int siw_create_listen(struct iw_cm_id *id, int backlog) + siw_cep_set_free_and_put(cep); + } + sock_release(s); ++ dev_put(ndev); + + return rv; + } +diff --git a/drivers/infiniband/sw/siw/siw_main.c b/drivers/infiniband/sw/siw/siw_main.c +index 17abef48abcd..14d3103aee6f 100644 +--- a/drivers/infiniband/sw/siw/siw_main.c ++++ b/drivers/infiniband/sw/siw/siw_main.c +@@ -287,7 +287,6 @@ static struct siw_device *siw_device_create(struct net_device *netdev) + return NULL; + + base_dev = &sdev->base_dev; +- sdev->netdev = netdev; + + if (netdev->addr_len) { + memcpy(sdev->raw_gid, netdev->dev_addr, +@@ -381,12 +380,10 @@ static int siw_netdev_event(struct notifier_block *nb, unsigned long event, + + switch (event) { + case NETDEV_UP: +- sdev->state = IB_PORT_ACTIVE; + siw_port_event(sdev, 1, IB_EVENT_PORT_ACTIVE); + break; + + case NETDEV_DOWN: +- sdev->state = IB_PORT_DOWN; + siw_port_event(sdev, 1, IB_EVENT_PORT_ERR); + break; + +@@ -407,12 +404,8 @@ static int siw_netdev_event(struct notifier_block *nb, unsigned long event, + siw_port_event(sdev, 1, IB_EVENT_LID_CHANGE); + break; + /* +- * Todo: Below netdev events are currently not handled. ++ * All other events are not handled + */ +- case NETDEV_CHANGEMTU: +- case NETDEV_CHANGE: +- break; +- + default: + break; + } +@@ -442,12 +435,6 @@ static int siw_newlink(const char *basedev_name, struct net_device *netdev) + sdev = siw_device_create(netdev); + if (sdev) { + dev_dbg(&netdev->dev, "siw: new device\n"); +- +- if (netif_running(netdev) && netif_carrier_ok(netdev)) +- sdev->state = IB_PORT_ACTIVE; +- else +- sdev->state = IB_PORT_DOWN; +- + ib_mark_name_assigned_by_user(&sdev->base_dev); + rv = siw_device_register(sdev, basedev_name); + if (rv) +diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c +index 986666c19378..7ca0297d68a4 100644 +--- a/drivers/infiniband/sw/siw/siw_verbs.c ++++ b/drivers/infiniband/sw/siw/siw_verbs.c +@@ -171,21 +171,29 @@ int siw_query_device(struct ib_device *base_dev, struct ib_device_attr *attr, + int siw_query_port(struct ib_device *base_dev, u32 port, + struct ib_port_attr *attr) + { +- struct siw_device *sdev = to_siw_dev(base_dev); ++ struct net_device *ndev; + int rv; + + memset(attr, 0, sizeof(*attr)); + + rv = ib_get_eth_speed(base_dev, port, &attr->active_speed, + &attr->active_width); ++ if (rv) ++ return rv; ++ ++ ndev = ib_device_get_netdev(base_dev, SIW_PORT); ++ if (!ndev) ++ return -ENODEV; ++ + attr->gid_tbl_len = 1; + attr->max_msg_sz = -1; +- attr->max_mtu = ib_mtu_int_to_enum(sdev->netdev->mtu); +- attr->active_mtu = ib_mtu_int_to_enum(sdev->netdev->mtu); +- attr->phys_state = sdev->state == IB_PORT_ACTIVE ? ++ attr->max_mtu = ib_mtu_int_to_enum(ndev->max_mtu); ++ attr->active_mtu = ib_mtu_int_to_enum(READ_ONCE(ndev->mtu)); ++ attr->phys_state = (netif_running(ndev) && netif_carrier_ok(ndev)) ? + IB_PORT_PHYS_STATE_LINK_UP : IB_PORT_PHYS_STATE_DISABLED; ++ attr->state = attr->phys_state == IB_PORT_PHYS_STATE_LINK_UP ? ++ IB_PORT_ACTIVE : IB_PORT_DOWN; + attr->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_DEVICE_MGMT_SUP; +- attr->state = sdev->state; + /* + * All zero + * +@@ -199,6 +207,7 @@ int siw_query_port(struct ib_device *base_dev, u32 port, + * attr->subnet_timeout = 0; + * attr->init_type_repy = 0; + */ ++ dev_put(ndev); + return rv; + } + +@@ -505,21 +514,24 @@ int siw_query_qp(struct ib_qp *base_qp, struct ib_qp_attr *qp_attr, + int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr) + { + struct siw_qp *qp; +- struct siw_device *sdev; ++ struct net_device *ndev; + +- if (base_qp && qp_attr && qp_init_attr) { ++ if (base_qp && qp_attr && qp_init_attr) + qp = to_siw_qp(base_qp); +- sdev = to_siw_dev(base_qp->device); +- } else { ++ else + return -EINVAL; +- } ++ ++ ndev = ib_device_get_netdev(base_qp->device, SIW_PORT); ++ if (!ndev) ++ return -ENODEV; ++ + qp_attr->qp_state = siw_qp_state_to_ib_qp_state[qp->attrs.state]; + qp_attr->cap.max_inline_data = SIW_MAX_INLINE; + qp_attr->cap.max_send_wr = qp->attrs.sq_size; + qp_attr->cap.max_send_sge = qp->attrs.sq_max_sges; + qp_attr->cap.max_recv_wr = qp->attrs.rq_size; + qp_attr->cap.max_recv_sge = qp->attrs.rq_max_sges; +- qp_attr->path_mtu = ib_mtu_int_to_enum(sdev->netdev->mtu); ++ qp_attr->path_mtu = ib_mtu_int_to_enum(READ_ONCE(ndev->mtu)); + qp_attr->max_rd_atomic = qp->attrs.irq_size; + qp_attr->max_dest_rd_atomic = qp->attrs.orq_size; + +@@ -534,6 +546,7 @@ int siw_query_qp(struct ib_qp *base_qp, struct ib_qp_attr *qp_attr, + + qp_init_attr->cap = qp_attr->cap; + ++ dev_put(ndev); + return 0; + } + +-- +2.39.5 + diff --git a/queue-6.12/sched_ext-fix-application-of-sizeof-to-pointer.patch b/queue-6.12/sched_ext-fix-application-of-sizeof-to-pointer.patch new file mode 100644 index 00000000000..beb97751b49 --- /dev/null +++ b/queue-6.12/sched_ext-fix-application-of-sizeof-to-pointer.patch @@ -0,0 +1,42 @@ +From 5ea1d14064be96f46f15f54568e6c0ad961882bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Nov 2024 10:51:29 +0800 +Subject: sched_ext: fix application of sizeof to pointer + +From: guanjing + +[ Upstream commit f24d192985cbd6782850fdbb3839039da2f0ee76 ] + +sizeof when applied to a pointer typed expression gives the size of +the pointer. + +The proper fix in this particular case is to code sizeof(*cpuset) +instead of sizeof(cpuset). + +This issue was detected with the help of Coccinelle. + +Fixes: 22a920209ab6 ("sched_ext: Implement tickless support") +Signed-off-by: guanjing +Acked-by: Andrea Righi +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + tools/sched_ext/scx_central.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/sched_ext/scx_central.c b/tools/sched_ext/scx_central.c +index 21deea320bd7..e938156ed0a0 100644 +--- a/tools/sched_ext/scx_central.c ++++ b/tools/sched_ext/scx_central.c +@@ -97,7 +97,7 @@ int main(int argc, char **argv) + SCX_BUG_ON(!cpuset, "Failed to allocate cpuset"); + CPU_ZERO(cpuset); + CPU_SET(skel->rodata->central_cpu, cpuset); +- SCX_BUG_ON(sched_setaffinity(0, sizeof(cpuset), cpuset), ++ SCX_BUG_ON(sched_setaffinity(0, sizeof(*cpuset), cpuset), + "Failed to affinitize to central CPU %d (max %d)", + skel->rodata->central_cpu, skel->rodata->nr_cpu_ids - 1); + CPU_FREE(cpuset); +-- +2.39.5 + diff --git a/queue-6.12/selftests-net-local_termination-require-mausezahn.patch b/queue-6.12/selftests-net-local_termination-require-mausezahn.patch new file mode 100644 index 00000000000..6173221a75d --- /dev/null +++ b/queue-6.12/selftests-net-local_termination-require-mausezahn.patch @@ -0,0 +1,36 @@ +From 87b7684a2d550f35d889c315fdc98897ad9b0b17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Dec 2024 17:54:10 +0200 +Subject: selftests: net: local_termination: require mausezahn + +From: Vladimir Oltean + +[ Upstream commit 246068b86b1c36e4590388ab8f278e21f1997dc1 ] + +Since the blamed commit, we require mausezahn because send_raw() uses it. +Remove the "REQUIRE_MZ=no" line, which overwrites the default of requiring it. + +Fixes: 237979504264 ("selftests: net: local_termination: add PTP frames to the mix") +Signed-off-by: Vladimir Oltean +Link: https://patch.msgid.link/20241219155410.1856868-1-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/local_termination.sh | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/tools/testing/selftests/net/forwarding/local_termination.sh b/tools/testing/selftests/net/forwarding/local_termination.sh +index c35548767756..ecd34f364125 100755 +--- a/tools/testing/selftests/net/forwarding/local_termination.sh ++++ b/tools/testing/selftests/net/forwarding/local_termination.sh +@@ -7,7 +7,6 @@ ALL_TESTS="standalone vlan_unaware_bridge vlan_aware_bridge test_vlan \ + NUM_NETIFS=2 + PING_COUNT=1 + REQUIRE_MTOOLS=yes +-REQUIRE_MZ=no + + source lib.sh + +-- +2.39.5 + diff --git a/queue-6.12/series b/queue-6.12/series index 89a5e39d4d6..f5afe34f1ff 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -9,3 +9,67 @@ pmdomain-core-add-dummy-release-function-to-genpd-device.patch tracing-have-process_string-also-allow-arrays.patch block-lift-bio_is_zone_append-to-bio.h.patch btrfs-use-bio_is_zone_append-in-the-completion-handl.patch +rdma-bnxt_re-remove-always-true-dattr-validity-check.patch +sched_ext-fix-application-of-sizeof-to-pointer.patch +rdma-mlx5-enforce-same-type-port-association-for-mul.patch +rdma-bnxt_re-fix-max-sges-for-the-work-request.patch +rdma-bnxt_re-avoid-initializing-the-software-queue-f.patch +rdma-bnxt_re-avoid-sending-the-modify-qp-workaround-.patch +rdma-core-fix-enodev-error-for-iwarp-test-over-vlan.patch +nvme-pci-512-byte-aligned-dma-pool-segment-quirk.patch +wifi-iwlwifi-fix-crf-name-for-bz.patch +rdma-bnxt_re-fix-the-check-for-9060-condition.patch +rdma-bnxt_re-add-check-for-path-mtu-in-modify_qp.patch +rdma-bnxt_re-fix-reporting-hw_ver-in-query_device.patch +rdma-nldev-set-error-code-in-rdma_nl_notify_event.patch +rdma-siw-remove-direct-link-to-net_device.patch +rdma-bnxt_re-fix-max_qp_wrs-reported.patch +rdma-bnxt_re-disable-use-of-reserved-wqes.patch +rdma-bnxt_re-add-send-queue-size-check-for-variable-.patch +rdma-bnxt_re-fix-msn-table-size-for-variable-wqe-mod.patch +rdma-bnxt_re-fix-the-locking-while-accessing-the-qp-.patch +net-phy-micrel-dynamically-control-external-clock-of.patch +drm-bridge-adv7511_audio-update-audio-infoframe-prop.patch +net-dsa-microchip-fix-ksz9477-set_ageing_time-functi.patch +net-dsa-microchip-fix-lan937x-set_ageing_time-functi.patch +selftests-net-local_termination-require-mausezahn.patch +netdev-genl-avoid-empty-messages-in-napi-get.patch +rdma-hns-fix-mapping-error-of-zero-hop-wqe-buffer.patch +rdma-hns-fix-accessing-invalid-dip_ctx-during-destro.patch +rdma-hns-fix-warning-storm-caused-by-invalid-input-i.patch +rdma-hns-fix-missing-flush-cqe-for-dwqe.patch +drm-xe-revert-some-changes-that-break-a-mesa-debug-t.patch +drm-xe-pf-use-correct-function-to-check-lmem-provisi.patch +drm-xe-fix-fault-on-fd-close-after-unbind.patch +net-stmmac-restructure-the-error-path-of-stmmac_prob.patch +net-fix-memory-leak-in-tcp_conn_request.patch +net-fix-netns-for-ip_tunnel_init_flow.patch +netrom-check-buffer-length-before-accessing-it.patch +net-pse-pd-tps23881-fix-power-on-off-issue.patch +net-mlx5-dr-select-msix-vector-0-for-completion-queu.patch +net-mlx5e-macsec-maintain-tx-sa-from-encoding_sa.patch +net-mlx5e-skip-restore-tc-rules-for-vport-rep-withou.patch +net-mlx5e-keep-netdev-when-leave-switchdev-for-devli.patch +rdma-rxe-remove-the-direct-link-to-net_device.patch +drm-i915-cx0_phy-fix-c10-pll-programming-sequence.patch +drm-i915-dg1-fix-power-gate-sequence.patch +workqueue-add-printf-attribute-to-__alloc_workqueue.patch +netfilter-nft_set_hash-unaligned-atomic-read-on-stru.patch +net-llc-reset-skb-transport_header.patch +nvmet-don-t-overflow-subsysnqn.patch +alsa-usb-audio-us16x08-initialize-array-before-use.patch +eth-bcmsysport-fix-call-balance-of-priv-clk-handling.patch +net-mv643xx_eth-fix-an-of-node-reference-leak.patch +net-wwan-t7xx-fix-fsm-command-timeout-issue.patch +rdma-rtrs-ensure-ib_sge-list-is-accessible.patch +rdma-bnxt_re-fix-error-recovery-sequence.patch +io_uring-net-always-initialize-kmsg-msg.msg_inq-upfr.patch +net-sfc-correct-key_len-for-efx_tc_ct_zone_ht_params.patch +net-reenable-netif_f_ipv6_csum-offload-for-big-tcp-p.patch +net-restrict-so_reuseport-to-inet-sockets.patch +net-wwan-iosm-properly-check-for-valid-exec-stage-in.patch +af_packet-fix-vlan_get_tci-vs-msg_peek.patch +af_packet-fix-vlan_get_protocol_dgram-vs-msg_peek.patch +ila-serialize-calls-to-nf_register_net_hooks.patch +net-ti-icssg-prueth-fix-firmware-load-sequence.patch +net-ti-icssg-prueth-fix-clearing-of-iep_cmp_cfg-regi.patch diff --git a/queue-6.12/wifi-iwlwifi-fix-crf-name-for-bz.patch b/queue-6.12/wifi-iwlwifi-fix-crf-name-for-bz.patch new file mode 100644 index 00000000000..219612214f1 --- /dev/null +++ b/queue-6.12/wifi-iwlwifi-fix-crf-name-for-bz.patch @@ -0,0 +1,111 @@ +From 2cabd48c80a45111b7b15ef6f88df4caecc4f52a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Dec 2024 13:29:42 +0200 +Subject: wifi: iwlwifi: fix CRF name for Bz + +From: Emmanuel Grumbach + +[ Upstream commit 0e8c52091633b354b12d0c29a27a22077584c111 ] + +We had BE201 hard coded. +Look at the RF_ID and decide based on its value. + +Fixes: 6795a37161fb ("wifi: iwlwifi: Print a specific device name.") +Signed-off-by: Emmanuel Grumbach +Signed-off-by: Miri Korenblit +Link: https://patch.msgid.link/20241212132940.b9eebda1ca60.I36791a134ed5e538e059418eb6520761da97b44c@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/cfg/bz.c | 1 + + .../net/wireless/intel/iwlwifi/iwl-config.h | 1 + + drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 37 ++++++++++++++++++- + 3 files changed, 38 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c +index fa1be8c54d3c..c18c6e933f47 100644 +--- a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c ++++ b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c +@@ -161,6 +161,7 @@ const struct iwl_cfg_trans_params iwl_gl_trans_cfg = { + + const char iwl_bz_name[] = "Intel(R) TBD Bz device"; + const char iwl_fm_name[] = "Intel(R) Wi-Fi 7 BE201 320MHz"; ++const char iwl_wh_name[] = "Intel(R) Wi-Fi 7 BE211 320MHz"; + const char iwl_gl_name[] = "Intel(R) Wi-Fi 7 BE200 320MHz"; + const char iwl_mtp_name[] = "Intel(R) Wi-Fi 7 BE202 160MHz"; + +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h +index 34c91deca57b..17721bb47e25 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h +@@ -545,6 +545,7 @@ extern const char iwl_ax231_name[]; + extern const char iwl_ax411_name[]; + extern const char iwl_bz_name[]; + extern const char iwl_fm_name[]; ++extern const char iwl_wh_name[]; + extern const char iwl_gl_name[]; + extern const char iwl_mtp_name[]; + extern const char iwl_sc_name[]; +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +index 805fb249a0c6..8fb2aa282242 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +@@ -1106,19 +1106,54 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct iwl_dev_info iwl_dev_info_table[] = { + iwlax210_2ax_cfg_so_jf_b0, iwl9462_name), + + /* Bz */ +-/* FIXME: need to change the naming according to the actual CRF */ + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, ++ IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, ++ iwl_cfg_bz, iwl_ax201_name), ++ ++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, ++ IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, ++ IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, ++ IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, ++ iwl_cfg_bz, iwl_ax211_name), ++ ++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, ++ IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, ++ IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + iwl_cfg_bz, iwl_fm_name), + ++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, ++ IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, ++ IWL_CFG_RF_TYPE_WH, IWL_CFG_ANY, IWL_CFG_ANY, ++ IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, ++ iwl_cfg_bz, iwl_wh_name), ++ + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_BZ_W, IWL_CFG_ANY, ++ IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, ++ iwl_cfg_bz, iwl_ax201_name), ++ ++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, ++ IWL_CFG_MAC_TYPE_BZ_W, IWL_CFG_ANY, ++ IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, IWL_CFG_ANY, ++ IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, ++ iwl_cfg_bz, iwl_ax211_name), ++ ++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, ++ IWL_CFG_MAC_TYPE_BZ_W, IWL_CFG_ANY, ++ IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, + iwl_cfg_bz, iwl_fm_name), + ++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, ++ IWL_CFG_MAC_TYPE_BZ_W, IWL_CFG_ANY, ++ IWL_CFG_RF_TYPE_WH, IWL_CFG_ANY, IWL_CFG_ANY, ++ IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, ++ iwl_cfg_bz, iwl_wh_name), ++ + /* Ga (Gl) */ + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_GL, IWL_CFG_ANY, +-- +2.39.5 + diff --git a/queue-6.12/workqueue-add-printf-attribute-to-__alloc_workqueue.patch b/queue-6.12/workqueue-add-printf-attribute-to-__alloc_workqueue.patch new file mode 100644 index 00000000000..549568b98bc --- /dev/null +++ b/queue-6.12/workqueue-add-printf-attribute-to-__alloc_workqueue.patch @@ -0,0 +1,42 @@ +From c8aed6b95bdb24be003b64b8ae70bde6534b267f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Dec 2024 12:43:58 +0800 +Subject: workqueue: add printf attribute to __alloc_workqueue() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Su Hui + +[ Upstream commit d57212f281fda9056412cd6cca983d9d2eb89f53 ] + +Fix a compiler warning with W=1: +kernel/workqueue.c: error: +function ‘__alloc_workqueue’ might be a candidate for ‘gnu_printf’ +format attribute[-Werror=suggest-attribute=format] + 5657 | name_len = vsnprintf(wq->name, sizeof(wq->name), fmt, args); + | ^~~~~~~~ + +Fixes: 9b59a85a84dc ("workqueue: Don't call va_start / va_end twice") +Signed-off-by: Su Hui +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/workqueue.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 9949ffad8df0..25bdd9af7eb6 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -5627,6 +5627,7 @@ static void wq_adjust_max_active(struct workqueue_struct *wq) + } while (activated); + } + ++__printf(1, 0) + static struct workqueue_struct *__alloc_workqueue(const char *fmt, + unsigned int flags, + int max_active, va_list args) +-- +2.39.5 +