--- /dev/null
+From 38e818718c5e04961eea0fa8feff3f100ce40408 Mon Sep 17 00:00:00 2001
+From: Boris Burkov <boris@bur.io>
+Date: Wed, 1 Oct 2025 17:20:22 -0700
+Subject: btrfs: fix racy bitfield write in btrfs_clear_space_info_full()
+
+From: Boris Burkov <boris@bur.io>
+
+commit 38e818718c5e04961eea0fa8feff3f100ce40408 upstream.
+
+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 <wqu@suse.com>
+Signed-off-by: Boris Burkov <boris@bur.io>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+[ The context change is due to the commit cc0517fe779f
+ ("btrfs: tweak extent/chunk allocation for space_info sub-space")
+ in v6.16 which is irrelevant to the logic of this patch. ]
+Signed-off-by: Rahul Sharma <black.hawk@163.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/block-group.c | 6 +++---
+ fs/btrfs/space-info.c | 22 +++++++++++-----------
+ fs/btrfs/space-info.h | 6 +++---
+ 3 files changed, 17 insertions(+), 17 deletions(-)
+
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -3924,7 +3924,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);
+ }
+@@ -3973,7 +3973,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 {
+@@ -3983,7 +3983,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
+@@ -179,7 +179,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;
+ }
+
+ /*
+@@ -360,7 +360,7 @@ void btrfs_add_bg_to_space_info(struct b
+ found->bytes_readonly += block_group->bytes_super;
+ btrfs_space_info_update_bytes_zone_unusable(info, found, block_group->zone_unusable);
+ if (block_group->length > 0)
+- found->full = 0;
++ found->full = false;
+ btrfs_try_granting_tickets(info, found);
+ spin_unlock(&found->lock);
+
+@@ -1116,7 +1116,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;
+ }
+@@ -1128,7 +1128,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;
+ }
+@@ -1171,7 +1171,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;
+@@ -1333,7 +1333,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;
+ }
+@@ -1344,7 +1344,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;
+ }
+@@ -1361,7 +1361,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;
+ }
+@@ -1378,7 +1378,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;
+ }
+@@ -1394,7 +1394,7 @@ static void btrfs_async_reclaim_data_spa
+
+ aborted_fs:
+ maybe_fail_all_tickets(fs_info, space_info);
+- space_info->flush = 0;
++ space_info->flush = false;
+ spin_unlock(&space_info->lock);
+ }
+
+@@ -1719,7 +1719,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
+@@ -109,11 +109,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 */
--- /dev/null
+From stable+bounces-216275-greg=kroah.com@vger.kernel.org Fri Feb 13 17:45:14 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 11:45:08 -0500
+Subject: bus: fsl-mc: fix use-after-free in driver_override_show()
+To: stable@vger.kernel.org
+Cc: Gui-Dong Han <hanguidong02@gmail.com>, Ioana Ciornei <ioana.ciornei@nxp.com>, "Christophe Leroy (CS GROUP)" <chleroy@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260213164508.3564699-2-sashal@kernel.org>
+
+From: Gui-Dong Han <hanguidong02@gmail.com>
+
+[ 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 <hanguidong02@gmail.com>
+Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
+Link: https://lore.kernel.org/r/20251202174438.12658-1-hanguidong02@gmail.com
+Signed-off-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -201,8 +201,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);
+
--- /dev/null
+From stable+bounces-216274-greg=kroah.com@vger.kernel.org Fri Feb 13 17:45:13 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 11:45:07 -0500
+Subject: bus: fsl-mc: Replace snprintf and sprintf with sysfs_emit in sysfs show functions
+To: stable@vger.kernel.org
+Cc: Chelsy Ratnawat <chelsyratnawat2001@gmail.com>, Ioana Ciornei <ioana.ciornei@nxp.com>, Christophe Leroy <christophe.leroy@csgroup.eu>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260213164508.3564699-1-sashal@kernel.org>
+
+From: Chelsy Ratnawat <chelsyratnawat2001@gmail.com>
+
+[ 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 <chelsyratnawat2001@gmail.com>
+Acked-by: Ioana Ciornei <ioana.ciornei@nxp.com>
+Link: https://lore.kernel.org/r/20250822124339.1739290-1-chelsyratnawat2001@gmail.com
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Stable-dep-of: 148891e95014 ("bus: fsl-mc: fix use-after-free in driver_override_show()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -175,8 +175,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);
+
+@@ -202,7 +202,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);
+
--- /dev/null
+From florian.fainelli@broadcom.com Fri Feb 13 18:57:04 2026
+From: Florian Fainelli <florian.fainelli@broadcom.com>
+Date: Fri, 13 Feb 2026 09:56:59 -0800
+Subject: cacheinfo: Decrement refcount in cache_setup_of_node()
+To: stable@vger.kernel.org
+Cc: Pierre Gondois <pierre.gondois@arm.com>, Sudeep Holla <sudeep.holla@arm.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Florian Fainelli <florian.fainelli@broadcom.com>, "Rafael J. Wysocki" <rafael@kernel.org>, linux-kernel@vger.kernel.org (open list)
+Message-ID: <20260213175700.1964980-2-florian.fainelli@broadcom.com>
+
+From: Pierre Gondois <pierre.gondois@arm.com>
+
+commit 3da72e18371c41a6f6f96b594854b178168c7757 upstream
+
+Refcounts to DT nodes are only incremented in the function
+and never decremented. Decrease the refcounts when necessary.
+
+Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
+Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
+Link: https://lore.kernel.org/r/20221026185954.991547-1-pierre.gondois@arm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/cacheinfo.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+--- a/drivers/base/cacheinfo.c
++++ b/drivers/base/cacheinfo.c
+@@ -195,7 +195,7 @@ static void cache_of_set_props(struct ca
+
+ static int cache_setup_of_node(unsigned int cpu)
+ {
+- struct device_node *np;
++ struct device_node *np, *prev;
+ struct cacheinfo *this_leaf;
+ unsigned int index = 0;
+
+@@ -205,19 +205,24 @@ static int cache_setup_of_node(unsigned
+ return -ENOENT;
+ }
+
++ prev = np;
++
+ while (index < cache_leaves(cpu)) {
+ this_leaf = per_cpu_cacheinfo_idx(cpu, index);
+- if (this_leaf->level != 1)
++ if (this_leaf->level != 1) {
+ np = of_find_next_cache_node(np);
+- else
+- np = of_node_get(np);/* cpu node itself */
+- if (!np)
+- break;
++ of_node_put(prev);
++ prev = np;
++ if (!np)
++ break;
++ }
+ cache_of_set_props(this_leaf, np);
+ this_leaf->fw_token = np;
+ index++;
+ }
+
++ of_node_put(np);
++
+ if (index != cache_leaves(cpu)) /* not all OF nodes populated */
+ return -ENOENT;
+
--- /dev/null
+From florian.fainelli@broadcom.com Fri Feb 13 18:57:05 2026
+From: Florian Fainelli <florian.fainelli@broadcom.com>
+Date: Fri, 13 Feb 2026 09:57:00 -0800
+Subject: cacheinfo: Remove of_node_put() for fw_token
+To: stable@vger.kernel.org
+Cc: Pierre Gondois <pierre.gondois@arm.com>, Geert Uytterhoeven <geert@linux-m68k.org>, Marek Szyprowski <m.szyprowski@samsung.com>, Geert Uytterhoeven <geert+renesas@glider.be>, Sudeep Holla <sudeep.holla@arm.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Florian Fainelli <florian.fainelli@broadcom.com>, "Rafael J. Wysocki" <rafael@kernel.org>, linux-kernel@vger.kernel.org (open list)
+Message-ID: <20260213175700.1964980-3-florian.fainelli@broadcom.com>
+
+From: Pierre Gondois <pierre.gondois@arm.com>
+
+commit 2613cc29c5723881ca603b1a3b50f0107010d5d6 upstream
+
+fw_token is used for DT/ACPI systems to identify CPUs sharing caches.
+For DT based systems, fw_token is set to a pointer to a DT node.
+
+commit 3da72e18371c ("cacheinfo: Decrement refcount in
+cache_setup_of_node()")
+doesn't increment the refcount of fw_token anymore in
+cache_setup_of_node(). fw_token is indeed used as a token and not
+as a (struct device_node*), so no reference to fw_token should be
+kept.
+
+However, [1] is triggered when hotplugging a CPU multiple times
+since cache_shared_cpu_map_remove() decrements the refcount to
+fw_token at each CPU unplugging, eventually reaching 0.
+
+Remove of_node_put() for fw_token in cache_shared_cpu_map_remove().
+
+[1]
+------------[ cut here ]------------
+refcount_t: saturated; leaking memory.
+WARNING: CPU: 4 PID: 32 at lib/refcount.c:22 refcount_warn_saturate (lib/refcount.c:22 (discriminator 3))
+Modules linked in:
+CPU: 4 PID: 32 Comm: cpuhp/4 Tainted: G W 6.1.0-rc1-14091-g9fdf2ca7b9c8 #76
+Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform, BIOS EDK II Oct 31 2022
+pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : refcount_warn_saturate (lib/refcount.c:22 (discriminator 3))
+lr : refcount_warn_saturate (lib/refcount.c:22 (discriminator 3))
+[...]
+Call trace:
+[...]
+of_node_release (drivers/of/dynamic.c:335)
+kobject_put (lib/kobject.c:677 lib/kobject.c:704 ./include/linux/kref.h:65 lib/kobject.c:721)
+of_node_put (drivers/of/dynamic.c:49)
+free_cache_attributes.part.0 (drivers/base/cacheinfo.c:712)
+cacheinfo_cpu_pre_down (drivers/base/cacheinfo.c:718)
+cpuhp_invoke_callback (kernel/cpu.c:247 (discriminator 4))
+cpuhp_thread_fun (kernel/cpu.c:785)
+smpboot_thread_fn (kernel/smpboot.c:164 (discriminator 3))
+kthread (kernel/kthread.c:376)
+ret_from_fork (arch/arm64/kernel/entry.S:861)
+---[ end trace 0000000000000000 ]---
+
+Fixes: 3da72e18371c ("cacheinfo: Decrement refcount in cache_setup_of_node()")
+Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Tested-by: Sudeep Holla <sudeep.holla@arm.com>
+Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
+Link: https://lore.kernel.org/r/20221116094958.2141072-1-pierre.gondois@arm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/cacheinfo.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/base/cacheinfo.c
++++ b/drivers/base/cacheinfo.c
+@@ -409,8 +409,6 @@ static void cache_shared_cpu_map_remove(
+ }
+ }
+ }
+- if (of_have_populated_dt())
+- of_node_put(this_leaf->fw_token);
+ }
+
+ /* cpu is no longer populated in the shared map */
--- /dev/null
+From adcbadfd8e05d3558c9cfaa783f17c645181165f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Thu, 29 Jan 2026 09:22:27 +0100
+Subject: net: sfp: Fix quirk for Ubiquiti U-Fiber Instant SFP module
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <kabel@kernel.org>
+
+commit adcbadfd8e05d3558c9cfaa783f17c645181165f upstream.
+
+Commit fd580c9830316eda ("net: sfp: augment SFP parsing with
+phy_interface_t bitmap") did not add augumentation for the interface
+bitmap in the quirk for Ubiquiti U-Fiber Instant.
+
+The subsequent commit f81fa96d8a6c7a77 ("net: phylink: use
+phy_interface_t bitmaps for optical modules") then changed phylink code
+for selection of SFP interface: instead of using link mode bitmap, the
+interface bitmap is used, and the fastest interface mode supported by
+both SFP module and MAC is chosen.
+
+Since the interface bitmap contains also modes faster than 1000base-x,
+this caused a regression wherein this module stopped working
+out-of-the-box.
+
+Fix this.
+
+Fixes: fd580c9830316eda ("net: sfp: augment SFP parsing with phy_interface_t bitmap")
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://patch.msgid.link/20260129082227.17443-1-kabel@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/phy/sfp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -376,6 +376,8 @@ static void sfp_quirk_ubnt_uf_instant(co
+ */
+ linkmode_zero(modes);
+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, modes);
++ phy_interface_zero(interfaces);
++ __set_bit(PHY_INTERFACE_MODE_1000BASEX, interfaces);
+ }
+
+ #define SFP_QUIRK(_v, _p, _m, _f) \
--- /dev/null
+From stable+bounces-216463-greg=kroah.com@vger.kernel.org Sat Feb 14 03:23:22 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 21:23:13 -0500
+Subject: PCI: endpoint: Automatically create a function specific attributes group
+To: stable@vger.kernel.org
+Cc: Damien Le Moal <dlemoal@kernel.org>, Lorenzo Pieralisi <lpieralisi@kernel.org>, Bjorn Helgaas <bhelgaas@google.com>, Manivannan Sadhasivam <mani@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260214022316.4103092-1-sashal@kernel.org>
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+[ 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 <dlemoal@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
+Stable-dep-of: 7c5c7d06bd1f ("PCI: endpoint: Avoid creating sub-groups asynchronously")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/PCI/endpoint/pci-ntb-howto.rst | 11 ++----
+ Documentation/PCI/endpoint/pci-vntb-howto.rst | 13 +++-----
+ drivers/pci/endpoint/pci-ep-cfs.c | 42 ++++++++++++--------------
+ 3 files changed, 29 insertions(+), 37 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/Documentation/PCI/endpoint/pci-vntb-howto.rst
++++ b/Documentation/PCI/endpoint/pci-vntb-howto.rst
+@@ -84,13 +84,10 @@ commands can be used::
+ # echo 0x1957 > functions/pci_epf_vntb/func1/vendorid
+ # echo 0x0809 > functions/pci_epf_vntb/func1/deviceid
+
+-In order to configure NTB specific attributes, a new sub-directory to func1
+-should be created::
+-
+- # mkdir functions/pci_epf_vntb/func1/pci_epf_vntb.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_vntb/func1/pci_epf_vntb.0/
+ db_count mw1 mw2 mw3 mw4 num_mws
+@@ -103,7 +100,7 @@ A sample configuration for NTB function
+ # echo 1 > functions/pci_epf_vntb/func1/pci_epf_vntb.0/num_mws
+ # echo 0x100000 > functions/pci_epf_vntb/func1/pci_epf_vntb.0/mw1
+
+-A sample configuration for virtual NTB driver for virutal PCI bus::
++A sample configuration for virtual NTB driver for virtual PCI bus::
+
+ # echo 0x1957 > functions/pci_epf_vntb/func1/pci_epf_vntb.0/vntb_vid
+ # echo 0x080A > functions/pci_epf_vntb/func1/pci_epf_vntb.0/vntb_pid
+--- 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;
+@@ -502,34 +503,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;
+@@ -547,6 +543,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,
--- /dev/null
+From stable+bounces-216465-greg=kroah.com@vger.kernel.org Sat Feb 14 03:23:23 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 21:23:15 -0500
+Subject: PCI: endpoint: Avoid creating sub-groups asynchronously
+To: stable@vger.kernel.org
+Cc: Liu Song <liu.song13@zte.com.cn>, Manivannan Sadhasivam <mani@kernel.org>, Bjorn Helgaas <bhelgaas@google.com>, stable@kernel.org, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260214022316.4103092-3-sashal@kernel.org>
+
+From: Liu Song <liu.song13@zte.com.cn>
+
+[ 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 <liu.song13@zte.com.cn>
+[mani: slightly reworded the description and added stable list]
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: stable@kernel.org
+Link: https://patch.msgid.link/20250710143845409gLM6JdlwPhlHG9iX3F6jK@zte.com.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+ }
+@@ -522,15 +521,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");
+@@ -589,9 +586,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;
+
--- /dev/null
+From stable+bounces-216464-greg=kroah.com@vger.kernel.org Sat Feb 14 03:23:23 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 21:23:14 -0500
+Subject: PCI: endpoint: Remove unused field in struct pci_epf_group
+To: stable@vger.kernel.org
+Cc: "Christophe JAILLET" <christophe.jaillet@wanadoo.fr>, "Krzysztof Wilczyński" <kwilczynski@kernel.org>, "Bjorn Helgaas" <bhelgaas@google.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260214022316.4103092-2-sashal@kernel.org>
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ 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 <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Stable-dep-of: 7c5c7d06bd1f ("PCI: endpoint: Avoid creating sub-groups asynchronously")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
--- /dev/null
+From stable+bounces-216460-greg=kroah.com@vger.kernel.org Sat Feb 14 02:49:24 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 20:49:14 -0500
+Subject: scsi: qla2xxx: Fix bsg_done() causing double free
+To: stable@vger.kernel.org
+Cc: Anil Gurumurthy <agurumurthy@marvell.com>, Nilesh Javali <njavali@marvell.com>, Himanshu Madhani <hmadhani2024@gmail.com>, "Martin K. Petersen" <martin.petersen@oracle.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260214014914.3893755-1-sashal@kernel.org>
+
+From: Anil Gurumurthy <agurumurthy@marvell.com>
+
+[ 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] <TASK>
+[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 <agurumurthy@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Reviewed-by: Himanshu Madhani <hmadhani2024@gmail.com>
+Link: https://patch.msgid.link/20251210101604.431868-12-njavali@marvell.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/qla2xxx/qla_bsg.c | 28 +++++++++++++++++-----------
+ 1 file changed, 17 insertions(+), 11 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;
+ }
+
+@@ -2612,8 +2613,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;
+ }
+@@ -2702,8 +2704,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:
+@@ -2802,8 +2805,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);
+@@ -2864,8 +2868,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;
+ }
+@@ -3240,7 +3245,8 @@ int qla2x00_mailbox_passthru(struct bsg_
+
+ bsg_job->reply_len = sizeof(*bsg_job->reply);
+ bsg_reply->result = DID_OK << 16;
+- 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(req_data);
+
--- /dev/null
+From stable+bounces-216251-greg=kroah.com@vger.kernel.org Fri Feb 13 16:43:48 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 10:43:32 -0500
+Subject: scsi: qla2xxx: Free sp in error path to fix system crash
+To: stable@vger.kernel.org
+Cc: Anil Gurumurthy <agurumurthy@marvell.com>, Nilesh Javali <njavali@marvell.com>, Himanshu Madhani <hmadhani2024@gmail.com>, "Martin K. Petersen" <martin.petersen@oracle.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260213154332.3544750-3-sashal@kernel.org>
+
+From: Anil Gurumurthy <agurumurthy@marvell.com>
+
+[ 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] <TASK>
+[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] </TASK>
+[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] <TASK>
+[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 <agurumurthy@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Reviewed-by: Himanshu Madhani <hmadhani2024@gmail.com>
+Link: https://patch.msgid.link/20251210101604.431868-9-njavali@marvell.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -3919,8 +3919,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)
--- /dev/null
+From stable+bounces-216250-greg=kroah.com@vger.kernel.org Fri Feb 13 16:44:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 10:43:31 -0500
+Subject: scsi: qla2xxx: Reduce fabric scan duplicate code
+To: stable@vger.kernel.org
+Cc: Quinn Tran <qutran@marvell.com>, Nilesh Javali <njavali@marvell.com>, Himanshu Madhani <himanshu.madhani@oracle.com>, "Martin K. Petersen" <martin.petersen@oracle.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260213154332.3544750-2-sashal@kernel.org>
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ 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 <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Link: https://lore.kernel.org/r/20240710171057.35066-10-njavali@marvell.com
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 7adbd2b78090 ("scsi: qla2xxx: Free sp in error path to fix system crash")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -3273,11 +3273,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;
+@@ -3503,9 +3512,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
+@@ -736,9 +736,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
+@@ -3488,7 +3488,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;
+@@ -3700,14 +3700,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;
+@@ -3717,37 +3714,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;
+@@ -3766,85 +3741,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) {
+@@ -3868,8 +3841,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);
+@@ -3894,28 +3866,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) {
+@@ -3926,127 +3900,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)
+@@ -4055,22 +3918,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) {
+@@ -4086,7 +3948,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;
+@@ -4094,7 +3956,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) *
+@@ -4106,7 +3967,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;
+@@ -4126,35 +3987,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) {
+@@ -4187,7 +4108,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);
+@@ -4198,6 +4119,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
+@@ -6444,10 +6444,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
+@@ -5522,15 +5522,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);
--- /dev/null
+From stable+bounces-216249-greg=kroah.com@vger.kernel.org Fri Feb 13 16:44:02 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 10:43:30 -0500
+Subject: scsi: qla2xxx: Remove dead code (GNN ID)
+To: stable@vger.kernel.org
+Cc: Quinn Tran <qutran@marvell.com>, Nilesh Javali <njavali@marvell.com>, Himanshu Madhani <himanshu.madhani@oracle.com>, "Martin K. Petersen" <martin.petersen@oracle.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260213154332.3544750-1-sashal@kernel.org>
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 87f6dafd50fb6d7214c32596a11b983138b09123 ]
+
+Remove stale/unused code (GNN ID).
+
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 7adbd2b78090 ("scsi: qla2xxx: Free sp in error path to fix system crash")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -2499,7 +2499,6 @@ struct ct_sns_desc {
+
+ enum discovery_state {
+ DSC_DELETED,
+- DSC_GNN_ID,
+ DSC_GNL,
+ DSC_LOGIN_PEND,
+ DSC_LOGIN_FAILED,
+@@ -2712,7 +2711,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",
+@@ -3508,7 +3506,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
+@@ -739,9 +739,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
+@@ -4216,116 +4216,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
+@@ -1723,12 +1723,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
+@@ -5532,9 +5532,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;
scsi-qla2xxx-delay-module-unload-while-fabric-scan-in-progress.patch
scsi-qla2xxx-query-fw-again-before-proceeding-with-login.patch
gpio-omap-do-not-register-driver-in-probe.patch
+btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_info_full.patch
+net-sfp-fix-quirk-for-ubiquiti-u-fiber-instant-sfp-module.patch
+smb-client-set-correct-id-uid-and-cruid-for-multiuser-automounts.patch
+scsi-qla2xxx-fix-bsg_done-causing-double-free.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
+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-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
+cacheinfo-decrement-refcount-in-cache_setup_of_node.patch
+cacheinfo-remove-of_node_put-for-fw_token.patch
--- /dev/null
+From 4508ec17357094e2075f334948393ddedbb75157 Mon Sep 17 00:00:00 2001
+From: Paulo Alcantara <pc@manguebit.com>
+Date: Sun, 11 Feb 2024 20:19:30 -0300
+Subject: smb: client: set correct id, uid and cruid for multiuser automounts
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+commit 4508ec17357094e2075f334948393ddedbb75157 upstream.
+
+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 <snehring@iastate.edu>
+Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2259257
+Cc: stable@vger.kernel.org # 6.2+
+Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+[ 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 <black.hawk@163.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/cifs_dfs_ref.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/fs/smb/client/cifs_dfs_ref.c
++++ b/fs/smb/client/cifs_dfs_ref.c
+@@ -283,6 +283,21 @@ out:
+ return rc;
+ }
+
++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
+ */
+@@ -333,6 +348,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);