From 48ac344cb8ef920b1993f3ef574498adb164f628 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 17 Feb 2026 13:45:29 +0100 Subject: [PATCH] 5.15-stable patches added patches: btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_info_full.patch bus-fsl-mc-fix-use-after-free-in-driver_override_show.patch bus-fsl-mc-replace-snprintf-and-sprintf-with-sysfs_emit-in-sysfs-show-functions.patch crypto-virtio-remove-duplicated-virtqueue_kick-in-virtio_crypto_skcipher_crypt_req.patch mptcp-fix-race-in-mptcp_pm_nl_flush_addrs_doit.patch net-dsa-free-routing-table-on-probe-failure.patch pci-endpoint-automatically-create-a-function-specific-attributes-group.patch pci-endpoint-avoid-creating-sub-groups-asynchronously.patch pci-endpoint-remove-unused-field-in-struct-pci_epf_group.patch scsi-qla2xxx-fix-bsg_done-causing-double-free.patch scsi-qla2xxx-free-sp-in-error-path-to-fix-system-crash.patch scsi-qla2xxx-reduce-fabric-scan-duplicate-code.patch scsi-qla2xxx-remove-dead-code-gnn-id.patch scsi-qla2xxx-use-named-initializers-for-port_state_str.patch selftests-mptcp-pm-ensure-unknown-flags-are-ignored.patch smb-client-set-correct-id-uid-and-cruid-for-multiuser-automounts.patch smb-server-fix-leak-of-active_num_conn-in-ksmbd_tcp_new_connection.patch --- ...write-in-btrfs_clear_space_info_full.patch | 246 ++++++ ...e-after-free-in-driver_override_show.patch | 50 ++ ...h-sysfs_emit-in-sysfs-show-functions.patch | 48 ++ ...-in-virtio_crypto_skcipher_crypt_req.patch | 40 + ...race-in-mptcp_pm_nl_flush_addrs_doit.patch | 82 ++ ...-free-routing-table-on-probe-failure.patch | 160 ++++ ...a-function-specific-attributes-group.patch | 235 ++++++ ...d-creating-sub-groups-asynchronously.patch | 103 +++ ...unused-field-in-struct-pci_epf_group.patch | 43 ++ ...xxx-fix-bsg_done-causing-double-free.patch | 125 +++ ...sp-in-error-path-to-fix-system-crash.patch | 87 +++ ...xx-reduce-fabric-scan-duplicate-code.patch | 716 ++++++++++++++++++ ...scsi-qla2xxx-remove-dead-code-gnn-id.patch | 214 ++++++ ...amed-initializers-for-port_state_str.patch | 95 +++ ...-pm-ensure-unknown-flags-are-ignored.patch | 94 +++ queue-5.15/series | 17 + ...d-and-cruid-for-multiuser-automounts.patch | 64 ++ ...num_conn-in-ksmbd_tcp_new_connection.patch | 48 ++ 18 files changed, 2467 insertions(+) create mode 100644 queue-5.15/btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_info_full.patch create mode 100644 queue-5.15/bus-fsl-mc-fix-use-after-free-in-driver_override_show.patch create mode 100644 queue-5.15/bus-fsl-mc-replace-snprintf-and-sprintf-with-sysfs_emit-in-sysfs-show-functions.patch create mode 100644 queue-5.15/crypto-virtio-remove-duplicated-virtqueue_kick-in-virtio_crypto_skcipher_crypt_req.patch create mode 100644 queue-5.15/mptcp-fix-race-in-mptcp_pm_nl_flush_addrs_doit.patch create mode 100644 queue-5.15/net-dsa-free-routing-table-on-probe-failure.patch create mode 100644 queue-5.15/pci-endpoint-automatically-create-a-function-specific-attributes-group.patch create mode 100644 queue-5.15/pci-endpoint-avoid-creating-sub-groups-asynchronously.patch create mode 100644 queue-5.15/pci-endpoint-remove-unused-field-in-struct-pci_epf_group.patch create mode 100644 queue-5.15/scsi-qla2xxx-fix-bsg_done-causing-double-free.patch create mode 100644 queue-5.15/scsi-qla2xxx-free-sp-in-error-path-to-fix-system-crash.patch create mode 100644 queue-5.15/scsi-qla2xxx-reduce-fabric-scan-duplicate-code.patch create mode 100644 queue-5.15/scsi-qla2xxx-remove-dead-code-gnn-id.patch create mode 100644 queue-5.15/scsi-qla2xxx-use-named-initializers-for-port_state_str.patch create mode 100644 queue-5.15/selftests-mptcp-pm-ensure-unknown-flags-are-ignored.patch create mode 100644 queue-5.15/smb-client-set-correct-id-uid-and-cruid-for-multiuser-automounts.patch create mode 100644 queue-5.15/smb-server-fix-leak-of-active_num_conn-in-ksmbd_tcp_new_connection.patch diff --git a/queue-5.15/btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_info_full.patch b/queue-5.15/btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_info_full.patch new file mode 100644 index 0000000000..cf590b08ce --- /dev/null +++ b/queue-5.15/btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_info_full.patch @@ -0,0 +1,246 @@ +From stable+bounces-215606-greg=kroah.com@vger.kernel.org Tue Feb 10 07:56:56 2026 +From: Rahul Sharma +Date: Tue, 10 Feb 2026 14:55:04 +0800 +Subject: btrfs: fix racy bitfield write in btrfs_clear_space_info_full() +To: gregkh@linuxfoundation.org, stable@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, Boris Burkov , Qu Wenruo , David Sterba , Rahul Sharma +Message-ID: <20260210065504.562467-1-black.hawk@163.com> + +From: Boris Burkov + +[ Upstream commit 38e818718c5e04961eea0fa8feff3f100ce40408 ] + +>From the memory-barriers.txt document regarding memory barrier ordering +guarantees: + + (*) These guarantees do not apply to bitfields, because compilers often + generate code to modify these using non-atomic read-modify-write + sequences. Do not attempt to use bitfields to synchronize parallel + algorithms. + + (*) Even in cases where bitfields are protected by locks, all fields + in a given bitfield must be protected by one lock. If two fields + in a given bitfield are protected by different locks, the compiler's + non-atomic read-modify-write sequences can cause an update to one + field to corrupt the value of an adjacent field. + +btrfs_space_info has a bitfield sharing an underlying word consisting of +the fields full, chunk_alloc, and flush: + +struct btrfs_space_info { + struct btrfs_fs_info * fs_info; /* 0 8 */ + struct btrfs_space_info * parent; /* 8 8 */ + ... + int clamp; /* 172 4 */ + unsigned int full:1; /* 176: 0 4 */ + unsigned int chunk_alloc:1; /* 176: 1 4 */ + unsigned int flush:1; /* 176: 2 4 */ + ... + +Therefore, to be safe from parallel read-modify-writes losing a write to +one of the bitfield members protected by a lock, all writes to all the +bitfields must use the lock. They almost universally do, except for +btrfs_clear_space_info_full() which iterates over the space_infos and +writes out found->full = 0 without a lock. + +Imagine that we have one thread completing a transaction in which we +finished deleting a block_group and are thus calling +btrfs_clear_space_info_full() while simultaneously the data reclaim +ticket infrastructure is running do_async_reclaim_data_space(): + + T1 T2 +btrfs_commit_transaction + btrfs_clear_space_info_full + data_sinfo->full = 0 + READ: full:0, chunk_alloc:0, flush:1 + do_async_reclaim_data_space(data_sinfo) + spin_lock(&space_info->lock); + if(list_empty(tickets)) + space_info->flush = 0; + READ: full: 0, chunk_alloc:0, flush:1 + MOD/WRITE: full: 0, chunk_alloc:0, flush:0 + spin_unlock(&space_info->lock); + return; + MOD/WRITE: full:0, chunk_alloc:0, flush:1 + +and now data_sinfo->flush is 1 but the reclaim worker has exited. This +breaks the invariant that flush is 0 iff there is no work queued or +running. Once this invariant is violated, future allocations that go +into __reserve_bytes() will add tickets to space_info->tickets but will +see space_info->flush is set to 1 and not queue the work. After this, +they will block forever on the resulting ticket, as it is now impossible +to kick the worker again. + +I also confirmed by looking at the assembly of the affected kernel that +it is doing RMW operations. For example, to set the flush (3rd) bit to 0, +the assembly is: + andb $0xfb,0x60(%rbx) +and similarly for setting the full (1st) bit to 0: + andb $0xfe,-0x20(%rax) + +So I think this is really a bug on practical systems. I have observed +a number of systems in this exact state, but am currently unable to +reproduce it. + +Rather than leaving this footgun lying around for the future, take +advantage of the fact that there is room in the struct anyway, and that +it is already quite large and simply change the three bitfield members to +bools. This avoids writes to space_info->full having any effect on +writes to space_info->flush, regardless of locking. + +Fixes: 957780eb2788 ("Btrfs: introduce ticketed enospc infrastructure") +Reviewed-by: Qu Wenruo +Signed-off-by: Boris Burkov +Reviewed-by: David Sterba +Signed-off-by: David Sterba +[ The context change is due to the commit cc0517fe779f +("btrfs: tweak extent/chunk allocation for space_info sub-space") +and the commit 45a59513b4b2 +("btrfs: add support for reclaiming from sub-space space_info") +in v6.16 which are irrelevant to the logic of this patch. ] +Signed-off-by: Rahul Sharma +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/block-group.c | 6 +++--- + fs/btrfs/space-info.c | 20 ++++++++++---------- + fs/btrfs/space-info.h | 6 +++--- + 3 files changed, 16 insertions(+), 16 deletions(-) + +--- a/fs/btrfs/block-group.c ++++ b/fs/btrfs/block-group.c +@@ -3699,7 +3699,7 @@ int btrfs_chunk_alloc(struct btrfs_trans + mutex_unlock(&fs_info->chunk_mutex); + } else { + /* Proceed with allocation */ +- space_info->chunk_alloc = 1; ++ space_info->chunk_alloc = true; + wait_for_alloc = false; + spin_unlock(&space_info->lock); + } +@@ -3735,7 +3735,7 @@ int btrfs_chunk_alloc(struct btrfs_trans + spin_lock(&space_info->lock); + if (ret < 0) { + if (ret == -ENOSPC) +- space_info->full = 1; ++ space_info->full = true; + else + goto out; + } else { +@@ -3745,7 +3745,7 @@ int btrfs_chunk_alloc(struct btrfs_trans + + space_info->force_alloc = CHUNK_ALLOC_NO_FORCE; + out: +- space_info->chunk_alloc = 0; ++ space_info->chunk_alloc = false; + spin_unlock(&space_info->lock); + mutex_unlock(&fs_info->chunk_mutex); + +--- a/fs/btrfs/space-info.c ++++ b/fs/btrfs/space-info.c +@@ -178,7 +178,7 @@ void btrfs_clear_space_info_full(struct + struct btrfs_space_info *found; + + list_for_each_entry(found, head, list) +- found->full = 0; ++ found->full = false; + } + + static int create_space_info(struct btrfs_fs_info *info, u64 flags) +@@ -271,7 +271,7 @@ void btrfs_update_space_info(struct btrf + found->bytes_readonly += bytes_readonly; + found->bytes_zone_unusable += bytes_zone_unusable; + if (total_bytes > 0) +- found->full = 0; ++ found->full = false; + btrfs_try_granting_tickets(info, found); + spin_unlock(&found->lock); + *space_info = found; +@@ -941,7 +941,7 @@ static void btrfs_async_reclaim_metadata + spin_lock(&space_info->lock); + to_reclaim = btrfs_calc_reclaim_metadata_size(fs_info, space_info); + if (!to_reclaim) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -953,7 +953,7 @@ static void btrfs_async_reclaim_metadata + flush_space(fs_info, space_info, to_reclaim, flush_state, false); + spin_lock(&space_info->lock); + if (list_empty(&space_info->tickets)) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -996,7 +996,7 @@ static void btrfs_async_reclaim_metadata + flush_state = FLUSH_DELAYED_ITEMS_NR; + commit_cycles--; + } else { +- space_info->flush = 0; ++ space_info->flush = false; + } + } else { + flush_state = FLUSH_DELAYED_ITEMS_NR; +@@ -1158,7 +1158,7 @@ static void btrfs_async_reclaim_data_spa + + spin_lock(&space_info->lock); + if (list_empty(&space_info->tickets)) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -1169,7 +1169,7 @@ static void btrfs_async_reclaim_data_spa + flush_space(fs_info, space_info, U64_MAX, ALLOC_CHUNK_FORCE, false); + spin_lock(&space_info->lock); + if (list_empty(&space_info->tickets)) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -1182,7 +1182,7 @@ static void btrfs_async_reclaim_data_spa + data_flush_states[flush_state], false); + spin_lock(&space_info->lock); + if (list_empty(&space_info->tickets)) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -1199,7 +1199,7 @@ static void btrfs_async_reclaim_data_spa + if (maybe_fail_all_tickets(fs_info, space_info)) + flush_state = 0; + else +- space_info->flush = 0; ++ space_info->flush = false; + } else { + flush_state = 0; + } +@@ -1510,7 +1510,7 @@ static int __reserve_bytes(struct btrfs_ + */ + maybe_clamp_preempt(fs_info, space_info); + +- space_info->flush = 1; ++ space_info->flush = true; + trace_btrfs_trigger_flush(fs_info, + space_info->flags, + orig_bytes, flush, +--- a/fs/btrfs/space-info.h ++++ b/fs/btrfs/space-info.h +@@ -28,11 +28,11 @@ struct btrfs_space_info { + flushing. The value is >> clamp, so turns + out to be a 2^clamp divisor. */ + +- unsigned int full:1; /* indicates that we cannot allocate any more ++ bool full; /* indicates that we cannot allocate any more + chunks for this space */ +- unsigned int chunk_alloc:1; /* set if we are allocating a chunk */ ++ bool chunk_alloc; /* set if we are allocating a chunk */ + +- unsigned int flush:1; /* set if we are trying to make space */ ++ bool flush; /* set if we are trying to make space */ + + unsigned int force_alloc; /* set if we need to force a chunk + alloc for this space */ diff --git a/queue-5.15/bus-fsl-mc-fix-use-after-free-in-driver_override_show.patch b/queue-5.15/bus-fsl-mc-fix-use-after-free-in-driver_override_show.patch new file mode 100644 index 0000000000..ff716ad272 --- /dev/null +++ b/queue-5.15/bus-fsl-mc-fix-use-after-free-in-driver_override_show.patch @@ -0,0 +1,50 @@ +From stable+bounces-216316-greg=kroah.com@vger.kernel.org Sat Feb 14 01:54:34 2026 +From: Sasha Levin +Date: Fri, 13 Feb 2026 19:54:27 -0500 +Subject: bus: fsl-mc: fix use-after-free in driver_override_show() +To: stable@vger.kernel.org +Cc: Gui-Dong Han , Ioana Ciornei , "Christophe Leroy (CS GROUP)" , Sasha Levin +Message-ID: <20260214005427.3653008-2-sashal@kernel.org> + +From: Gui-Dong Han + +[ Upstream commit 148891e95014b5dc5878acefa57f1940c281c431 ] + +The driver_override_show() function reads the driver_override string +without holding the device_lock. However, driver_override_store() uses +driver_set_override(), which modifies and frees the string while holding +the device_lock. + +This can result in a concurrent use-after-free if the string is freed +by the store function while being read by the show function. + +Fix this by holding the device_lock around the read operation. + +Fixes: 1f86a00c1159 ("bus/fsl-mc: add support for 'driver_override' in the mc-bus") +Cc: stable@vger.kernel.org +Signed-off-by: Gui-Dong Han +Reviewed-by: Ioana Ciornei +Link: https://lore.kernel.org/r/20251202174438.12658-1-hanguidong02@gmail.com +Signed-off-by: Christophe Leroy (CS GROUP) +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bus/fsl-mc/fsl-mc-bus.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/bus/fsl-mc/fsl-mc-bus.c ++++ b/drivers/bus/fsl-mc/fsl-mc-bus.c +@@ -199,8 +199,12 @@ static ssize_t driver_override_show(stru + struct device_attribute *attr, char *buf) + { + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); ++ ssize_t len; + +- return sysfs_emit(buf, "%s\n", mc_dev->driver_override); ++ device_lock(dev); ++ len = sysfs_emit(buf, "%s\n", mc_dev->driver_override); ++ device_unlock(dev); ++ return len; + } + static DEVICE_ATTR_RW(driver_override); + diff --git a/queue-5.15/bus-fsl-mc-replace-snprintf-and-sprintf-with-sysfs_emit-in-sysfs-show-functions.patch b/queue-5.15/bus-fsl-mc-replace-snprintf-and-sprintf-with-sysfs_emit-in-sysfs-show-functions.patch new file mode 100644 index 0000000000..cbb7cb21fe --- /dev/null +++ b/queue-5.15/bus-fsl-mc-replace-snprintf-and-sprintf-with-sysfs_emit-in-sysfs-show-functions.patch @@ -0,0 +1,48 @@ +From stable+bounces-216315-greg=kroah.com@vger.kernel.org Sat Feb 14 01:54:32 2026 +From: Sasha Levin +Date: Fri, 13 Feb 2026 19:54:26 -0500 +Subject: bus: fsl-mc: Replace snprintf and sprintf with sysfs_emit in sysfs show functions +To: stable@vger.kernel.org +Cc: Chelsy Ratnawat , Ioana Ciornei , Christophe Leroy , Sasha Levin +Message-ID: <20260214005427.3653008-1-sashal@kernel.org> + +From: Chelsy Ratnawat + +[ Upstream commit a50522c805a6c575c80f41b04706e084d814e116 ] + +Use sysfs_emit() instead of snprintf()/sprintf() when writing +to sysfs buffers, as recommended by the kernel documentation. + +Signed-off-by: Chelsy Ratnawat +Acked-by: Ioana Ciornei +Link: https://lore.kernel.org/r/20250822124339.1739290-1-chelsyratnawat2001@gmail.com +Signed-off-by: Christophe Leroy +Stable-dep-of: 148891e95014 ("bus: fsl-mc: fix use-after-free in driver_override_show()") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bus/fsl-mc/fsl-mc-bus.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/bus/fsl-mc/fsl-mc-bus.c ++++ b/drivers/bus/fsl-mc/fsl-mc-bus.c +@@ -156,8 +156,8 @@ static ssize_t modalias_show(struct devi + { + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); + +- return sprintf(buf, "fsl-mc:v%08Xd%s\n", mc_dev->obj_desc.vendor, +- mc_dev->obj_desc.type); ++ return sysfs_emit(buf, "fsl-mc:v%08Xd%s\n", mc_dev->obj_desc.vendor, ++ mc_dev->obj_desc.type); + } + static DEVICE_ATTR_RO(modalias); + +@@ -200,7 +200,7 @@ static ssize_t driver_override_show(stru + { + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); + +- return snprintf(buf, PAGE_SIZE, "%s\n", mc_dev->driver_override); ++ return sysfs_emit(buf, "%s\n", mc_dev->driver_override); + } + static DEVICE_ATTR_RW(driver_override); + diff --git a/queue-5.15/crypto-virtio-remove-duplicated-virtqueue_kick-in-virtio_crypto_skcipher_crypt_req.patch b/queue-5.15/crypto-virtio-remove-duplicated-virtqueue_kick-in-virtio_crypto_skcipher_crypt_req.patch new file mode 100644 index 0000000000..1f11b6286d --- /dev/null +++ b/queue-5.15/crypto-virtio-remove-duplicated-virtqueue_kick-in-virtio_crypto_skcipher_crypt_req.patch @@ -0,0 +1,40 @@ +From stable+bounces-216235-greg=kroah.com@vger.kernel.org Fri Feb 13 15:13:37 2026 +From: Sasha Levin +Date: Fri, 13 Feb 2026 09:10:48 -0500 +Subject: crypto: virtio - Remove duplicated virtqueue_kick in virtio_crypto_skcipher_crypt_req +To: stable@vger.kernel.org +Cc: Bibo Mao , Jason Wang , "Michael S. Tsirkin" , Herbert Xu , Sasha Levin +Message-ID: <20260213141048.3504475-1-sashal@kernel.org> + +From: Bibo Mao + +[ Upstream commit 14f86a1155cca1176abf55987b2fce7f7fcb2455 ] + +With function virtio_crypto_skcipher_crypt_req(), there is already +virtqueue_kick() call with spinlock held in function +__virtio_crypto_skcipher_do_req(). Remove duplicated virtqueue_kick() +function call here. + +Fixes: d79b5d0bbf2e ("crypto: virtio - support crypto engine framework") +Cc: stable@vger.kernel.org +Signed-off-by: Bibo Mao +Acked-by: Jason Wang +Acked-by: Michael S. Tsirkin +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/crypto/virtio/virtio_crypto_algs.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/crypto/virtio/virtio_crypto_algs.c ++++ b/drivers/crypto/virtio/virtio_crypto_algs.c +@@ -569,8 +569,6 @@ int virtio_crypto_skcipher_crypt_req( + if (ret < 0) + return ret; + +- virtqueue_kick(data_vq->vq); +- + return 0; + } + diff --git a/queue-5.15/mptcp-fix-race-in-mptcp_pm_nl_flush_addrs_doit.patch b/queue-5.15/mptcp-fix-race-in-mptcp_pm_nl_flush_addrs_doit.patch new file mode 100644 index 0000000000..82086be020 --- /dev/null +++ b/queue-5.15/mptcp-fix-race-in-mptcp_pm_nl_flush_addrs_doit.patch @@ -0,0 +1,82 @@ +From stable+bounces-215984-greg=kroah.com@vger.kernel.org Thu Feb 12 18:42:13 2026 +From: "Matthieu Baerts (NGI0)" +Date: Thu, 12 Feb 2026 18:41:47 +0100 +Subject: mptcp: fix race in mptcp_pm_nl_flush_addrs_doit() +To: stable@vger.kernel.org, gregkh@linuxfoundation.org +Cc: MPTCP Upstream , Eric Dumazet , syzbot+5498a510ff9de39d37da@syzkaller.appspotmail.com, Eulgyu Kim , Mat Martineau , "Matthieu Baerts (NGI0)" , Jakub Kicinski +Message-ID: <20260212174146.1841030-2-matttbe@kernel.org> + +From: Eric Dumazet + +commit e2a9eeb69f7d4ca4cf4c70463af77664fdb6ab1d upstream. + +syzbot and Eulgyu Kim reported crashes in mptcp_pm_nl_get_local_id() +and/or mptcp_pm_nl_is_backup() + +Root cause is list_splice_init() in mptcp_pm_nl_flush_addrs_doit() +which is not RCU ready. + +list_splice_init_rcu() can not be called here while holding pernet->lock +spinlock. + +Many thanks to Eulgyu Kim for providing a repro and testing our patches. + +Fixes: 141694df6573 ("mptcp: remove address when netlink flushes addrs") +Signed-off-by: Eric Dumazet +Reported-by: syzbot+5498a510ff9de39d37da@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/6970a46d.a00a0220.3ad28e.5cf0.GAE@google.com/T/ +Reported-by: Eulgyu Kim +Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/611 +Reviewed-by: Mat Martineau +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20260124-net-mptcp-race_nl_flush_addrs-v3-1-b2dc1b613e9d@kernel.org +Signed-off-by: Jakub Kicinski +[ Conflicts because the code has been moved from pm_netlink.c to + pm_kernel.c later on in commit 8617e85e04bd ("mptcp: pm: split + in-kernel PM specific code"). The same modifications can be applied + in pm_netlink.c with one exception, because 'pernet->local_addr_list' + has been renamed to 'pernet->endp_list' in commit 35e71e43a56d + ("mptcp: pm: in-kernel: rename 'local_addr_list' to 'endp_list'"). The + previous name is then still being used in this version. + Also, another conflict is caused by commit 7bcf4d8022f9 ("mptcp: pm: + rename helpers linked to 'flush'") which is not in this version: + mptcp_nl_remove_addrs_list() has been renamed to + mptcp_nl_flush_addrs_list(). The previous name has then been kept. ] +Signed-off-by: Matthieu Baerts (NGI0) +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/pm_netlink.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +--- a/net/mptcp/pm_netlink.c ++++ b/net/mptcp/pm_netlink.c +@@ -1656,16 +1656,26 @@ static void __reset_counters(struct pm_n + static int mptcp_nl_cmd_flush_addrs(struct sk_buff *skb, struct genl_info *info) + { + struct pm_nl_pernet *pernet = genl_info_pm_nl(info); +- LIST_HEAD(free_list); ++ struct list_head free_list; + + spin_lock_bh(&pernet->lock); +- list_splice_init(&pernet->local_addr_list, &free_list); ++ free_list = pernet->local_addr_list; ++ INIT_LIST_HEAD_RCU(&pernet->local_addr_list); + __reset_counters(pernet); + pernet->next_id = 1; + bitmap_zero(pernet->id_bitmap, MAX_ADDR_ID + 1); + spin_unlock_bh(&pernet->lock); +- mptcp_nl_remove_addrs_list(sock_net(skb->sk), &free_list); ++ ++ if (free_list.next == &pernet->local_addr_list) ++ return 0; ++ + synchronize_rcu(); ++ ++ /* Adjust the pointers to free_list instead of pernet->local_addr_list */ ++ free_list.prev->next = &free_list; ++ free_list.next->prev = &free_list; ++ ++ mptcp_nl_remove_addrs_list(sock_net(skb->sk), &free_list); + __flush_addrs(&free_list); + return 0; + } diff --git a/queue-5.15/net-dsa-free-routing-table-on-probe-failure.patch b/queue-5.15/net-dsa-free-routing-table-on-probe-failure.patch new file mode 100644 index 0000000000..3f4da2a08e --- /dev/null +++ b/queue-5.15/net-dsa-free-routing-table-on-probe-failure.patch @@ -0,0 +1,160 @@ +From lanbincn@139.com Thu Feb 12 11:52:47 2026 +From: Bin Lan +Date: Thu, 12 Feb 2026 10:52:36 +0000 +Subject: net: dsa: free routing table on probe failure +To: stable@vger.kernel.org, gregkh@linuxfoundation.org +Cc: Vladimir Oltean , Jakub Kicinski , Bin Lan +Message-ID: <20260212105236.4180-1-lanbincn@139.com> + +From: Vladimir Oltean + +[ Upstream commit 8bf108d7161ffc6880ad13a0cc109de3cf631727 ] + +If complete = true in dsa_tree_setup(), it means that we are the last +switch of the tree which is successfully probing, and we should be +setting up all switches from our probe path. + +After "complete" becomes true, dsa_tree_setup_cpu_ports() or any +subsequent function may fail. If that happens, the entire tree setup is +in limbo: the first N-1 switches have successfully finished probing +(doing nothing but having allocated persistent memory in the tree's +dst->ports, and maybe dst->rtable), and switch N failed to probe, ending +the tree setup process before anything is tangible from the user's PoV. + +If switch N fails to probe, its memory (ports) will be freed and removed +from dst->ports. However, the dst->rtable elements pointing to its ports, +as created by dsa_link_touch(), will remain there, and will lead to +use-after-free if dereferenced. + +If dsa_tree_setup_switches() returns -EPROBE_DEFER, which is entirely +possible because that is where ds->ops->setup() is, we get a kasan +report like this: + +================================================================== +BUG: KASAN: slab-use-after-free in mv88e6xxx_setup_upstream_port+0x240/0x568 +Read of size 8 at addr ffff000004f56020 by task kworker/u8:3/42 + +Call trace: + __asan_report_load8_noabort+0x20/0x30 + mv88e6xxx_setup_upstream_port+0x240/0x568 + mv88e6xxx_setup+0xebc/0x1eb0 + dsa_register_switch+0x1af4/0x2ae0 + mv88e6xxx_register_switch+0x1b8/0x2a8 + mv88e6xxx_probe+0xc4c/0xf60 + mdio_probe+0x78/0xb8 + really_probe+0x2b8/0x5a8 + __driver_probe_device+0x164/0x298 + driver_probe_device+0x78/0x258 + __device_attach_driver+0x274/0x350 + +Allocated by task 42: + __kasan_kmalloc+0x84/0xa0 + __kmalloc_cache_noprof+0x298/0x490 + dsa_switch_touch_ports+0x174/0x3d8 + dsa_register_switch+0x800/0x2ae0 + mv88e6xxx_register_switch+0x1b8/0x2a8 + mv88e6xxx_probe+0xc4c/0xf60 + mdio_probe+0x78/0xb8 + really_probe+0x2b8/0x5a8 + __driver_probe_device+0x164/0x298 + driver_probe_device+0x78/0x258 + __device_attach_driver+0x274/0x350 + +Freed by task 42: + __kasan_slab_free+0x48/0x68 + kfree+0x138/0x418 + dsa_register_switch+0x2694/0x2ae0 + mv88e6xxx_register_switch+0x1b8/0x2a8 + mv88e6xxx_probe+0xc4c/0xf60 + mdio_probe+0x78/0xb8 + really_probe+0x2b8/0x5a8 + __driver_probe_device+0x164/0x298 + driver_probe_device+0x78/0x258 + __device_attach_driver+0x274/0x350 + +The simplest way to fix the bug is to delete the routing table in its +entirety. dsa_tree_setup_routing_table() has no problem in regenerating +it even if we deleted links between ports other than those of switch N, +because dsa_link_touch() first checks whether the port pair already +exists in dst->rtable, allocating if not. + +The deletion of the routing table in its entirety already exists in +dsa_tree_teardown(), so refactor that into a function that can also be +called from the tree setup error path. + +In my analysis of the commit to blame, it is the one which added +dsa_link elements to dst->rtable. Prior to that, each switch had its own +ds->rtable which is freed when the switch fails to probe. But the tree +is potentially persistent memory. + +Fixes: c5f51765a1f6 ("net: dsa: list DSA links in the fabric") +Signed-off-by: Vladimir Oltean +Link: https://patch.msgid.link/20250414213001.2957964-1-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +[ Backport the fix to net/dsa/dsa2.c in v5.15.y for dsa2.c was +renamed back into dsa.c by commit +47d2ce03dcfb ("net: dsa: rename dsa2.c back into dsa.c and create its header") +since v6.2. ] +Signed-off-by: Bin Lan +Signed-off-by: Greg Kroah-Hartman +--- + net/dsa/dsa2.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +--- a/net/dsa/dsa2.c ++++ b/net/dsa/dsa2.c +@@ -1079,6 +1079,16 @@ static void dsa_tree_teardown_lags(struc + kfree(dst->lags); + } + ++static void dsa_tree_teardown_routing_table(struct dsa_switch_tree *dst) ++{ ++ struct dsa_link *dl, *next; ++ ++ list_for_each_entry_safe(dl, next, &dst->rtable, list) { ++ list_del(&dl->list); ++ kfree(dl); ++ } ++} ++ + static int dsa_tree_setup(struct dsa_switch_tree *dst) + { + bool complete; +@@ -1096,7 +1106,7 @@ static int dsa_tree_setup(struct dsa_swi + + err = dsa_tree_setup_cpu_ports(dst); + if (err) +- return err; ++ goto teardown_rtable; + + err = dsa_tree_setup_switches(dst); + if (err) +@@ -1123,14 +1133,14 @@ teardown_switches: + dsa_tree_teardown_switches(dst); + teardown_cpu_ports: + dsa_tree_teardown_cpu_ports(dst); ++teardown_rtable: ++ dsa_tree_teardown_routing_table(dst); + + return err; + } + + static void dsa_tree_teardown(struct dsa_switch_tree *dst) + { +- struct dsa_link *dl, *next; +- + if (!dst->setup) + return; + +@@ -1144,10 +1154,7 @@ static void dsa_tree_teardown(struct dsa + + dsa_tree_teardown_cpu_ports(dst); + +- list_for_each_entry_safe(dl, next, &dst->rtable, list) { +- list_del(&dl->list); +- kfree(dl); +- } ++ dsa_tree_teardown_routing_table(dst); + + pr_info("DSA: tree %d torn down\n", dst->index); + diff --git a/queue-5.15/pci-endpoint-automatically-create-a-function-specific-attributes-group.patch b/queue-5.15/pci-endpoint-automatically-create-a-function-specific-attributes-group.patch new file mode 100644 index 0000000000..9aded88920 --- /dev/null +++ b/queue-5.15/pci-endpoint-automatically-create-a-function-specific-attributes-group.patch @@ -0,0 +1,235 @@ +From stable+bounces-216477-greg=kroah.com@vger.kernel.org Sat Feb 14 14:03:01 2026 +From: Sasha Levin +Date: Sat, 14 Feb 2026 08:02:52 -0500 +Subject: PCI: endpoint: Automatically create a function specific attributes group +To: stable@vger.kernel.org +Cc: Damien Le Moal , Lorenzo Pieralisi , Bjorn Helgaas , Manivannan Sadhasivam , Sasha Levin +Message-ID: <20260214130254.345213-1-sashal@kernel.org> + +From: Damien Le Moal + +[ Upstream commit 70b3740f2c1941e2006d61539131b70d20cba9a6 ] + +A PCI endpoint function driver can define function specific attributes +under its function configfs directory using the add_cfs() endpoint driver +operation. This is done by tying up the mkdir operation for the function +configfs directory to a call to the add_cfs() operation. However, there +are no checks preventing the user from repeatedly creating function +specific attribute directories with different names, resulting in the same +endpoint specific attributes group being added multiple times, which also +result in an invalid reference counting for the attribute groups. E.g., +using the pci-epf-ntb function driver as an example, the user creates the +function as follows: + + $ modprobe pci-epf-ntb + $ cd /sys/kernel/config/pci_ep/functions/pci_epf_ntb + $ mkdir func0 + $ tree func0 + func0/ + |-- baseclass_code + |-- cache_line_size + |-- ... + `-- vendorid + + $ mkdir func0/attrs + $ tree func0 + func0/ + |-- attrs + | |-- db_count + | |-- mw1 + | |-- mw2 + | |-- mw3 + | |-- mw4 + | |-- num_mws + | `-- spad_count + |-- baseclass_code + |-- cache_line_size + |-- ... + `-- vendorid + +At this point, the function can be started by linking the EP controller. +However, if the user mistakenly creates again a directory: + + $ mkdir func0/attrs2 + $ tree func0 + func0/ + |-- attrs + | |-- db_count + | |-- mw1 + | |-- mw2 + | |-- mw3 + | |-- mw4 + | |-- num_mws + | `-- spad_count + |-- attrs2 + | |-- db_count + | |-- mw1 + | |-- mw2 + | |-- mw3 + | |-- mw4 + | |-- num_mws + | `-- spad_count + |-- baseclass_code + |-- cache_line_size + |-- ... + `-- vendorid + +The endpoint function specific attributes are duplicated and cause a crash +when the endpoint function device is torn down: + + refcount_t: addition on 0; use-after-free. + WARNING: CPU: 2 PID: 834 at lib/refcount.c:25 refcount_warn_saturate+0xc8/0x144 + CPU: 2 PID: 834 Comm: rmdir Not tainted 6.3.0-rc1 #1 + Hardware name: Pine64 RockPro64 v2.1 (DT) + pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) + ... + Call trace: + refcount_warn_saturate+0xc8/0x144 + config_item_get+0x7c/0x80 + configfs_rmdir+0x17c/0x30c + vfs_rmdir+0x8c/0x204 + do_rmdir+0x158/0x184 + __arm64_sys_unlinkat+0x64/0x80 + invoke_syscall+0x48/0x114 + ... + +Fix this by modifying pci_epf_cfs_work() to execute the new function +pci_ep_cfs_add_type_group() which itself calls pci_epf_type_add_cfs() to +obtain the function specific attribute group and the group name (directory +name) from the endpoint function driver. If the function driver defines an +attribute group, pci_ep_cfs_add_type_group() then proceeds to register this +group using configfs_register_group(), thus automatically exposing the +function type specific configfs attributes to the user. E.g.: + + $ modprobe pci-epf-ntb + $ cd /sys/kernel/config/pci_ep/functions/pci_epf_ntb + $ mkdir func0 + $ tree func0 + func0/ + |-- baseclass_code + |-- cache_line_size + |-- ... + |-- pci_epf_ntb.0 + | |-- db_count + | |-- mw1 + | |-- mw2 + | |-- mw3 + | |-- mw4 + | |-- num_mws + | `-- spad_count + |-- primary + |-- ... + `-- vendorid + +With this change, there is no need for the user to create or delete +directories in the endpoint function attributes directory. The +pci_epf_type_group_ops group operations are thus removed. + +Also update the documentation for the pci-epf-ntb and pci-epf-vntb function +drivers to reflect this change, removing the explanations showing the need +to manually create the sub-directory for the function specific attributes. + +Link: https://lore.kernel.org/r/20230415023542.77601-2-dlemoal@kernel.org +Signed-off-by: Damien Le Moal +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Bjorn Helgaas +Reviewed-by: Manivannan Sadhasivam +Stable-dep-of: 7c5c7d06bd1f ("PCI: endpoint: Avoid creating sub-groups asynchronously") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/PCI/endpoint/pci-ntb-howto.rst | 11 ++----- + drivers/pci/endpoint/pci-ep-cfs.c | 42 ++++++++++++--------------- + 2 files changed, 24 insertions(+), 29 deletions(-) + +--- a/Documentation/PCI/endpoint/pci-ntb-howto.rst ++++ b/Documentation/PCI/endpoint/pci-ntb-howto.rst +@@ -88,13 +88,10 @@ commands can be used:: + # echo 0x104c > functions/pci_epf_ntb/func1/vendorid + # echo 0xb00d > functions/pci_epf_ntb/func1/deviceid + +-In order to configure NTB specific attributes, a new sub-directory to func1 +-should be created:: +- +- # mkdir functions/pci_epf_ntb/func1/pci_epf_ntb.0/ +- +-The NTB function driver will populate this directory with various attributes +-that can be configured by the user:: ++The PCI endpoint framework also automatically creates a sub-directory in the ++function attribute directory. This sub-directory has the same name as the name ++of the function device and is populated with the following NTB specific ++attributes that can be configured by the user:: + + # ls functions/pci_epf_ntb/func1/pci_epf_ntb.0/ + db_count mw1 mw2 mw3 mw4 num_mws +--- a/drivers/pci/endpoint/pci-ep-cfs.c ++++ b/drivers/pci/endpoint/pci-ep-cfs.c +@@ -23,6 +23,7 @@ struct pci_epf_group { + struct config_group group; + struct config_group primary_epc_group; + struct config_group secondary_epc_group; ++ struct config_group *type_group; + struct delayed_work cfs_work; + struct pci_epf *epf; + int index; +@@ -514,34 +515,29 @@ static struct configfs_item_operations p + .release = pci_epf_release, + }; + +-static struct config_group *pci_epf_type_make(struct config_group *group, +- const char *name) +-{ +- struct pci_epf_group *epf_group = to_pci_epf_group(&group->cg_item); +- struct config_group *epf_type_group; +- +- epf_type_group = pci_epf_type_add_cfs(epf_group->epf, group); +- return epf_type_group; +-} +- +-static void pci_epf_type_drop(struct config_group *group, +- struct config_item *item) +-{ +- config_item_put(item); +-} +- +-static struct configfs_group_operations pci_epf_type_group_ops = { +- .make_group = &pci_epf_type_make, +- .drop_item = &pci_epf_type_drop, +-}; +- + static const struct config_item_type pci_epf_type = { +- .ct_group_ops = &pci_epf_type_group_ops, + .ct_item_ops = &pci_epf_ops, + .ct_attrs = pci_epf_attrs, + .ct_owner = THIS_MODULE, + }; + ++static void pci_ep_cfs_add_type_group(struct pci_epf_group *epf_group) ++{ ++ struct config_group *group; ++ ++ group = pci_epf_type_add_cfs(epf_group->epf, &epf_group->group); ++ if (!group) ++ return; ++ ++ if (IS_ERR(group)) { ++ dev_err(&epf_group->epf->dev, ++ "failed to create epf type specific attributes\n"); ++ return; ++ } ++ ++ configfs_register_group(&epf_group->group, group); ++} ++ + static void pci_epf_cfs_work(struct work_struct *work) + { + struct pci_epf_group *epf_group; +@@ -559,6 +555,8 @@ static void pci_epf_cfs_work(struct work + pr_err("failed to create 'secondary' EPC interface\n"); + return; + } ++ ++ pci_ep_cfs_add_type_group(epf_group); + } + + static struct config_group *pci_epf_make(struct config_group *group, diff --git a/queue-5.15/pci-endpoint-avoid-creating-sub-groups-asynchronously.patch b/queue-5.15/pci-endpoint-avoid-creating-sub-groups-asynchronously.patch new file mode 100644 index 0000000000..c930bf57d1 --- /dev/null +++ b/queue-5.15/pci-endpoint-avoid-creating-sub-groups-asynchronously.patch @@ -0,0 +1,103 @@ +From stable+bounces-216479-greg=kroah.com@vger.kernel.org Sat Feb 14 14:03:04 2026 +From: Sasha Levin +Date: Sat, 14 Feb 2026 08:02:54 -0500 +Subject: PCI: endpoint: Avoid creating sub-groups asynchronously +To: stable@vger.kernel.org +Cc: Liu Song , Manivannan Sadhasivam , Bjorn Helgaas , stable@kernel.org, Sasha Levin +Message-ID: <20260214130254.345213-3-sashal@kernel.org> + +From: Liu Song + +[ Upstream commit 7c5c7d06bd1f86d2c3ebe62be903a4ba42db4d2c ] + +The asynchronous creation of sub-groups by a delayed work could lead to a +NULL pointer dereference when the driver directory is removed before the +work completes. + +The crash can be easily reproduced with the following commands: + + # cd /sys/kernel/config/pci_ep/functions/pci_epf_test + # for i in {1..20}; do mkdir test && rmdir test; done + + BUG: kernel NULL pointer dereference, address: 0000000000000088 + ... + Call Trace: + configfs_register_group+0x3d/0x190 + pci_epf_cfs_work+0x41/0x110 + process_one_work+0x18f/0x350 + worker_thread+0x25a/0x3a0 + +Fix this issue by using configfs_add_default_group() API which does not +have the deadlock problem as configfs_register_group() and does not require +the delayed work handler. + +Fixes: e85a2d783762 ("PCI: endpoint: Add support in configfs to associate two EPCs with EPF") +Signed-off-by: Liu Song +[mani: slightly reworded the description and added stable list] +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Cc: stable@kernel.org +Link: https://patch.msgid.link/20250710143845409gLM6JdlwPhlHG9iX3F6jK@zte.com.cn +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/endpoint/pci-ep-cfs.c | 15 +++++---------- + 1 file changed, 5 insertions(+), 10 deletions(-) + +--- a/drivers/pci/endpoint/pci-ep-cfs.c ++++ b/drivers/pci/endpoint/pci-ep-cfs.c +@@ -23,7 +23,6 @@ struct pci_epf_group { + struct config_group group; + struct config_group primary_epc_group; + struct config_group secondary_epc_group; +- struct delayed_work cfs_work; + struct pci_epf *epf; + int index; + }; +@@ -100,7 +99,7 @@ static struct config_group + secondary_epc_group = &epf_group->secondary_epc_group; + config_group_init_type_name(secondary_epc_group, "secondary", + &pci_secondary_epc_type); +- configfs_register_group(&epf_group->group, secondary_epc_group); ++ configfs_add_default_group(secondary_epc_group, &epf_group->group); + + return secondary_epc_group; + } +@@ -160,7 +159,7 @@ static struct config_group + + config_group_init_type_name(primary_epc_group, "primary", + &pci_primary_epc_type); +- configfs_register_group(&epf_group->group, primary_epc_group); ++ configfs_add_default_group(primary_epc_group, &epf_group->group); + + return primary_epc_group; + } +@@ -534,15 +533,13 @@ static void pci_ep_cfs_add_type_group(st + return; + } + +- configfs_register_group(&epf_group->group, group); ++ configfs_add_default_group(group, &epf_group->group); + } + +-static void pci_epf_cfs_work(struct work_struct *work) ++static void pci_epf_cfs_add_sub_groups(struct pci_epf_group *epf_group) + { +- struct pci_epf_group *epf_group; + struct config_group *group; + +- epf_group = container_of(work, struct pci_epf_group, cfs_work.work); + group = pci_ep_cfs_add_primary_group(epf_group); + if (IS_ERR(group)) { + pr_err("failed to create 'primary' EPC interface\n"); +@@ -601,9 +598,7 @@ static struct config_group *pci_epf_make + + kfree(epf_name); + +- INIT_DELAYED_WORK(&epf_group->cfs_work, pci_epf_cfs_work); +- queue_delayed_work(system_wq, &epf_group->cfs_work, +- msecs_to_jiffies(1)); ++ pci_epf_cfs_add_sub_groups(epf_group); + + return &epf_group->group; + diff --git a/queue-5.15/pci-endpoint-remove-unused-field-in-struct-pci_epf_group.patch b/queue-5.15/pci-endpoint-remove-unused-field-in-struct-pci_epf_group.patch new file mode 100644 index 0000000000..6370befdc9 --- /dev/null +++ b/queue-5.15/pci-endpoint-remove-unused-field-in-struct-pci_epf_group.patch @@ -0,0 +1,43 @@ +From stable+bounces-216478-greg=kroah.com@vger.kernel.org Sat Feb 14 14:03:03 2026 +From: Sasha Levin +Date: Sat, 14 Feb 2026 08:02:53 -0500 +Subject: PCI: endpoint: Remove unused field in struct pci_epf_group +To: stable@vger.kernel.org +Cc: "Christophe JAILLET" , "Krzysztof Wilczyński" , "Bjorn Helgaas" , "Sasha Levin" +Message-ID: <20260214130254.345213-2-sashal@kernel.org> + +From: Christophe JAILLET + +[ Upstream commit 328e4dffbeecc0f2cc5a149dee6c11a0577c9671 ] + +In "struct pci_epf_group", the 'type_group' field is unused. + +This was added, but already unused, by commit 70b3740f2c19 ("PCI: endpoint: +Automatically create a function specific attributes group"). + +Thus, remove it. + +Found with cppcheck, unusedStructMember. + +[kwilczynski: commit log] +Link: https://lore.kernel.org/linux-pci/6507d44b6c60a19af35a605e2d58050be8872ab6.1712341008.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Christophe JAILLET +Signed-off-by: Krzysztof Wilczyński +Signed-off-by: Bjorn Helgaas +Stable-dep-of: 7c5c7d06bd1f ("PCI: endpoint: Avoid creating sub-groups asynchronously") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/endpoint/pci-ep-cfs.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/pci/endpoint/pci-ep-cfs.c ++++ b/drivers/pci/endpoint/pci-ep-cfs.c +@@ -23,7 +23,6 @@ struct pci_epf_group { + struct config_group group; + struct config_group primary_epc_group; + struct config_group secondary_epc_group; +- struct config_group *type_group; + struct delayed_work cfs_work; + struct pci_epf *epf; + int index; diff --git a/queue-5.15/scsi-qla2xxx-fix-bsg_done-causing-double-free.patch b/queue-5.15/scsi-qla2xxx-fix-bsg_done-causing-double-free.patch new file mode 100644 index 0000000000..4ec1d1cf4a --- /dev/null +++ b/queue-5.15/scsi-qla2xxx-fix-bsg_done-causing-double-free.patch @@ -0,0 +1,125 @@ +From stable+bounces-216476-greg=kroah.com@vger.kernel.org Sat Feb 14 14:02:42 2026 +From: Sasha Levin +Date: Sat, 14 Feb 2026 08:02:35 -0500 +Subject: scsi: qla2xxx: Fix bsg_done() causing double free +To: stable@vger.kernel.org +Cc: Anil Gurumurthy , Nilesh Javali , Himanshu Madhani , "Martin K. Petersen" , Sasha Levin +Message-ID: <20260214130235.343904-1-sashal@kernel.org> + +From: Anil Gurumurthy + +[ Upstream commit c2c68225b1456f4d0d393b5a8778d51bb0d5b1d0 ] + +Kernel panic observed on system, + +[5353358.825191] BUG: unable to handle page fault for address: ff5f5e897b024000 +[5353358.825194] #PF: supervisor write access in kernel mode +[5353358.825195] #PF: error_code(0x0002) - not-present page +[5353358.825196] PGD 100006067 P4D 0 +[5353358.825198] Oops: 0002 [#1] PREEMPT SMP NOPTI +[5353358.825200] CPU: 5 PID: 2132085 Comm: qlafwupdate.sub Kdump: loaded Tainted: G W L ------- --- 5.14.0-503.34.1.el9_5.x86_64 #1 +[5353358.825203] Hardware name: HPE ProLiant DL360 Gen11/ProLiant DL360 Gen11, BIOS 2.44 01/17/2025 +[5353358.825204] RIP: 0010:memcpy_erms+0x6/0x10 +[5353358.825211] RSP: 0018:ff591da8f4f6b710 EFLAGS: 00010246 +[5353358.825212] RAX: ff5f5e897b024000 RBX: 0000000000007090 RCX: 0000000000001000 +[5353358.825213] RDX: 0000000000001000 RSI: ff591da8f4fed090 RDI: ff5f5e897b024000 +[5353358.825214] RBP: 0000000000010000 R08: ff5f5e897b024000 R09: 0000000000000000 +[5353358.825215] R10: ff46cf8c40517000 R11: 0000000000000001 R12: 0000000000008090 +[5353358.825216] R13: ff591da8f4f6b720 R14: 0000000000001000 R15: 0000000000000000 +[5353358.825218] FS: 00007f1e88d47740(0000) GS:ff46cf935f940000(0000) knlGS:0000000000000000 +[5353358.825219] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[5353358.825220] CR2: ff5f5e897b024000 CR3: 0000000231532004 CR4: 0000000000771ef0 +[5353358.825221] PKRU: 55555554 +[5353358.825222] Call Trace: +[5353358.825223] +[5353358.825224] ? show_trace_log_lvl+0x1c4/0x2df +[5353358.825229] ? show_trace_log_lvl+0x1c4/0x2df +[5353358.825232] ? sg_copy_buffer+0xc8/0x110 +[5353358.825236] ? __die_body.cold+0x8/0xd +[5353358.825238] ? page_fault_oops+0x134/0x170 +[5353358.825242] ? kernelmode_fixup_or_oops+0x84/0x110 +[5353358.825244] ? exc_page_fault+0xa8/0x150 +[5353358.825247] ? asm_exc_page_fault+0x22/0x30 +[5353358.825252] ? memcpy_erms+0x6/0x10 +[5353358.825253] sg_copy_buffer+0xc8/0x110 +[5353358.825259] qla2x00_process_vendor_specific+0x652/0x1320 [qla2xxx] +[5353358.825317] qla24xx_bsg_request+0x1b2/0x2d0 [qla2xxx] + +Most routines in qla_bsg.c call bsg_done() only for success cases. +However a few invoke it for failure case as well leading to a double +free. Validate before calling bsg_done(). + +Cc: stable@vger.kernel.org +Signed-off-by: Anil Gurumurthy +Signed-off-by: Nilesh Javali +Reviewed-by: Himanshu Madhani +Link: https://patch.msgid.link/20251210101604.431868-12-njavali@marvell.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_bsg.c | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_bsg.c ++++ b/drivers/scsi/qla2xxx/qla_bsg.c +@@ -1546,8 +1546,9 @@ qla2x00_update_optrom(struct bsg_job *bs + ha->optrom_buffer = NULL; + ha->optrom_state = QLA_SWAITING; + mutex_unlock(&ha->optrom_mutex); +- bsg_job_done(bsg_job, bsg_reply->result, +- bsg_reply->reply_payload_rcv_len); ++ if (!rval) ++ bsg_job_done(bsg_job, bsg_reply->result, ++ bsg_reply->reply_payload_rcv_len); + return rval; + } + +@@ -2525,8 +2526,9 @@ qla2x00_manage_host_stats(struct bsg_job + sizeof(struct ql_vnd_mng_host_stats_resp)); + + bsg_reply->result = DID_OK; +- bsg_job_done(bsg_job, bsg_reply->result, +- bsg_reply->reply_payload_rcv_len); ++ if (!ret) ++ bsg_job_done(bsg_job, bsg_reply->result, ++ bsg_reply->reply_payload_rcv_len); + + return ret; + } +@@ -2615,8 +2617,9 @@ qla2x00_get_host_stats(struct bsg_job *b + bsg_job->reply_payload.sg_cnt, + data, response_len); + bsg_reply->result = DID_OK; +- bsg_job_done(bsg_job, bsg_reply->result, +- bsg_reply->reply_payload_rcv_len); ++ if (!ret) ++ bsg_job_done(bsg_job, bsg_reply->result, ++ bsg_reply->reply_payload_rcv_len); + + kfree(data); + host_stat_out: +@@ -2715,8 +2718,9 @@ reply: + bsg_job->reply_payload.sg_cnt, data, + response_len); + bsg_reply->result = DID_OK; +- bsg_job_done(bsg_job, bsg_reply->result, +- bsg_reply->reply_payload_rcv_len); ++ if (!ret) ++ bsg_job_done(bsg_job, bsg_reply->result, ++ bsg_reply->reply_payload_rcv_len); + + tgt_stat_out: + kfree(data); +@@ -2777,8 +2781,9 @@ qla2x00_manage_host_port(struct bsg_job + bsg_job->reply_payload.sg_cnt, &rsp_data, + sizeof(struct ql_vnd_mng_host_port_resp)); + bsg_reply->result = DID_OK; +- bsg_job_done(bsg_job, bsg_reply->result, +- bsg_reply->reply_payload_rcv_len); ++ if (!ret) ++ bsg_job_done(bsg_job, bsg_reply->result, ++ bsg_reply->reply_payload_rcv_len); + + return ret; + } diff --git a/queue-5.15/scsi-qla2xxx-free-sp-in-error-path-to-fix-system-crash.patch b/queue-5.15/scsi-qla2xxx-free-sp-in-error-path-to-fix-system-crash.patch new file mode 100644 index 0000000000..b5690a1626 --- /dev/null +++ b/queue-5.15/scsi-qla2xxx-free-sp-in-error-path-to-fix-system-crash.patch @@ -0,0 +1,87 @@ +From stable+bounces-216273-greg=kroah.com@vger.kernel.org Fri Feb 13 17:47:07 2026 +From: Sasha Levin +Date: Fri, 13 Feb 2026 11:45:03 -0500 +Subject: scsi: qla2xxx: Free sp in error path to fix system crash +To: stable@vger.kernel.org +Cc: Anil Gurumurthy , Nilesh Javali , Himanshu Madhani , "Martin K. Petersen" , Sasha Levin +Message-ID: <20260213164503.3564614-4-sashal@kernel.org> + +From: Anil Gurumurthy + +[ Upstream commit 7adbd2b7809066c75f0433e5e2a8e114b429f30f ] + +System crash seen during load/unload test in a loop, + +[61110.449331] qla2xxx [0000:27:00.0]-0042:0: Disabled MSI-X. +[61110.467494] ============================================================================= +[61110.467498] BUG qla2xxx_srbs (Tainted: G OE -------- --- ): Objects remaining in qla2xxx_srbs on __kmem_cache_shutdown() +[61110.467501] ----------------------------------------------------------------------------- + +[61110.467502] Slab 0x000000000ffc8162 objects=51 used=1 fp=0x00000000e25d3d85 flags=0x57ffffc0010200(slab|head|node=1|zone=2|lastcpupid=0x1fffff) +[61110.467509] CPU: 53 PID: 455206 Comm: rmmod Kdump: loaded Tainted: G OE -------- --- 5.14.0-284.11.1.el9_2.x86_64 #1 +[61110.467513] Hardware name: HPE ProLiant DL385 Gen10 Plus v2/ProLiant DL385 Gen10 Plus v2, BIOS A42 08/17/2023 +[61110.467515] Call Trace: +[61110.467516] +[61110.467519] dump_stack_lvl+0x34/0x48 +[61110.467526] slab_err.cold+0x53/0x67 +[61110.467534] __kmem_cache_shutdown+0x16e/0x320 +[61110.467540] kmem_cache_destroy+0x51/0x160 +[61110.467544] qla2x00_module_exit+0x93/0x99 [qla2xxx] +[61110.467607] ? __do_sys_delete_module.constprop.0+0x178/0x280 +[61110.467613] ? syscall_trace_enter.constprop.0+0x145/0x1d0 +[61110.467616] ? do_syscall_64+0x5c/0x90 +[61110.467619] ? exc_page_fault+0x62/0x150 +[61110.467622] ? entry_SYSCALL_64_after_hwframe+0x63/0xcd +[61110.467626] +[61110.467627] Disabling lock debugging due to kernel taint +[61110.467635] Object 0x0000000026f7e6e6 @offset=16000 +[61110.467639] ------------[ cut here ]------------ +[61110.467639] kmem_cache_destroy qla2xxx_srbs: Slab cache still has objects when called from qla2x00_module_exit+0x93/0x99 [qla2xxx] +[61110.467659] WARNING: CPU: 53 PID: 455206 at mm/slab_common.c:520 kmem_cache_destroy+0x14d/0x160 +[61110.467718] CPU: 53 PID: 455206 Comm: rmmod Kdump: loaded Tainted: G B OE -------- --- 5.14.0-284.11.1.el9_2.x86_64 #1 +[61110.467720] Hardware name: HPE ProLiant DL385 Gen10 Plus v2/ProLiant DL385 Gen10 Plus v2, BIOS A42 08/17/2023 +[61110.467721] RIP: 0010:kmem_cache_destroy+0x14d/0x160 +[61110.467724] Code: 99 7d 07 00 48 89 ef e8 e1 6a 07 00 eb b3 48 8b 55 60 48 8b 4c 24 20 48 c7 c6 70 fc 66 90 48 c7 c7 f8 ef a1 90 e8 e1 ed 7c 00 <0f> 0b eb 93 c3 cc cc cc cc 66 2e 0f 1f 84 00 00 00 00 00 55 48 89 +[61110.467725] RSP: 0018:ffffa304e489fe80 EFLAGS: 00010282 +[61110.467727] RAX: 0000000000000000 RBX: ffffffffc0d9a860 RCX: 0000000000000027 +[61110.467729] RDX: ffff8fd5ff9598a8 RSI: 0000000000000001 RDI: ffff8fd5ff9598a0 +[61110.467730] RBP: ffff8fb6aaf78700 R08: 0000000000000000 R09: 0000000100d863b7 +[61110.467731] R10: ffffa304e489fd20 R11: ffffffff913bef48 R12: 0000000040002000 +[61110.467731] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 +[61110.467733] FS: 00007f64c89fb740(0000) GS:ffff8fd5ff940000(0000) knlGS:0000000000000000 +[61110.467734] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[61110.467735] CR2: 00007f0f02bfe000 CR3: 00000020ad6dc005 CR4: 0000000000770ee0 +[61110.467736] PKRU: 55555554 +[61110.467737] Call Trace: +[61110.467738] +[61110.467739] qla2x00_module_exit+0x93/0x99 [qla2xxx] +[61110.467755] ? __do_sys_delete_module.constprop.0+0x178/0x280 + +Free sp in the error path to fix the crash. + +Fixes: f352eeb75419 ("scsi: qla2xxx: Add ability to use GPNFT/GNNFT for RSCN handling") +Cc: stable@vger.kernel.org +Signed-off-by: Anil Gurumurthy +Signed-off-by: Nilesh Javali +Reviewed-by: Himanshu Madhani +Link: https://patch.msgid.link/20251210101604.431868-9-njavali@marvell.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_gs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_gs.c ++++ b/drivers/scsi/qla2xxx/qla_gs.c +@@ -3921,8 +3921,8 @@ int qla_fab_async_scan(scsi_qla_host_t * + if (vha->scan.scan_flags & SF_SCANNING) { + spin_unlock_irqrestore(&vha->work_lock, flags); + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2012, +- "%s: scan active\n", __func__); +- return rval; ++ "%s: scan active for sp:%p\n", __func__, sp); ++ goto done_free_sp; + } + vha->scan.scan_flags |= SF_SCANNING; + if (!sp) diff --git a/queue-5.15/scsi-qla2xxx-reduce-fabric-scan-duplicate-code.patch b/queue-5.15/scsi-qla2xxx-reduce-fabric-scan-duplicate-code.patch new file mode 100644 index 0000000000..a28100a127 --- /dev/null +++ b/queue-5.15/scsi-qla2xxx-reduce-fabric-scan-duplicate-code.patch @@ -0,0 +1,716 @@ +From stable+bounces-216271-greg=kroah.com@vger.kernel.org Fri Feb 13 17:45:10 2026 +From: Sasha Levin +Date: Fri, 13 Feb 2026 11:45:02 -0500 +Subject: scsi: qla2xxx: Reduce fabric scan duplicate code +To: stable@vger.kernel.org +Cc: Quinn Tran , Nilesh Javali , Himanshu Madhani , "Martin K. Petersen" , Sasha Levin +Message-ID: <20260213164503.3564614-3-sashal@kernel.org> + +From: Quinn Tran + +[ Upstream commit beafd692461443e0fb1d61aa56886bf85ef6f5e4 ] + +For fabric scan, current code uses switch scan opcode and flags as the +method to iterate through different commands to carry out the process. +This makes it hard to read. This patch convert those opcode and flags into +steps. In addition, this help reduce some duplicate code. + +Consolidate routines that handle GPNFT & GNNFT. + +Cc: stable@vger.kernel.org +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240710171057.35066-10-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Stable-dep-of: 7adbd2b78090 ("scsi: qla2xxx: Free sp in error path to fix system crash") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_def.h | 14 + + drivers/scsi/qla2xxx/qla_gbl.h | 6 + drivers/scsi/qla2xxx/qla_gs.c | 432 ++++++++++++++++------------------------ + drivers/scsi/qla2xxx/qla_init.c | 5 + drivers/scsi/qla2xxx/qla_os.c | 12 - + 5 files changed, 200 insertions(+), 269 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_def.h ++++ b/drivers/scsi/qla2xxx/qla_def.h +@@ -3262,11 +3262,20 @@ struct fab_scan_rp { + u8 node_name[8]; + }; + ++enum scan_step { ++ FAB_SCAN_START, ++ FAB_SCAN_GPNFT_FCP, ++ FAB_SCAN_GNNFT_FCP, ++ FAB_SCAN_GPNFT_NVME, ++ FAB_SCAN_GNNFT_NVME, ++}; ++ + struct fab_scan { + struct fab_scan_rp *l; + u32 size; + u32 rscn_gen_start; + u32 rscn_gen_end; ++ enum scan_step step; + u16 scan_retry; + #define MAX_SCAN_RETRIES 5 + enum scan_flags_t scan_flags; +@@ -3492,9 +3501,8 @@ enum qla_work_type { + QLA_EVT_RELOGIN, + QLA_EVT_ASYNC_PRLO, + QLA_EVT_ASYNC_PRLO_DONE, +- QLA_EVT_GPNFT, +- QLA_EVT_GPNFT_DONE, +- QLA_EVT_GNNFT_DONE, ++ QLA_EVT_SCAN_CMD, ++ QLA_EVT_SCAN_FINISH, + QLA_EVT_GFPNID, + QLA_EVT_SP_RETRY, + QLA_EVT_IIDMA, +--- a/drivers/scsi/qla2xxx/qla_gbl.h ++++ b/drivers/scsi/qla2xxx/qla_gbl.h +@@ -727,9 +727,9 @@ void qla24xx_handle_gpsc_event(scsi_qla_ + int qla2x00_mgmt_svr_login(scsi_qla_host_t *); + void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea); + int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool); +-int qla24xx_async_gpnft(scsi_qla_host_t *, u8, srb_t *); +-void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *); +-void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *); ++int qla_fab_async_scan(scsi_qla_host_t *, srb_t *); ++void qla_fab_scan_start(struct scsi_qla_host *); ++void qla_fab_scan_finish(scsi_qla_host_t *, srb_t *); + int qla24xx_post_gfpnid_work(struct scsi_qla_host *, fc_port_t *); + int qla24xx_async_gfpnid(scsi_qla_host_t *, fc_port_t *); + void qla24xx_handle_gfpnid_event(scsi_qla_host_t *, struct event_arg *); +--- a/drivers/scsi/qla2xxx/qla_gs.c ++++ b/drivers/scsi/qla2xxx/qla_gs.c +@@ -3487,7 +3487,7 @@ static bool qla_ok_to_clear_rscn(scsi_ql + return true; + } + +-void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) ++void qla_fab_scan_finish(scsi_qla_host_t *vha, srb_t *sp) + { + fc_port_t *fcport; + u32 i, rc; +@@ -3702,14 +3702,11 @@ out: + } + } + +-static int qla2x00_post_gnnft_gpnft_done_work(struct scsi_qla_host *vha, ++static int qla2x00_post_next_scan_work(struct scsi_qla_host *vha, + srb_t *sp, int cmd) + { + struct qla_work_evt *e; + +- if (cmd != QLA_EVT_GPNFT_DONE && cmd != QLA_EVT_GNNFT_DONE) +- return QLA_PARAMETER_ERROR; +- + e = qla2x00_alloc_work(vha, cmd); + if (!e) + return QLA_FUNCTION_FAILED; +@@ -3719,37 +3716,15 @@ static int qla2x00_post_gnnft_gpnft_done + return qla2x00_post_work(vha, e); + } + +-static int qla2x00_post_nvme_gpnft_work(struct scsi_qla_host *vha, +- srb_t *sp, int cmd) +-{ +- struct qla_work_evt *e; +- +- if (cmd != QLA_EVT_GPNFT) +- return QLA_PARAMETER_ERROR; +- +- e = qla2x00_alloc_work(vha, cmd); +- if (!e) +- return QLA_FUNCTION_FAILED; +- +- e->u.gpnft.fc4_type = FC4_TYPE_NVME; +- e->u.gpnft.sp = sp; +- +- return qla2x00_post_work(vha, e); +-} +- + static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha, + struct srb *sp) + { + struct qla_hw_data *ha = vha->hw; + int num_fibre_dev = ha->max_fibre_devices; +- struct ct_sns_req *ct_req = +- (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; + struct ct_sns_gpnft_rsp *ct_rsp = + (struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp; + struct ct_sns_gpn_ft_data *d; + struct fab_scan_rp *rp; +- u16 cmd = be16_to_cpu(ct_req->command); +- u8 fc4_type = sp->gen2; + int i, j, k; + port_id_t id; + u8 found; +@@ -3768,85 +3743,83 @@ static void qla2x00_find_free_fcp_nvme_s + if (id.b24 == 0 || wwn == 0) + continue; + +- if (fc4_type == FC4_TYPE_FCP_SCSI) { +- if (cmd == GPN_FT_CMD) { +- rp = &vha->scan.l[j]; +- rp->id = id; +- memcpy(rp->port_name, d->port_name, 8); +- j++; +- rp->fc4type = FS_FC4TYPE_FCP; +- } else { +- for (k = 0; k < num_fibre_dev; k++) { +- rp = &vha->scan.l[k]; +- if (id.b24 == rp->id.b24) { +- memcpy(rp->node_name, +- d->port_name, 8); +- break; +- } ++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2025, ++ "%s %06x %8ph \n", ++ __func__, id.b24, d->port_name); ++ ++ switch (vha->scan.step) { ++ case FAB_SCAN_GPNFT_FCP: ++ rp = &vha->scan.l[j]; ++ rp->id = id; ++ memcpy(rp->port_name, d->port_name, 8); ++ j++; ++ rp->fc4type = FS_FC4TYPE_FCP; ++ break; ++ case FAB_SCAN_GNNFT_FCP: ++ for (k = 0; k < num_fibre_dev; k++) { ++ rp = &vha->scan.l[k]; ++ if (id.b24 == rp->id.b24) { ++ memcpy(rp->node_name, ++ d->port_name, 8); ++ break; + } + } +- } else { +- /* Search if the fibre device supports FC4_TYPE_NVME */ +- if (cmd == GPN_FT_CMD) { +- found = 0; ++ break; ++ case FAB_SCAN_GPNFT_NVME: ++ found = 0; + +- for (k = 0; k < num_fibre_dev; k++) { +- rp = &vha->scan.l[k]; +- if (!memcmp(rp->port_name, +- d->port_name, 8)) { +- /* +- * Supports FC-NVMe & FCP +- */ +- rp->fc4type |= FS_FC4TYPE_NVME; +- found = 1; +- break; +- } ++ for (k = 0; k < num_fibre_dev; k++) { ++ rp = &vha->scan.l[k]; ++ if (!memcmp(rp->port_name, d->port_name, 8)) { ++ /* ++ * Supports FC-NVMe & FCP ++ */ ++ rp->fc4type |= FS_FC4TYPE_NVME; ++ found = 1; ++ break; + } ++ } + +- /* We found new FC-NVMe only port */ +- if (!found) { +- for (k = 0; k < num_fibre_dev; k++) { +- rp = &vha->scan.l[k]; +- if (wwn_to_u64(rp->port_name)) { +- continue; +- } else { +- rp->id = id; +- memcpy(rp->port_name, +- d->port_name, 8); +- rp->fc4type = +- FS_FC4TYPE_NVME; +- break; +- } +- } +- } +- } else { ++ /* We found new FC-NVMe only port */ ++ if (!found) { + for (k = 0; k < num_fibre_dev; k++) { + rp = &vha->scan.l[k]; +- if (id.b24 == rp->id.b24) { +- memcpy(rp->node_name, +- d->port_name, 8); ++ if (wwn_to_u64(rp->port_name)) { ++ continue; ++ } else { ++ rp->id = id; ++ memcpy(rp->port_name, d->port_name, 8); ++ rp->fc4type = FS_FC4TYPE_NVME; + break; + } + } + } ++ break; ++ case FAB_SCAN_GNNFT_NVME: ++ for (k = 0; k < num_fibre_dev; k++) { ++ rp = &vha->scan.l[k]; ++ if (id.b24 == rp->id.b24) { ++ memcpy(rp->node_name, d->port_name, 8); ++ break; ++ } ++ } ++ break; ++ default: ++ break; + } + } + } + +-static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) ++static void qla_async_scan_sp_done(srb_t *sp, int res) + { + struct scsi_qla_host *vha = sp->vha; +- struct ct_sns_req *ct_req = +- (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; +- u16 cmd = be16_to_cpu(ct_req->command); +- u8 fc4_type = sp->gen2; + unsigned long flags; + int rc; + + /* gen2 field is holding the fc4type */ +- ql_dbg(ql_dbg_disc, vha, 0xffff, +- "Async done-%s res %x FC4Type %x\n", +- sp->name, res, sp->gen2); ++ ql_dbg(ql_dbg_disc, vha, 0x2026, ++ "Async done-%s res %x step %x\n", ++ sp->name, res, vha->scan.step); + + sp->rc = res; + if (res) { +@@ -3870,8 +3843,7 @@ static void qla2x00_async_gpnft_gnnft_sp + * sp for GNNFT_DONE work. This will allow all + * the resource to get freed up. + */ +- rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp, +- QLA_EVT_GNNFT_DONE); ++ rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_FINISH); + if (rc) { + /* Cleanup here to prevent memory leak */ + qla24xx_sp_unmap(vha, sp); +@@ -3896,28 +3868,30 @@ static void qla2x00_async_gpnft_gnnft_sp + + qla2x00_find_free_fcp_nvme_slot(vha, sp); + +- if ((fc4_type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled && +- cmd == GNN_FT_CMD) { +- spin_lock_irqsave(&vha->work_lock, flags); +- vha->scan.scan_flags &= ~SF_SCANNING; +- spin_unlock_irqrestore(&vha->work_lock, flags); +- +- sp->rc = res; +- rc = qla2x00_post_nvme_gpnft_work(vha, sp, QLA_EVT_GPNFT); +- if (rc) { +- qla24xx_sp_unmap(vha, sp); +- set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); +- set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); +- } +- return; +- } ++ spin_lock_irqsave(&vha->work_lock, flags); ++ vha->scan.scan_flags &= ~SF_SCANNING; ++ spin_unlock_irqrestore(&vha->work_lock, flags); + +- if (cmd == GPN_FT_CMD) { +- rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp, +- QLA_EVT_GPNFT_DONE); +- } else { +- rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp, +- QLA_EVT_GNNFT_DONE); ++ switch (vha->scan.step) { ++ case FAB_SCAN_GPNFT_FCP: ++ case FAB_SCAN_GPNFT_NVME: ++ rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_CMD); ++ break; ++ case FAB_SCAN_GNNFT_FCP: ++ if (vha->flags.nvme_enabled) ++ rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_CMD); ++ else ++ rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_FINISH); ++ ++ break; ++ case FAB_SCAN_GNNFT_NVME: ++ rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_FINISH); ++ break; ++ default: ++ /* should not be here */ ++ WARN_ON(1); ++ rc = QLA_FUNCTION_FAILED; ++ break; + } + + if (rc) { +@@ -3928,127 +3902,16 @@ static void qla2x00_async_gpnft_gnnft_sp + } + } + +-/* +- * Get WWNN list for fc4_type +- * +- * It is assumed the same SRB is re-used from GPNFT to avoid +- * mem free & re-alloc +- */ +-static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp, +- u8 fc4_type) +-{ +- int rval = QLA_FUNCTION_FAILED; +- struct ct_sns_req *ct_req; +- struct ct_sns_pkt *ct_sns; +- unsigned long flags; +- +- if (!vha->flags.online) { +- spin_lock_irqsave(&vha->work_lock, flags); +- vha->scan.scan_flags &= ~SF_SCANNING; +- spin_unlock_irqrestore(&vha->work_lock, flags); +- goto done_free_sp; +- } +- +- if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) { +- ql_log(ql_log_warn, vha, 0xffff, +- "%s: req %p rsp %p are not setup\n", +- __func__, sp->u.iocb_cmd.u.ctarg.req, +- sp->u.iocb_cmd.u.ctarg.rsp); +- spin_lock_irqsave(&vha->work_lock, flags); +- vha->scan.scan_flags &= ~SF_SCANNING; +- spin_unlock_irqrestore(&vha->work_lock, flags); +- WARN_ON(1); +- set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); +- set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); +- goto done_free_sp; +- } +- +- ql_dbg(ql_dbg_disc, vha, 0xfffff, +- "%s: FC4Type %x, CT-PASSTHRU %s command ctarg rsp size %d, ctarg req size %d\n", +- __func__, fc4_type, sp->name, sp->u.iocb_cmd.u.ctarg.rsp_size, +- sp->u.iocb_cmd.u.ctarg.req_size); +- +- sp->type = SRB_CT_PTHRU_CMD; +- sp->name = "gnnft"; +- sp->gen1 = vha->hw->base_qpair->chip_reset; +- sp->gen2 = fc4_type; +- qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2, +- qla2x00_async_gpnft_gnnft_sp_done); +- +- memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size); +- memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size); +- +- ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; +- /* CT_IU preamble */ +- ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD, +- sp->u.iocb_cmd.u.ctarg.rsp_size); +- +- /* GPN_FT req */ +- ct_req->req.gpn_ft.port_type = fc4_type; +- +- sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE; +- sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; +- +- ql_dbg(ql_dbg_disc, vha, 0xffff, +- "Async-%s hdl=%x FC4Type %x.\n", sp->name, +- sp->handle, ct_req->req.gpn_ft.port_type); +- +- rval = qla2x00_start_sp(sp); +- if (rval != QLA_SUCCESS) { +- goto done_free_sp; +- } +- +- return rval; +- +-done_free_sp: +- if (sp->u.iocb_cmd.u.ctarg.req) { +- dma_free_coherent(&vha->hw->pdev->dev, +- sp->u.iocb_cmd.u.ctarg.req_allocated_size, +- sp->u.iocb_cmd.u.ctarg.req, +- sp->u.iocb_cmd.u.ctarg.req_dma); +- sp->u.iocb_cmd.u.ctarg.req = NULL; +- } +- if (sp->u.iocb_cmd.u.ctarg.rsp) { +- dma_free_coherent(&vha->hw->pdev->dev, +- sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, +- sp->u.iocb_cmd.u.ctarg.rsp, +- sp->u.iocb_cmd.u.ctarg.rsp_dma); +- sp->u.iocb_cmd.u.ctarg.rsp = NULL; +- } +- /* ref: INIT */ +- kref_put(&sp->cmd_kref, qla2x00_sp_release); +- +- spin_lock_irqsave(&vha->work_lock, flags); +- vha->scan.scan_flags &= ~SF_SCANNING; +- if (vha->scan.scan_flags == 0) { +- ql_dbg(ql_dbg_disc, vha, 0xffff, +- "%s: schedule\n", __func__); +- vha->scan.scan_flags |= SF_QUEUED; +- schedule_delayed_work(&vha->scan.scan_work, 5); +- } +- spin_unlock_irqrestore(&vha->work_lock, flags); +- +- +- return rval; +-} /* GNNFT */ +- +-void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp) +-{ +- ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, +- "%s enter\n", __func__); +- qla24xx_async_gnnft(vha, sp, sp->gen2); +-} +- + /* Get WWPN list for certain fc4_type */ +-int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) ++int qla_fab_async_scan(scsi_qla_host_t *vha, srb_t *sp) + { + int rval = QLA_FUNCTION_FAILED; + struct ct_sns_req *ct_req; + struct ct_sns_pkt *ct_sns; +- u32 rspsz; ++ u32 rspsz = 0; + unsigned long flags; + +- ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, ++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x200c, + "%s enter\n", __func__); + + if (!vha->flags.online) +@@ -4057,22 +3920,21 @@ int qla24xx_async_gpnft(scsi_qla_host_t + spin_lock_irqsave(&vha->work_lock, flags); + if (vha->scan.scan_flags & SF_SCANNING) { + spin_unlock_irqrestore(&vha->work_lock, flags); +- ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, ++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2012, + "%s: scan active\n", __func__); + return rval; + } + vha->scan.scan_flags |= SF_SCANNING; ++ if (!sp) ++ vha->scan.step = FAB_SCAN_START; ++ + spin_unlock_irqrestore(&vha->work_lock, flags); + +- if (fc4_type == FC4_TYPE_FCP_SCSI) { +- ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, ++ switch (vha->scan.step) { ++ case FAB_SCAN_START: ++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2018, + "%s: Performing FCP Scan\n", __func__); + +- if (sp) { +- /* ref: INIT */ +- kref_put(&sp->cmd_kref, qla2x00_sp_release); +- } +- + /* ref: INIT */ + sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); + if (!sp) { +@@ -4088,7 +3950,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t + GFP_KERNEL); + sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt); + if (!sp->u.iocb_cmd.u.ctarg.req) { +- ql_log(ql_log_warn, vha, 0xffff, ++ ql_log(ql_log_warn, vha, 0x201a, + "Failed to allocate ct_sns request.\n"); + spin_lock_irqsave(&vha->work_lock, flags); + vha->scan.scan_flags &= ~SF_SCANNING; +@@ -4096,7 +3958,6 @@ int qla24xx_async_gpnft(scsi_qla_host_t + qla2x00_rel_sp(sp); + return rval; + } +- sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE; + + rspsz = sizeof(struct ct_sns_gpnft_rsp) + + ((vha->hw->max_fibre_devices - 1) * +@@ -4108,7 +3969,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t + GFP_KERNEL); + sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = rspsz; + if (!sp->u.iocb_cmd.u.ctarg.rsp) { +- ql_log(ql_log_warn, vha, 0xffff, ++ ql_log(ql_log_warn, vha, 0x201b, + "Failed to allocate ct_sns request.\n"); + spin_lock_irqsave(&vha->work_lock, flags); + vha->scan.scan_flags &= ~SF_SCANNING; +@@ -4128,35 +3989,95 @@ int qla24xx_async_gpnft(scsi_qla_host_t + "%s scan list size %d\n", __func__, vha->scan.size); + + memset(vha->scan.l, 0, vha->scan.size); +- } else if (!sp) { +- ql_dbg(ql_dbg_disc, vha, 0xffff, +- "NVME scan did not provide SP\n"); ++ ++ vha->scan.step = FAB_SCAN_GPNFT_FCP; ++ break; ++ case FAB_SCAN_GPNFT_FCP: ++ vha->scan.step = FAB_SCAN_GNNFT_FCP; ++ break; ++ case FAB_SCAN_GNNFT_FCP: ++ vha->scan.step = FAB_SCAN_GPNFT_NVME; ++ break; ++ case FAB_SCAN_GPNFT_NVME: ++ vha->scan.step = FAB_SCAN_GNNFT_NVME; ++ break; ++ case FAB_SCAN_GNNFT_NVME: ++ default: ++ /* should not be here */ ++ WARN_ON(1); ++ goto done_free_sp; ++ } ++ ++ if (!sp) { ++ ql_dbg(ql_dbg_disc, vha, 0x201c, ++ "scan did not provide SP\n"); + return rval; + } ++ if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) { ++ ql_log(ql_log_warn, vha, 0x201d, ++ "%s: req %p rsp %p are not setup\n", ++ __func__, sp->u.iocb_cmd.u.ctarg.req, ++ sp->u.iocb_cmd.u.ctarg.rsp); ++ spin_lock_irqsave(&vha->work_lock, flags); ++ vha->scan.scan_flags &= ~SF_SCANNING; ++ spin_unlock_irqrestore(&vha->work_lock, flags); ++ WARN_ON(1); ++ set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); ++ set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); ++ goto done_free_sp; ++ } ++ ++ rspsz = sp->u.iocb_cmd.u.ctarg.rsp_size; ++ memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size); ++ memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size); ++ + + sp->type = SRB_CT_PTHRU_CMD; +- sp->name = "gpnft"; + sp->gen1 = vha->hw->base_qpair->chip_reset; +- sp->gen2 = fc4_type; + qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2, +- qla2x00_async_gpnft_gnnft_sp_done); +- +- rspsz = sp->u.iocb_cmd.u.ctarg.rsp_size; +- memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size); +- memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size); ++ qla_async_scan_sp_done); + + ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; +- /* CT_IU preamble */ +- ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz); + +- /* GPN_FT req */ +- ct_req->req.gpn_ft.port_type = fc4_type; ++ /* CT_IU preamble */ ++ switch (vha->scan.step) { ++ case FAB_SCAN_GPNFT_FCP: ++ sp->name = "gpnft"; ++ ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz); ++ ct_req->req.gpn_ft.port_type = FC4_TYPE_FCP_SCSI; ++ sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE; ++ break; ++ case FAB_SCAN_GNNFT_FCP: ++ sp->name = "gnnft"; ++ ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD, rspsz); ++ ct_req->req.gpn_ft.port_type = FC4_TYPE_FCP_SCSI; ++ sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE; ++ break; ++ case FAB_SCAN_GPNFT_NVME: ++ sp->name = "gpnft"; ++ ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz); ++ ct_req->req.gpn_ft.port_type = FC4_TYPE_NVME; ++ sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE; ++ break; ++ case FAB_SCAN_GNNFT_NVME: ++ sp->name = "gnnft"; ++ ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD, rspsz); ++ ct_req->req.gpn_ft.port_type = FC4_TYPE_NVME; ++ sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE; ++ break; ++ default: ++ /* should not be here */ ++ WARN_ON(1); ++ goto done_free_sp; ++ } + + sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; + +- ql_dbg(ql_dbg_disc, vha, 0xffff, +- "Async-%s hdl=%x FC4Type %x.\n", sp->name, +- sp->handle, ct_req->req.gpn_ft.port_type); ++ ql_dbg(ql_dbg_disc, vha, 0x2003, ++ "%s: step %d, rsp size %d, req size %d hdl %x %s FC4TYPE %x \n", ++ __func__, vha->scan.step, sp->u.iocb_cmd.u.ctarg.rsp_size, ++ sp->u.iocb_cmd.u.ctarg.req_size, sp->handle, sp->name, ++ ct_req->req.gpn_ft.port_type); + + rval = qla2x00_start_sp(sp); + if (rval != QLA_SUCCESS) { +@@ -4189,7 +4110,7 @@ done_free_sp: + spin_lock_irqsave(&vha->work_lock, flags); + vha->scan.scan_flags &= ~SF_SCANNING; + if (vha->scan.scan_flags == 0) { +- ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, ++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2007, + "%s: Scan scheduled.\n", __func__); + vha->scan.scan_flags |= SF_QUEUED; + schedule_delayed_work(&vha->scan.scan_work, 5); +@@ -4200,6 +4121,15 @@ done_free_sp: + return rval; + } + ++void qla_fab_scan_start(struct scsi_qla_host *vha) ++{ ++ int rval; ++ ++ rval = qla_fab_async_scan(vha, NULL); ++ if (rval) ++ set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); ++} ++ + void qla_scan_work_fn(struct work_struct *work) + { + struct fab_scan *s = container_of(to_delayed_work(work), +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -6457,10 +6457,7 @@ qla2x00_configure_fabric(scsi_qla_host_t + if (USE_ASYNC_SCAN(ha)) { + /* start of scan begins here */ + vha->scan.rscn_gen_end = atomic_read(&vha->rscn_gen); +- rval = qla24xx_async_gpnft(vha, FC4_TYPE_FCP_SCSI, +- NULL); +- if (rval) +- set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); ++ qla_fab_scan_start(vha); + } else { + list_for_each_entry(fcport, &vha->vp_fcports, list) + fcport->scan_state = QLA_FCPORT_SCAN; +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -5490,15 +5490,11 @@ qla2x00_do_work(struct scsi_qla_host *vh + qla2x00_async_prlo_done(vha, e->u.logio.fcport, + e->u.logio.data); + break; +- case QLA_EVT_GPNFT: +- qla24xx_async_gpnft(vha, e->u.gpnft.fc4_type, +- e->u.gpnft.sp); ++ case QLA_EVT_SCAN_CMD: ++ qla_fab_async_scan(vha, e->u.iosb.sp); + break; +- case QLA_EVT_GPNFT_DONE: +- qla24xx_async_gpnft_done(vha, e->u.iosb.sp); +- break; +- case QLA_EVT_GNNFT_DONE: +- qla24xx_async_gnnft_done(vha, e->u.iosb.sp); ++ case QLA_EVT_SCAN_FINISH: ++ qla_fab_scan_finish(vha, e->u.iosb.sp); + break; + case QLA_EVT_GFPNID: + qla24xx_async_gfpnid(vha, e->u.fcport.fcport); diff --git a/queue-5.15/scsi-qla2xxx-remove-dead-code-gnn-id.patch b/queue-5.15/scsi-qla2xxx-remove-dead-code-gnn-id.patch new file mode 100644 index 0000000000..6c402db441 --- /dev/null +++ b/queue-5.15/scsi-qla2xxx-remove-dead-code-gnn-id.patch @@ -0,0 +1,214 @@ +From stable+bounces-216270-greg=kroah.com@vger.kernel.org Fri Feb 13 17:46:56 2026 +From: Sasha Levin +Date: Fri, 13 Feb 2026 11:45:01 -0500 +Subject: scsi: qla2xxx: Remove dead code (GNN ID) +To: stable@vger.kernel.org +Cc: Quinn Tran , Nilesh Javali , Himanshu Madhani , "Martin K. Petersen" , Sasha Levin +Message-ID: <20260213164503.3564614-2-sashal@kernel.org> + +From: Quinn Tran + +[ Upstream commit 87f6dafd50fb6d7214c32596a11b983138b09123 ] + +Remove stale/unused code (GNN ID). + +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Stable-dep-of: 7adbd2b78090 ("scsi: qla2xxx: Free sp in error path to fix system crash") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_def.h | 3 - + drivers/scsi/qla2xxx/qla_gbl.h | 3 - + drivers/scsi/qla2xxx/qla_gs.c | 110 ---------------------------------------- + drivers/scsi/qla2xxx/qla_init.c | 7 -- + drivers/scsi/qla2xxx/qla_os.c | 3 - + 5 files changed, 1 insertion(+), 125 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_def.h ++++ b/drivers/scsi/qla2xxx/qla_def.h +@@ -2488,7 +2488,6 @@ struct ct_sns_desc { + + enum discovery_state { + DSC_DELETED, +- DSC_GNN_ID, + DSC_GNL, + DSC_LOGIN_PEND, + DSC_LOGIN_FAILED, +@@ -2701,7 +2700,6 @@ extern const char *const port_state_str[ + + static const char *const port_dstate_str[] = { + [DSC_DELETED] = "DELETED", +- [DSC_GNN_ID] = "GNN_ID", + [DSC_GNL] = "GNL", + [DSC_LOGIN_PEND] = "LOGIN_PEND", + [DSC_LOGIN_FAILED] = "LOGIN_FAILED", +@@ -3497,7 +3495,6 @@ enum qla_work_type { + QLA_EVT_GPNFT, + QLA_EVT_GPNFT_DONE, + QLA_EVT_GNNFT_DONE, +- QLA_EVT_GNNID, + QLA_EVT_GFPNID, + QLA_EVT_SP_RETRY, + QLA_EVT_IIDMA, +--- a/drivers/scsi/qla2xxx/qla_gbl.h ++++ b/drivers/scsi/qla2xxx/qla_gbl.h +@@ -730,9 +730,6 @@ int qla24xx_async_gffid(scsi_qla_host_t + int qla24xx_async_gpnft(scsi_qla_host_t *, u8, srb_t *); + void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *); + void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *); +-int qla24xx_async_gnnid(scsi_qla_host_t *, fc_port_t *); +-void qla24xx_handle_gnnid_event(scsi_qla_host_t *, struct event_arg *); +-int qla24xx_post_gnnid_work(struct scsi_qla_host *, fc_port_t *); + int qla24xx_post_gfpnid_work(struct scsi_qla_host *, fc_port_t *); + int qla24xx_async_gfpnid(scsi_qla_host_t *, fc_port_t *); + void qla24xx_handle_gfpnid_event(scsi_qla_host_t *, struct event_arg *); +--- a/drivers/scsi/qla2xxx/qla_gs.c ++++ b/drivers/scsi/qla2xxx/qla_gs.c +@@ -4218,116 +4218,6 @@ void qla_scan_work_fn(struct work_struct + spin_unlock_irqrestore(&vha->work_lock, flags); + } + +-/* GNN_ID */ +-void qla24xx_handle_gnnid_event(scsi_qla_host_t *vha, struct event_arg *ea) +-{ +- qla24xx_post_gnl_work(vha, ea->fcport); +-} +- +-static void qla2x00_async_gnnid_sp_done(srb_t *sp, int res) +-{ +- struct scsi_qla_host *vha = sp->vha; +- fc_port_t *fcport = sp->fcport; +- u8 *node_name = fcport->ct_desc.ct_sns->p.rsp.rsp.gnn_id.node_name; +- struct event_arg ea; +- u64 wwnn; +- +- fcport->flags &= ~FCF_ASYNC_SENT; +- wwnn = wwn_to_u64(node_name); +- if (wwnn) +- memcpy(fcport->node_name, node_name, WWN_SIZE); +- +- memset(&ea, 0, sizeof(ea)); +- ea.fcport = fcport; +- ea.sp = sp; +- ea.rc = res; +- +- ql_dbg(ql_dbg_disc, vha, 0x204f, +- "Async done-%s res %x, WWPN %8phC %8phC\n", +- sp->name, res, fcport->port_name, fcport->node_name); +- +- qla24xx_handle_gnnid_event(vha, &ea); +- +- /* ref: INIT */ +- kref_put(&sp->cmd_kref, qla2x00_sp_release); +-} +- +-int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport) +-{ +- int rval = QLA_FUNCTION_FAILED; +- struct ct_sns_req *ct_req; +- srb_t *sp; +- +- if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) +- return rval; +- +- qla2x00_set_fcport_disc_state(fcport, DSC_GNN_ID); +- /* ref: INIT */ +- sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); +- if (!sp) +- goto done; +- +- fcport->flags |= FCF_ASYNC_SENT; +- sp->type = SRB_CT_PTHRU_CMD; +- sp->name = "gnnid"; +- sp->gen1 = fcport->rscn_gen; +- sp->gen2 = fcport->login_gen; +- qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2, +- qla2x00_async_gnnid_sp_done); +- +- /* CT_IU preamble */ +- ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GNN_ID_CMD, +- GNN_ID_RSP_SIZE); +- +- /* GNN_ID req */ +- ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id); +- +- +- /* req & rsp use the same buffer */ +- sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; +- sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; +- sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; +- sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; +- sp->u.iocb_cmd.u.ctarg.req_size = GNN_ID_REQ_SIZE; +- sp->u.iocb_cmd.u.ctarg.rsp_size = GNN_ID_RSP_SIZE; +- sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; +- +- ql_dbg(ql_dbg_disc, vha, 0xffff, +- "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n", +- sp->name, fcport->port_name, +- sp->handle, fcport->loop_id, fcport->d_id.b24); +- +- rval = qla2x00_start_sp(sp); +- if (rval != QLA_SUCCESS) +- goto done_free_sp; +- return rval; +- +-done_free_sp: +- /* ref: INIT */ +- kref_put(&sp->cmd_kref, qla2x00_sp_release); +- fcport->flags &= ~FCF_ASYNC_SENT; +-done: +- return rval; +-} +- +-int qla24xx_post_gnnid_work(struct scsi_qla_host *vha, fc_port_t *fcport) +-{ +- struct qla_work_evt *e; +- int ls; +- +- ls = atomic_read(&vha->loop_state); +- if (((ls != LOOP_READY) && (ls != LOOP_UP)) || +- test_bit(UNLOADING, &vha->dpc_flags)) +- return 0; +- +- e = qla2x00_alloc_work(vha, QLA_EVT_GNNID); +- if (!e) +- return QLA_FUNCTION_FAILED; +- +- e->u.fcport.fcport = fcport; +- return qla2x00_post_work(vha, e); +-} +- + /* GPFN_ID */ + void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) + { +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -1725,12 +1725,7 @@ int qla24xx_fcport_handle_login(struct s + } + break; + default: +- if (wwn == 0) { +- ql_dbg(ql_dbg_disc, vha, 0xffff, +- "%s %d %8phC post GNNID\n", +- __func__, __LINE__, fcport->port_name); +- qla24xx_post_gnnid_work(vha, fcport); +- } else if (fcport->loop_id == FC_NO_LOOP_ID) { ++ if (fcport->loop_id == FC_NO_LOOP_ID) { + ql_dbg(ql_dbg_disc, vha, 0x20bd, + "%s %d %8phC post gnl\n", + __func__, __LINE__, fcport->port_name); +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -5500,9 +5500,6 @@ qla2x00_do_work(struct scsi_qla_host *vh + case QLA_EVT_GNNFT_DONE: + qla24xx_async_gnnft_done(vha, e->u.iosb.sp); + break; +- case QLA_EVT_GNNID: +- qla24xx_async_gnnid(vha, e->u.fcport.fcport); +- break; + case QLA_EVT_GFPNID: + qla24xx_async_gfpnid(vha, e->u.fcport.fcport); + break; diff --git a/queue-5.15/scsi-qla2xxx-use-named-initializers-for-port_state_str.patch b/queue-5.15/scsi-qla2xxx-use-named-initializers-for-port_state_str.patch new file mode 100644 index 0000000000..5396e99eb2 --- /dev/null +++ b/queue-5.15/scsi-qla2xxx-use-named-initializers-for-port_state_str.patch @@ -0,0 +1,95 @@ +From stable+bounces-216269-greg=kroah.com@vger.kernel.org Fri Feb 13 17:45:10 2026 +From: Sasha Levin +Date: Fri, 13 Feb 2026 11:45:00 -0500 +Subject: scsi: qla2xxx: Use named initializers for port_[d]state_str +To: stable@vger.kernel.org +Cc: Gleb Chesnokov , Himanshu Madhani , "Martin K. Petersen" , Sasha Levin +Message-ID: <20260213164503.3564614-1-sashal@kernel.org> + +From: Gleb Chesnokov + +[ Upstream commit 6e0e85d39e528da2915a2da261195f81bfde6915 ] + +Make port_state_str and port_dstate_str a little more readable and +maintainable by using named initializers. + +Also convert FCS_* macros into an enum. + +Link: https://lore.kernel.org/r/AS8PR10MB495215841EB25C16DBC0CB409D349@AS8PR10MB4952.EURPRD10.PROD.OUTLOOK.COM +Reviewed-by: Himanshu Madhani +Signed-off-by: Gleb Chesnokov +Signed-off-by: Martin K. Petersen +Stable-dep-of: 7adbd2b78090 ("scsi: qla2xxx: Free sp in error path to fix system crash") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_def.h | 35 +++++++++++++++++++---------------- + drivers/scsi/qla2xxx/qla_isr.c | 10 +++++----- + 2 files changed, 24 insertions(+), 21 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_def.h ++++ b/drivers/scsi/qla2xxx/qla_def.h +@@ -2689,25 +2689,28 @@ struct event_arg { + /* + * Fibre channel port/lun states. + */ +-#define FCS_UNCONFIGURED 1 +-#define FCS_DEVICE_DEAD 2 +-#define FCS_DEVICE_LOST 3 +-#define FCS_ONLINE 4 ++enum { ++ FCS_UNKNOWN, ++ FCS_UNCONFIGURED, ++ FCS_DEVICE_DEAD, ++ FCS_DEVICE_LOST, ++ FCS_ONLINE, ++}; + + extern const char *const port_state_str[5]; + +-static const char * const port_dstate_str[] = { +- "DELETED", +- "GNN_ID", +- "GNL", +- "LOGIN_PEND", +- "LOGIN_FAILED", +- "GPDB", +- "UPD_FCPORT", +- "LOGIN_COMPLETE", +- "ADISC", +- "DELETE_PEND", +- "LOGIN_AUTH_PEND", ++static const char *const port_dstate_str[] = { ++ [DSC_DELETED] = "DELETED", ++ [DSC_GNN_ID] = "GNN_ID", ++ [DSC_GNL] = "GNL", ++ [DSC_LOGIN_PEND] = "LOGIN_PEND", ++ [DSC_LOGIN_FAILED] = "LOGIN_FAILED", ++ [DSC_GPDB] = "GPDB", ++ [DSC_UPD_FCPORT] = "UPD_FCPORT", ++ [DSC_LOGIN_COMPLETE] = "LOGIN_COMPLETE", ++ [DSC_ADISC] = "ADISC", ++ [DSC_DELETE_PEND] = "DELETE_PEND", ++ [DSC_LOGIN_AUTH_PEND] = "LOGIN_AUTH_PEND", + }; + + /* +--- a/drivers/scsi/qla2xxx/qla_isr.c ++++ b/drivers/scsi/qla2xxx/qla_isr.c +@@ -49,11 +49,11 @@ qla27xx_process_purex_fpin(struct scsi_q + } + + const char *const port_state_str[] = { +- "Unknown", +- "UNCONFIGURED", +- "DEAD", +- "LOST", +- "ONLINE" ++ [FCS_UNKNOWN] = "Unknown", ++ [FCS_UNCONFIGURED] = "UNCONFIGURED", ++ [FCS_DEVICE_DEAD] = "DEAD", ++ [FCS_DEVICE_LOST] = "LOST", ++ [FCS_ONLINE] = "ONLINE" + }; + + static void diff --git a/queue-5.15/selftests-mptcp-pm-ensure-unknown-flags-are-ignored.patch b/queue-5.15/selftests-mptcp-pm-ensure-unknown-flags-are-ignored.patch new file mode 100644 index 0000000000..cc5e77af4f --- /dev/null +++ b/queue-5.15/selftests-mptcp-pm-ensure-unknown-flags-are-ignored.patch @@ -0,0 +1,94 @@ +From matttbe@kernel.org Thu Feb 12 12:04:04 2026 +From: "Matthieu Baerts (NGI0)" +Date: Thu, 12 Feb 2026 12:03:45 +0100 +Subject: selftests: mptcp: pm: ensure unknown flags are ignored +To: stable@vger.kernel.org, gregkh@linuxfoundation.org +Cc: MPTCP Upstream , "Matthieu Baerts (NGI0)" , Mat Martineau , Jakub Kicinski +Message-ID: <20260212110344.781836-2-matttbe@kernel.org> + +From: "Matthieu Baerts (NGI0)" + +commit 29f4801e9c8dfd12bdcb33b61a6ac479c7162bd7 upstream. + +This validates the previous commit: the userspace can set unknown flags +-- the 7th bit is currently unused -- without errors, but only the +supported ones are printed in the endpoints dumps. + +The 'Fixes' tag here below is the same as the one from the previous +commit: this patch here is not fixing anything wrong in the selftests, +but it validates the previous fix for an issue introduced by this commit +ID. + +Fixes: 01cacb00b35c ("mptcp: add netlink-based PM") +Cc: stable@vger.kernel.org +Reviewed-by: Mat Martineau +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20251205-net-mptcp-misc-fixes-6-19-rc1-v1-2-9e4781a6c1b8@kernel.org +Signed-off-by: Jakub Kicinski +[ Conflicts in pm_netlink.sh, because some refactoring have been done + later on: commit 0d16ed0c2e74 ("selftests: mptcp: add + {get,format}_endpoint(s) helpers") and commit c99d57d0007a + ("selftests: mptcp: use pm_nl endpoint ops") are not in this version. + The same operation can still be done at the same place, without using + the new helpers. + Also, commit 1dc88d241f92 ("selftests: mptcp: pm_nl_ctl: always look + for errors") is not in this version, and create a conflict in the + context which is not related to the modification here. + Conflicts in pm_nl_ctl.c, because commit 69c6ce7b6eca ("selftests: + mptcp: add implicit endpoint test case") is not in this version, and + caused a conflict in the context which is not related to the + modification here. ] +Signed-off-by: Matthieu Baerts (NGI0) +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/net/mptcp/pm_netlink.sh | 4 ++++ + tools/testing/selftests/net/mptcp/pm_nl_ctl.c | 11 +++++++++++ + 2 files changed, 15 insertions(+) + +--- a/tools/testing/selftests/net/mptcp/pm_netlink.sh ++++ b/tools/testing/selftests/net/mptcp/pm_netlink.sh +@@ -124,6 +124,10 @@ id 8 flags signal 10.0.1.8" "id limit" + ip netns exec $ns1 ./pm_nl_ctl flush + check "ip netns exec $ns1 ./pm_nl_ctl dump" "" "flush addrs" + ++ip netns exec $ns1 ./pm_nl_ctl add 10.0.1.1 flags unknown ++check "ip netns exec $ns1 ./pm_nl_ctl dump" "id 1 flags 10.0.1.1" "ignore unknown flags" ++ip netns exec $ns1 ./pm_nl_ctl flush ++ + ip netns exec $ns1 ./pm_nl_ctl limits 9 1 + check "ip netns exec $ns1 ./pm_nl_ctl limits" "$default_limits" "rcv addrs above hard limit" + +--- a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c ++++ b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c +@@ -22,6 +22,8 @@ + #define MPTCP_PM_NAME "mptcp_pm" + #endif + ++#define MPTCP_PM_ADDR_FLAG_UNKNOWN _BITUL(7) ++ + static void syntax(char *argv[]) + { + fprintf(stderr, "%s add|get|set|del|flush|dump|accept []\n", argv[0]); +@@ -238,6 +240,8 @@ int add_addr(int fd, int pm_family, int + flags |= MPTCP_PM_ADDR_FLAG_BACKUP; + else if (!strcmp(tok, "fullmesh")) + flags |= MPTCP_PM_ADDR_FLAG_FULLMESH; ++ else if (!strcmp(tok, "unknown")) ++ flags |= MPTCP_PM_ADDR_FLAG_UNKNOWN; + else + error(1, errno, + "unknown flag %s", argv[arg]); +@@ -435,6 +439,13 @@ static void print_addr(struct rtattr *at + if (flags) + printf(","); + } ++ ++ if (flags & MPTCP_PM_ADDR_FLAG_UNKNOWN) { ++ printf("unknown"); ++ flags &= ~MPTCP_PM_ADDR_FLAG_UNKNOWN; ++ if (flags) ++ printf(","); ++ } + + /* bump unknown flags, if any */ + if (flags) diff --git a/queue-5.15/series b/queue-5.15/series index 2d0f4a5a21..5b3a0fc4fc 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -15,3 +15,20 @@ platform-x86-panasonic-laptop-fix-sysfs-group-leak-i.patch asoc-fsl_xcvr-fix-missing-lock-in-fsl_xcvr_mode_put.patch gpiolib-acpi-fix-gpio-count-with-string-references.patch revert-wireguard-device-enable-threaded-napi.patch +btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_info_full.patch +smb-client-set-correct-id-uid-and-cruid-for-multiuser-automounts.patch +net-dsa-free-routing-table-on-probe-failure.patch +selftests-mptcp-pm-ensure-unknown-flags-are-ignored.patch +mptcp-fix-race-in-mptcp_pm_nl_flush_addrs_doit.patch +crypto-virtio-remove-duplicated-virtqueue_kick-in-virtio_crypto_skcipher_crypt_req.patch +smb-server-fix-leak-of-active_num_conn-in-ksmbd_tcp_new_connection.patch +bus-fsl-mc-replace-snprintf-and-sprintf-with-sysfs_emit-in-sysfs-show-functions.patch +bus-fsl-mc-fix-use-after-free-in-driver_override_show.patch +scsi-qla2xxx-fix-bsg_done-causing-double-free.patch +scsi-qla2xxx-use-named-initializers-for-port_state_str.patch +scsi-qla2xxx-remove-dead-code-gnn-id.patch +scsi-qla2xxx-reduce-fabric-scan-duplicate-code.patch +scsi-qla2xxx-free-sp-in-error-path-to-fix-system-crash.patch +pci-endpoint-automatically-create-a-function-specific-attributes-group.patch +pci-endpoint-remove-unused-field-in-struct-pci_epf_group.patch +pci-endpoint-avoid-creating-sub-groups-asynchronously.patch diff --git a/queue-5.15/smb-client-set-correct-id-uid-and-cruid-for-multiuser-automounts.patch b/queue-5.15/smb-client-set-correct-id-uid-and-cruid-for-multiuser-automounts.patch new file mode 100644 index 0000000000..c7b30d1133 --- /dev/null +++ b/queue-5.15/smb-client-set-correct-id-uid-and-cruid-for-multiuser-automounts.patch @@ -0,0 +1,64 @@ +From stable+bounces-215924-greg=kroah.com@vger.kernel.org Thu Feb 12 09:51:18 2026 +From: Rahul Sharma +Date: Thu, 12 Feb 2026 16:50:30 +0800 +Subject: smb: client: set correct id, uid and cruid for multiuser automounts +To: gregkh@linuxfoundation.org, stable@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, Paulo Alcantara , Shane Nehring , Steve French , Rahul Sharma +Message-ID: <20260212085030.372707-1-black.hawk@163.com> + +From: Paulo Alcantara + +[ Upstream commit 4508ec17357094e2075f334948393ddedbb75157 ] + +When uid, gid and cruid are not specified, we need to dynamically +set them into the filesystem context used for automounting otherwise +they'll end up reusing the values from the parent mount. + +Fixes: 9fd29a5bae6e ("cifs: use fs_context for automounts") +Reported-by: Shane Nehring +Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2259257 +Cc: stable@vger.kernel.org # 6.2+ +Signed-off-by: Paulo Alcantara (Red Hat) +Signed-off-by: Steve French +[ The context change is due to the commit 561f82a3a24c +("smb: client: rename cifs_dfs_ref.c to namespace.c") and the commit +0a049935e47e ("smb: client: get rid of dfs naming in automount code") +in v6.6 which are irrelevant to the logic of this patch. ] +Signed-off-by: Rahul Sharma +Signed-off-by: Greg Kroah-Hartman +--- + fs/cifs/cifs_dfs_ref.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/fs/cifs/cifs_dfs_ref.c ++++ b/fs/cifs/cifs_dfs_ref.c +@@ -258,6 +258,21 @@ compose_mount_options_err: + goto compose_mount_options_out; + } + ++static void fs_context_set_ids(struct smb3_fs_context *ctx) ++{ ++ kuid_t uid = current_fsuid(); ++ kgid_t gid = current_fsgid(); ++ ++ if (ctx->multiuser) { ++ if (!ctx->uid_specified) ++ ctx->linux_uid = uid; ++ if (!ctx->gid_specified) ++ ctx->linux_gid = gid; ++ } ++ if (!ctx->cruid_specified) ++ ctx->cred_uid = uid; ++} ++ + /* + * Create a vfsmount that we can automount + */ +@@ -309,6 +324,7 @@ static struct vfsmount *cifs_dfs_do_auto + tmp.source = full_path; + tmp.UNC = tmp.prepath = NULL; + ++ fs_context_set_ids(&tmp); + rc = smb3_fs_context_dup(ctx, &tmp); + if (rc) { + mnt = ERR_PTR(rc); diff --git a/queue-5.15/smb-server-fix-leak-of-active_num_conn-in-ksmbd_tcp_new_connection.patch b/queue-5.15/smb-server-fix-leak-of-active_num_conn-in-ksmbd_tcp_new_connection.patch new file mode 100644 index 0000000000..fe1e93bbf8 --- /dev/null +++ b/queue-5.15/smb-server-fix-leak-of-active_num_conn-in-ksmbd_tcp_new_connection.patch @@ -0,0 +1,48 @@ +From stable+bounces-216246-greg=kroah.com@vger.kernel.org Fri Feb 13 16:09:01 2026 +From: Sasha Levin +Date: Fri, 13 Feb 2026 10:08:55 -0500 +Subject: smb: server: fix leak of active_num_conn in ksmbd_tcp_new_connection() +To: stable@vger.kernel.org +Cc: Henrique Carvalho , Namjae Jeon , Steve French , Sasha Levin +Message-ID: <20260213150855.3532387-1-sashal@kernel.org> + +From: Henrique Carvalho + +[ Upstream commit 77ffbcac4e569566d0092d5f22627dfc0896b553 ] + +On kthread_run() failure in ksmbd_tcp_new_connection(), the transport is +freed via free_transport(), which does not decrement active_num_conn, +leaking this counter. + +Replace free_transport() with ksmbd_tcp_disconnect(). + +Fixes: 0d0d4680db22e ("ksmbd: add max connections parameter") +Cc: stable@vger.kernel.org +Signed-off-by: Henrique Carvalho +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/ksmbd/transport_tcp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/ksmbd/transport_tcp.c ++++ b/fs/ksmbd/transport_tcp.c +@@ -41,6 +41,7 @@ static struct ksmbd_transport_ops ksmbd_ + + static void tcp_stop_kthread(struct task_struct *kthread); + static struct interface *alloc_iface(char *ifname); ++static void ksmbd_tcp_disconnect(struct ksmbd_transport *t); + + #define KSMBD_TRANS(t) (&(t)->transport) + #define TCP_TRANS(t) ((struct tcp_transport *)container_of(t, \ +@@ -207,7 +208,7 @@ static int ksmbd_tcp_new_connection(stru + if (IS_ERR(handler)) { + pr_err("cannot start conn thread\n"); + rc = PTR_ERR(handler); +- free_transport(t); ++ ksmbd_tcp_disconnect(KSMBD_TRANS(t)); + } + return rc; + -- 2.47.3