]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 30 Jul 2024 14:14:21 +0000 (16:14 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 30 Jul 2024 14:14:21 +0000 (16:14 +0200)
added patches:
bluetooth-btusb-add-realtek-rtl8852be-support-id-0x13d3-0x3591.patch
bluetooth-btusb-add-rtl8852be-device-0489-e125-to-device-tables.patch
lib-build_oid_registry-don-t-mention-the-full-path-of-the-script-in-output.patch
minmax-scsi-fix-mis-use-of-clamp-in-sr.c.patch
mm-mglru-fix-ineffective-protection-calculation.patch
nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch
pci-dpc-fix-use-after-free-on-concurrent-dpc-and-hot-removal.patch
pci-introduce-cleanup-helpers-for-device-reference-counts-and-locks.patch
video-logo-drop-full-path-of-the-input-filename-in-generated-file.patch
wifi-mac80211-track-capability-opmode-nss-separately.patch

queue-6.6/bluetooth-btusb-add-realtek-rtl8852be-support-id-0x13d3-0x3591.patch [new file with mode: 0644]
queue-6.6/bluetooth-btusb-add-rtl8852be-device-0489-e125-to-device-tables.patch [new file with mode: 0644]
queue-6.6/lib-build_oid_registry-don-t-mention-the-full-path-of-the-script-in-output.patch [new file with mode: 0644]
queue-6.6/minmax-scsi-fix-mis-use-of-clamp-in-sr.c.patch [new file with mode: 0644]
queue-6.6/mm-mglru-fix-ineffective-protection-calculation.patch [new file with mode: 0644]
queue-6.6/nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch [new file with mode: 0644]
queue-6.6/pci-dpc-fix-use-after-free-on-concurrent-dpc-and-hot-removal.patch [new file with mode: 0644]
queue-6.6/pci-introduce-cleanup-helpers-for-device-reference-counts-and-locks.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/video-logo-drop-full-path-of-the-input-filename-in-generated-file.patch [new file with mode: 0644]
queue-6.6/wifi-mac80211-track-capability-opmode-nss-separately.patch [new file with mode: 0644]

diff --git a/queue-6.6/bluetooth-btusb-add-realtek-rtl8852be-support-id-0x13d3-0x3591.patch b/queue-6.6/bluetooth-btusb-add-realtek-rtl8852be-support-id-0x13d3-0x3591.patch
new file mode 100644 (file)
index 0000000..20339c2
--- /dev/null
@@ -0,0 +1,65 @@
+From 473a89b4ed7fd52a419340f7c540d5c8fc96fc75 Mon Sep 17 00:00:00 2001
+From: WangYuli <wangyuli@uniontech.com>
+Date: Sat, 22 Jun 2024 12:09:59 +0800
+Subject: Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x13d3:0x3591
+
+From: WangYuli <wangyuli@uniontech.com>
+
+commit 473a89b4ed7fd52a419340f7c540d5c8fc96fc75 upstream.
+
+Add the support ID(0x13d3, 0x3591) to usb_device_id table for
+Realtek RTL8852BE.
+
+The device table is as follows:
+
+T:  Bus=01 Lev=02 Prnt=03 Port=00 Cnt=01 Dev#=  5 Spd=12   MxCh= 0
+D:  Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs=  1
+P:  Vendor=13d3 ProdID=3591 Rev= 0.00
+S:  Manufacturer=Realtek
+S:  Product=Bluetooth Radio
+S:  SerialNumber=00e04c000001
+C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=1ms
+E:  Ad=02(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms
+E:  Ad=82(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
+E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
+I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
+E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
+I:  If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
+I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
+I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
+I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: WangYuli <wangyuli@uniontech.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Erpeng Xu <xuerpeng@uniontech.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/btusb.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -551,6 +551,8 @@ static const struct usb_device_id quirks
+                                                    BTUSB_WIDEBAND_SPEECH },
+       { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK |
+                                                    BTUSB_WIDEBAND_SPEECH },
++      { USB_DEVICE(0x13d3, 0x3591), .driver_info = BTUSB_REALTEK |
++                                                   BTUSB_WIDEBAND_SPEECH },
+       { USB_DEVICE(0x0489, 0xe125), .driver_info = BTUSB_REALTEK |
+                                                    BTUSB_WIDEBAND_SPEECH },
diff --git a/queue-6.6/bluetooth-btusb-add-rtl8852be-device-0489-e125-to-device-tables.patch b/queue-6.6/bluetooth-btusb-add-rtl8852be-device-0489-e125-to-device-tables.patch
new file mode 100644 (file)
index 0000000..77e5725
--- /dev/null
@@ -0,0 +1,63 @@
+From 295ef07a9dae6182ad4b689aa8c6a7dbba21474c Mon Sep 17 00:00:00 2001
+From: Hilda Wu <hildawu@realtek.com>
+Date: Mon, 17 Jun 2024 17:05:18 +0800
+Subject: Bluetooth: btusb: Add RTL8852BE device 0489:e125 to device tables
+
+From: Hilda Wu <hildawu@realtek.com>
+
+commit 295ef07a9dae6182ad4b689aa8c6a7dbba21474c upstream.
+
+Add the support ID 0489:e125 to usb_device_id table for
+Realtek RTL8852B chip.
+
+The device info from /sys/kernel/debug/usb/devices as below.
+
+T:  Bus=01 Lev=01 Prnt=01 Port=07 Cnt=03 Dev#=  5 Spd=12   MxCh= 0
+D:  Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs=  1
+P:  Vendor=0489 ProdID=e125 Rev= 0.00
+S:  Manufacturer=Realtek
+S:  Product=Bluetooth Radio
+S:  SerialNumber=00e04c000001
+C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=1ms
+E:  Ad=02(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms
+E:  Ad=82(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
+E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
+I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
+E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
+I:  If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
+I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
+I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
+I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
+E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
+
+Signed-off-by: Hilda Wu <hildawu@realtek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Erpeng Xu <xuerpeng@uniontech.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/btusb.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -551,6 +551,8 @@ static const struct usb_device_id quirks
+                                                    BTUSB_WIDEBAND_SPEECH },
+       { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK |
+                                                    BTUSB_WIDEBAND_SPEECH },
++      { USB_DEVICE(0x0489, 0xe125), .driver_info = BTUSB_REALTEK |
++                                                   BTUSB_WIDEBAND_SPEECH },
+       /* Realtek Bluetooth devices */
+       { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),
diff --git a/queue-6.6/lib-build_oid_registry-don-t-mention-the-full-path-of-the-script-in-output.patch b/queue-6.6/lib-build_oid_registry-don-t-mention-the-full-path-of-the-script-in-output.patch
new file mode 100644 (file)
index 0000000..1c90492
--- /dev/null
@@ -0,0 +1,60 @@
+From 5ef6dc08cfde240b8c748733759185646e654570 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Wed, 13 Mar 2024 22:19:56 +0100
+Subject: lib/build_OID_registry: don't mention the full path of the script in output
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+commit 5ef6dc08cfde240b8c748733759185646e654570 upstream.
+
+This change strips the full path of the script generating
+lib/oid_registry_data.c to just lib/build_OID_registry.  The motivation
+for this change is Yocto emitting a build warning
+
+       File /usr/src/debug/linux-lxatac/6.7-r0/lib/oid_registry_data.c in package linux-lxatac-src contains reference to TMPDIR [buildpaths]
+
+So this change brings us one step closer to make the build result
+reproducible independent of the build path.
+
+Link: https://lkml.kernel.org/r/20240313211957.884561-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Cc: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ lib/build_OID_registry |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/lib/build_OID_registry
++++ b/lib/build_OID_registry
+@@ -8,6 +8,7 @@
+ #
+ use strict;
++use Cwd qw(abs_path);
+ my @names = ();
+ my @oids = ();
+@@ -17,6 +18,8 @@ if ($#ARGV != 1) {
+     exit(2);
+ }
++my $abs_srctree = abs_path($ENV{'srctree'});
++
+ #
+ # Open the file to read from
+ #
+@@ -35,7 +38,7 @@ close IN_FILE || die;
+ #
+ open C_FILE, ">$ARGV[1]" or die;
+ print C_FILE "/*\n";
+-print C_FILE " * Automatically generated by ", $0, ".  Do not edit\n";
++print C_FILE " * Automatically generated by ", $0 =~ s#^\Q$abs_srctree/\E##r, ".  Do not edit\n";
+ print C_FILE " */\n";
+ #
diff --git a/queue-6.6/minmax-scsi-fix-mis-use-of-clamp-in-sr.c.patch b/queue-6.6/minmax-scsi-fix-mis-use-of-clamp-in-sr.c.patch
new file mode 100644 (file)
index 0000000..be59a76
--- /dev/null
@@ -0,0 +1,48 @@
+From 9f499b8c791d2983c0a31a543c51d1b2f15e8755 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Sun, 28 Jul 2024 17:06:20 -0700
+Subject: minmax: scsi: fix mis-use of 'clamp()' in sr.c
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 9f499b8c791d2983c0a31a543c51d1b2f15e8755 upstream.
+
+While working on simplifying the minmax functions, and avoiding
+excessive macro expansion, it turns out that the sr.c use of the
+'clamp()' macro has the arguments the wrong way around.
+
+The clamp logic is
+
+       val = clamp(in, low, high);
+
+and it returns the input clamped to the low/high limits. But sr.c ddid
+
+       speed = clamp(0, speed, 0xffff / 177);
+
+which clamps the value '0' to the range '[speed, 0xffff / 177]' and ends
+up being nonsensical.
+
+Happily, I don't think anybody ever cared.
+
+Fixes: 9fad9d560af5 ("scsi: sr: Fix unintentional arithmetic wraparound")
+Cc: Justin Stitt <justinstitt@google.com>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/sr_ioctl.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/sr_ioctl.c
++++ b/drivers/scsi/sr_ioctl.c
+@@ -431,7 +431,7 @@ int sr_select_speed(struct cdrom_device_
+       struct packet_command cgc;
+       /* avoid exceeding the max speed or overflowing integer bounds */
+-      speed = clamp(0, speed, 0xffff / 177);
++      speed = clamp(speed, 0, 0xffff / 177);
+       if (speed == 0)
+               speed = 0xffff; /* set to max */
diff --git a/queue-6.6/mm-mglru-fix-ineffective-protection-calculation.patch b/queue-6.6/mm-mglru-fix-ineffective-protection-calculation.patch
new file mode 100644 (file)
index 0000000..ef58747
--- /dev/null
@@ -0,0 +1,184 @@
+From 30d77b7eef019fa4422980806e8b7cdc8674493e Mon Sep 17 00:00:00 2001
+From: Yu Zhao <yuzhao@google.com>
+Date: Fri, 12 Jul 2024 17:29:56 -0600
+Subject: mm/mglru: fix ineffective protection calculation
+
+From: Yu Zhao <yuzhao@google.com>
+
+commit 30d77b7eef019fa4422980806e8b7cdc8674493e upstream.
+
+mem_cgroup_calculate_protection() is not stateless and should only be used
+as part of a top-down tree traversal.  shrink_one() traverses the per-node
+memcg LRU instead of the root_mem_cgroup tree, and therefore it should not
+call mem_cgroup_calculate_protection().
+
+The existing misuse in shrink_one() can cause ineffective protection of
+sub-trees that are grandchildren of root_mem_cgroup.  Fix it by reusing
+lru_gen_age_node(), which already traverses the root_mem_cgroup tree, to
+calculate the protection.
+
+Previously lru_gen_age_node() opportunistically skips the first pass,
+i.e., when scan_control->priority is DEF_PRIORITY.  On the second pass,
+lruvec_is_sizable() uses appropriate scan_control->priority, set by
+set_initial_priority() from lru_gen_shrink_node(), to decide whether a
+memcg is too small to reclaim from.
+
+Now lru_gen_age_node() unconditionally traverses the root_mem_cgroup tree.
+So it should call set_initial_priority() upfront, to make sure
+lruvec_is_sizable() uses appropriate scan_control->priority on the first
+pass.  Otherwise, lruvec_is_reclaimable() can return false negatives and
+result in premature OOM kills when min_ttl_ms is used.
+
+Link: https://lkml.kernel.org/r/20240712232956.1427127-1-yuzhao@google.com
+Fixes: e4dde56cd208 ("mm: multi-gen LRU: per-node lru_gen_folio lists")
+Signed-off-by: Yu Zhao <yuzhao@google.com>
+Reported-by: T.J. Mercier <tjmercier@google.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/vmscan.c |   83 +++++++++++++++++++++++++++---------------------------------
+ 1 file changed, 38 insertions(+), 45 deletions(-)
+
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -4546,6 +4546,32 @@ done:
+  *                          working set protection
+  ******************************************************************************/
++static void set_initial_priority(struct pglist_data *pgdat, struct scan_control *sc)
++{
++      int priority;
++      unsigned long reclaimable;
++
++      if (sc->priority != DEF_PRIORITY || sc->nr_to_reclaim < MIN_LRU_BATCH)
++              return;
++      /*
++       * Determine the initial priority based on
++       * (total >> priority) * reclaimed_to_scanned_ratio = nr_to_reclaim,
++       * where reclaimed_to_scanned_ratio = inactive / total.
++       */
++      reclaimable = node_page_state(pgdat, NR_INACTIVE_FILE);
++      if (can_reclaim_anon_pages(NULL, pgdat->node_id, sc))
++              reclaimable += node_page_state(pgdat, NR_INACTIVE_ANON);
++
++      /* round down reclaimable and round up sc->nr_to_reclaim */
++      priority = fls_long(reclaimable) - 1 - fls_long(sc->nr_to_reclaim - 1);
++
++      /*
++       * The estimation is based on LRU pages only, so cap it to prevent
++       * overshoots of shrinker objects by large margins.
++       */
++      sc->priority = clamp(priority, DEF_PRIORITY / 2, DEF_PRIORITY);
++}
++
+ static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
+ {
+       int gen, type, zone;
+@@ -4579,19 +4605,17 @@ static bool lruvec_is_reclaimable(struct
+       struct mem_cgroup *memcg = lruvec_memcg(lruvec);
+       DEFINE_MIN_SEQ(lruvec);
+-      /* see the comment on lru_gen_folio */
+-      gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]);
+-      birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
+-
+-      if (time_is_after_jiffies(birth + min_ttl))
++      if (mem_cgroup_below_min(NULL, memcg))
+               return false;
+       if (!lruvec_is_sizable(lruvec, sc))
+               return false;
+-      mem_cgroup_calculate_protection(NULL, memcg);
++      /* see the comment on lru_gen_folio */
++      gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]);
++      birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
+-      return !mem_cgroup_below_min(NULL, memcg);
++      return time_is_before_jiffies(birth + min_ttl);
+ }
+ /* to protect the working set of the last N jiffies */
+@@ -4601,23 +4625,20 @@ static void lru_gen_age_node(struct pgli
+ {
+       struct mem_cgroup *memcg;
+       unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl);
++      bool reclaimable = !min_ttl;
+       VM_WARN_ON_ONCE(!current_is_kswapd());
+-      /* check the order to exclude compaction-induced reclaim */
+-      if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY)
+-              return;
++      set_initial_priority(pgdat, sc);
+       memcg = mem_cgroup_iter(NULL, NULL, NULL);
+       do {
+               struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
+-              if (lruvec_is_reclaimable(lruvec, sc, min_ttl)) {
+-                      mem_cgroup_iter_break(NULL, memcg);
+-                      return;
+-              }
++              mem_cgroup_calculate_protection(NULL, memcg);
+-              cond_resched();
++              if (!reclaimable)
++                      reclaimable = lruvec_is_reclaimable(lruvec, sc, min_ttl);
+       } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
+       /*
+@@ -4625,7 +4646,7 @@ static void lru_gen_age_node(struct pgli
+        * younger than min_ttl. However, another possibility is all memcgs are
+        * either too small or below min.
+        */
+-      if (mutex_trylock(&oom_lock)) {
++      if (!reclaimable && mutex_trylock(&oom_lock)) {
+               struct oom_control oc = {
+                       .gfp_mask = sc->gfp_mask,
+               };
+@@ -5424,8 +5445,7 @@ static int shrink_one(struct lruvec *lru
+       struct mem_cgroup *memcg = lruvec_memcg(lruvec);
+       struct pglist_data *pgdat = lruvec_pgdat(lruvec);
+-      mem_cgroup_calculate_protection(NULL, memcg);
+-
++      /* lru_gen_age_node() called mem_cgroup_calculate_protection() */
+       if (mem_cgroup_below_min(NULL, memcg))
+               return MEMCG_LRU_YOUNG;
+@@ -5565,33 +5585,6 @@ static void lru_gen_shrink_lruvec(struct
+ #endif
+-static void set_initial_priority(struct pglist_data *pgdat, struct scan_control *sc)
+-{
+-      int priority;
+-      unsigned long reclaimable;
+-      struct lruvec *lruvec = mem_cgroup_lruvec(NULL, pgdat);
+-
+-      if (sc->priority != DEF_PRIORITY || sc->nr_to_reclaim < MIN_LRU_BATCH)
+-              return;
+-      /*
+-       * Determine the initial priority based on
+-       * (total >> priority) * reclaimed_to_scanned_ratio = nr_to_reclaim,
+-       * where reclaimed_to_scanned_ratio = inactive / total.
+-       */
+-      reclaimable = node_page_state(pgdat, NR_INACTIVE_FILE);
+-      if (get_swappiness(lruvec, sc))
+-              reclaimable += node_page_state(pgdat, NR_INACTIVE_ANON);
+-
+-      /* round down reclaimable and round up sc->nr_to_reclaim */
+-      priority = fls_long(reclaimable) - 1 - fls_long(sc->nr_to_reclaim - 1);
+-
+-      /*
+-       * The estimation is based on LRU pages only, so cap it to prevent
+-       * overshoots of shrinker objects by large margins.
+-       */
+-      sc->priority = clamp(priority, DEF_PRIORITY / 2, DEF_PRIORITY);
+-}
+-
+ static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *sc)
+ {
+       struct blk_plug plug;
diff --git a/queue-6.6/nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch b/queue-6.6/nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch
new file mode 100644 (file)
index 0000000..6660c7e
--- /dev/null
@@ -0,0 +1,97 @@
+From 4811f7af6090e8f5a398fbdd766f903ef6c0d787 Mon Sep 17 00:00:00 2001
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Date: Thu, 25 Jul 2024 14:20:07 +0900
+Subject: nilfs2: handle inconsistent state in nilfs_btnode_create_block()
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+commit 4811f7af6090e8f5a398fbdd766f903ef6c0d787 upstream.
+
+Syzbot reported that a buffer state inconsistency was detected in
+nilfs_btnode_create_block(), triggering a kernel bug.
+
+It is not appropriate to treat this inconsistency as a bug; it can occur
+if the argument block address (the buffer index of the newly created
+block) is a virtual block number and has been reallocated due to
+corruption of the bitmap used to manage its allocation state.
+
+So, modify nilfs_btnode_create_block() and its callers to treat it as a
+possible filesystem error, rather than triggering a kernel bug.
+
+Link: https://lkml.kernel.org/r/20240725052007.4562-1-konishi.ryusuke@gmail.com
+Fixes: a60be987d45d ("nilfs2: B-tree node cache")
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Reported-by: syzbot+89cc4f2324ed37988b60@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=89cc4f2324ed37988b60
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nilfs2/btnode.c |   25 ++++++++++++++++++++-----
+ fs/nilfs2/btree.c  |    4 ++--
+ 2 files changed, 22 insertions(+), 7 deletions(-)
+
+--- a/fs/nilfs2/btnode.c
++++ b/fs/nilfs2/btnode.c
+@@ -51,12 +51,21 @@ nilfs_btnode_create_block(struct address
+       bh = nilfs_grab_buffer(inode, btnc, blocknr, BIT(BH_NILFS_Node));
+       if (unlikely(!bh))
+-              return NULL;
++              return ERR_PTR(-ENOMEM);
+       if (unlikely(buffer_mapped(bh) || buffer_uptodate(bh) ||
+                    buffer_dirty(bh))) {
+-              brelse(bh);
+-              BUG();
++              /*
++               * The block buffer at the specified new address was already
++               * in use.  This can happen if it is a virtual block number
++               * and has been reallocated due to corruption of the bitmap
++               * used to manage its allocation state (if not, the buffer
++               * clearing of an abandoned b-tree node is missing somewhere).
++               */
++              nilfs_error(inode->i_sb,
++                          "state inconsistency probably due to duplicate use of b-tree node block address %llu (ino=%lu)",
++                          (unsigned long long)blocknr, inode->i_ino);
++              goto failed;
+       }
+       memset(bh->b_data, 0, i_blocksize(inode));
+       bh->b_bdev = inode->i_sb->s_bdev;
+@@ -67,6 +76,12 @@ nilfs_btnode_create_block(struct address
+       unlock_page(bh->b_page);
+       put_page(bh->b_page);
+       return bh;
++
++failed:
++      unlock_page(bh->b_page);
++      put_page(bh->b_page);
++      brelse(bh);
++      return ERR_PTR(-EIO);
+ }
+ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
+@@ -217,8 +232,8 @@ retry:
+       }
+       nbh = nilfs_btnode_create_block(btnc, newkey);
+-      if (!nbh)
+-              return -ENOMEM;
++      if (IS_ERR(nbh))
++              return PTR_ERR(nbh);
+       BUG_ON(nbh == obh);
+       ctxt->newbh = nbh;
+--- a/fs/nilfs2/btree.c
++++ b/fs/nilfs2/btree.c
+@@ -63,8 +63,8 @@ static int nilfs_btree_get_new_block(con
+       struct buffer_head *bh;
+       bh = nilfs_btnode_create_block(btnc, ptr);
+-      if (!bh)
+-              return -ENOMEM;
++      if (IS_ERR(bh))
++              return PTR_ERR(bh);
+       set_buffer_nilfs_volatile(bh);
+       *bhp = bh;
diff --git a/queue-6.6/pci-dpc-fix-use-after-free-on-concurrent-dpc-and-hot-removal.patch b/queue-6.6/pci-dpc-fix-use-after-free-on-concurrent-dpc-and-hot-removal.patch
new file mode 100644 (file)
index 0000000..8dfaa6d
--- /dev/null
@@ -0,0 +1,87 @@
+From 11a1f4bc47362700fcbde717292158873fb847ed Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Tue, 18 Jun 2024 12:54:55 +0200
+Subject: PCI/DPC: Fix use-after-free on concurrent DPC and hot-removal
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 11a1f4bc47362700fcbde717292158873fb847ed upstream.
+
+Keith reports a use-after-free when a DPC event occurs concurrently to
+hot-removal of the same portion of the hierarchy:
+
+The dpc_handler() awaits readiness of the secondary bus below the
+Downstream Port where the DPC event occurred.  To do so, it polls the
+config space of the first child device on the secondary bus.  If that
+child device is concurrently removed, accesses to its struct pci_dev
+cause the kernel to oops.
+
+That's because pci_bridge_wait_for_secondary_bus() neglects to hold a
+reference on the child device.  Before v6.3, the function was only
+called on resume from system sleep or on runtime resume.  Holding a
+reference wasn't necessary back then because the pciehp IRQ thread
+could never run concurrently.  (On resume from system sleep, IRQs are
+not enabled until after the resume_noirq phase.  And runtime resume is
+always awaited before a PCI device is removed.)
+
+However starting with v6.3, pci_bridge_wait_for_secondary_bus() is also
+called on a DPC event.  Commit 53b54ad074de ("PCI/DPC: Await readiness
+of secondary bus after reset"), which introduced that, failed to
+appreciate that pci_bridge_wait_for_secondary_bus() now needs to hold a
+reference on the child device because dpc_handler() and pciehp may
+indeed run concurrently.  The commit was backported to v5.10+ stable
+kernels, so that's the oldest one affected.
+
+Add the missing reference acquisition.
+
+Abridged stack trace:
+
+  BUG: unable to handle page fault for address: 00000000091400c0
+  CPU: 15 PID: 2464 Comm: irq/53-pcie-dpc 6.9.0
+  RIP: pci_bus_read_config_dword+0x17/0x50
+  pci_dev_wait()
+  pci_bridge_wait_for_secondary_bus()
+  dpc_reset_link()
+  pcie_do_recovery()
+  dpc_handler()
+
+Fixes: 53b54ad074de ("PCI/DPC: Await readiness of secondary bus after reset")
+Closes: https://lore.kernel.org/r/20240612181625.3604512-3-kbusch@meta.com/
+Link: https://lore.kernel.org/linux-pci/8e4bcd4116fd94f592f2bf2749f168099c480ddf.1718707743.git.lukas@wunner.de
+Reported-by: Keith Busch <kbusch@kernel.org>
+Tested-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Reviewed-by: Keith Busch <kbusch@kernel.org>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Cc: stable@vger.kernel.org # v5.10+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/pci.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -5123,7 +5123,7 @@ static int pci_bus_max_d3cold_delay(cons
+  */
+ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type)
+ {
+-      struct pci_dev *child;
++      struct pci_dev *child __free(pci_dev_put) = NULL;
+       int delay;
+       if (pci_dev_is_disconnected(dev))
+@@ -5152,8 +5152,8 @@ int pci_bridge_wait_for_secondary_bus(st
+               return 0;
+       }
+-      child = list_first_entry(&dev->subordinate->devices, struct pci_dev,
+-                               bus_list);
++      child = pci_dev_get(list_first_entry(&dev->subordinate->devices,
++                                           struct pci_dev, bus_list));
+       up_read(&pci_bus_sem);
+       /*
diff --git a/queue-6.6/pci-introduce-cleanup-helpers-for-device-reference-counts-and-locks.patch b/queue-6.6/pci-introduce-cleanup-helpers-for-device-reference-counts-and-locks.patch
new file mode 100644 (file)
index 0000000..de3881a
--- /dev/null
@@ -0,0 +1,88 @@
+From ced085ef369af7a2b6da962ec2fbd01339f60693 Mon Sep 17 00:00:00 2001
+From: Ira Weiny <ira.weiny@intel.com>
+Date: Wed, 20 Dec 2023 16:17:35 -0800
+Subject: PCI: Introduce cleanup helpers for device reference counts and locks
+
+From: Ira Weiny <ira.weiny@intel.com>
+
+commit ced085ef369af7a2b6da962ec2fbd01339f60693 upstream.
+
+The "goto error" pattern is notorious for introducing subtle resource
+leaks. Use the new cleanup.h helpers for PCI device reference counts and
+locks.
+
+Similar to the new put_device() and device_lock() cleanup helpers,
+__free(put_device) and guard(device), define the same for PCI devices,
+__free(pci_dev_put) and guard(pci_dev).  These helpers eliminate the
+need for "goto free;" and "goto unlock;" patterns. For example, A
+'struct pci_dev *' instance declared as:
+
+    struct pci_dev *pdev __free(pci_dev_put) = NULL;
+
+...will automatically call pci_dev_put() if @pdev is non-NULL when @pdev
+goes out of scope (automatic variable scope). If a function wants to
+invoke pci_dev_put() on error, but return @pdev on success, it can do:
+
+    return no_free_ptr(pdev);
+
+...or:
+
+    return_ptr(pdev);
+
+For potential cleanup opportunity there are 587 open-coded calls to
+pci_dev_put() in the kernel with 65 instances within 10 lines of a goto
+statement with the CXL driver threatening to add another one.
+
+The guard() helper holds the associated lock for the remainder of the
+current scope in which it was invoked. So, for example:
+
+    func(...)
+    {
+        if (...) {
+            ...
+            guard(pci_dev); /* pci_dev_lock() invoked here */
+            ...
+        } /* <- implied pci_dev_unlock() triggered here */
+    }
+
+There are 15 invocations of pci_dev_unlock() in the kernel with 5
+instances within 10 lines of a goto statement. Again, the CXL driver is
+threatening to add another.
+
+Introduce these helpers to preclude the addition of new more error prone
+goto put; / goto unlock; sequences. For now, these helpers are used in
+drivers/cxl/pci.c to allow ACPI error reports to be fed back into the
+CXL driver associated with the PCI device identified in the report.
+
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Ira Weiny <ira.weiny@intel.com>
+Link: https://lore.kernel.org/r/20231220-cxl-cper-v5-8-1bb8a4ca2c7a@intel.com
+[djbw: rewrite changelog]
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/pci.h |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -1146,6 +1146,7 @@ int pci_get_interrupt_pin(struct pci_dev
+ u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp);
+ struct pci_dev *pci_dev_get(struct pci_dev *dev);
+ void pci_dev_put(struct pci_dev *dev);
++DEFINE_FREE(pci_dev_put, struct pci_dev *, if (_T) pci_dev_put(_T))
+ void pci_remove_bus(struct pci_bus *b);
+ void pci_stop_and_remove_bus_device(struct pci_dev *dev);
+ void pci_stop_and_remove_bus_device_locked(struct pci_dev *dev);
+@@ -1851,6 +1852,7 @@ void pci_cfg_access_unlock(struct pci_de
+ void pci_dev_lock(struct pci_dev *dev);
+ int pci_dev_trylock(struct pci_dev *dev);
+ void pci_dev_unlock(struct pci_dev *dev);
++DEFINE_GUARD(pci_dev, struct pci_dev *, pci_dev_lock(_T), pci_dev_unlock(_T))
+ /*
+  * PCI domain support.  Sometimes called PCI segment (eg by ACPI),
index c69903525c49fa64c5bb185b16093f336cd902f9..d2afed473706f947341c403d0c22fd616af7cb45 100644 (file)
@@ -502,3 +502,13 @@ drm-etnaviv-don-t-block-scheduler-when-gpu-is-still-active.patch
 drm-panfrost-mark-simple_ondemand-governor-as-softdep.patch
 rbd-rename-rbd_lock_state_releasing-and-releasing_wait.patch
 rbd-don-t-assume-rbd_lock_state_locked-for-exclusive-mappings.patch
+lib-build_oid_registry-don-t-mention-the-full-path-of-the-script-in-output.patch
+video-logo-drop-full-path-of-the-input-filename-in-generated-file.patch
+bluetooth-btusb-add-rtl8852be-device-0489-e125-to-device-tables.patch
+bluetooth-btusb-add-realtek-rtl8852be-support-id-0x13d3-0x3591.patch
+minmax-scsi-fix-mis-use-of-clamp-in-sr.c.patch
+nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch
+mm-mglru-fix-ineffective-protection-calculation.patch
+wifi-mac80211-track-capability-opmode-nss-separately.patch
+pci-introduce-cleanup-helpers-for-device-reference-counts-and-locks.patch
+pci-dpc-fix-use-after-free-on-concurrent-dpc-and-hot-removal.patch
diff --git a/queue-6.6/video-logo-drop-full-path-of-the-input-filename-in-generated-file.patch b/queue-6.6/video-logo-drop-full-path-of-the-input-filename-in-generated-file.patch
new file mode 100644 (file)
index 0000000..e959c59
--- /dev/null
@@ -0,0 +1,36 @@
+From fb3b9c2d217f1f51fffe19fc0f4eaf55e2d4ea4f Mon Sep 17 00:00:00 2001
+From: Lucas Stach <l.stach@pengutronix.de>
+Date: Wed, 10 Apr 2024 15:41:21 +0200
+Subject: video: logo: Drop full path of the input filename in generated file
+
+From: Lucas Stach <l.stach@pengutronix.de>
+
+commit fb3b9c2d217f1f51fffe19fc0f4eaf55e2d4ea4f upstream.
+
+Avoid this Yocto build warning to make build reproducible:
+
+    WARNING: linux-foo-6.8-r0 do_package_qa: QA Issue:
+    File /usr/src/debug/linux-foo/6.8-r0/drivers/video/logo/logo_linux_clut224.c
+    in package linux-foo-src contains reference to TMPDIR
+
+Helge modified the patch to drop the whole line.
+
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Cc: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/logo/pnmtologo.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/video/logo/pnmtologo.c
++++ b/drivers/video/logo/pnmtologo.c
+@@ -235,8 +235,6 @@ static void write_header(void)
+       fputs("/*\n", out);
+       fputs(" *  DO NOT EDIT THIS FILE!\n", out);
+       fputs(" *\n", out);
+-      fprintf(out, " *  It was automatically generated from %s\n", filename);
+-      fputs(" *\n", out);
+       fprintf(out, " *  Linux logo %s\n", logoname);
+       fputs(" */\n\n", out);
+       fputs("#include <linux/linux_logo.h>\n\n", out);
diff --git a/queue-6.6/wifi-mac80211-track-capability-opmode-nss-separately.patch b/queue-6.6/wifi-mac80211-track-capability-opmode-nss-separately.patch
new file mode 100644 (file)
index 0000000..f0bc825
--- /dev/null
@@ -0,0 +1,191 @@
+From a8bca3e9371dc5e276af4168be099b2a05554c2a Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Wed, 28 Feb 2024 12:01:57 +0100
+Subject: wifi: mac80211: track capability/opmode NSS separately
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit a8bca3e9371dc5e276af4168be099b2a05554c2a upstream.
+
+We're currently tracking rx_nss for each station, and that
+is meant to be initialized to the capability NSS and later
+reduced by the operating mode notification NSS.
+
+However, we're mixing up capabilities and operating mode
+NSS in the same variable. This forces us to recalculate
+the NSS capability on operating mode notification RX,
+which is a bit strange; due to the previous fix I had to
+never keep rx_nss as zero, it also means that the capa is
+never taken into account properly.
+
+Fix all this by storing the capability value, that can be
+recalculated unconditionally whenever needed, and storing
+the operating mode notification NSS separately, taking it
+into account when assigning the final rx_nss value.
+
+Cc: stable@vger.kernel.org
+Fixes: dd6c064cfc3f ("wifi: mac80211: set station RX-NSS on reconfig")
+Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://msgid.link/20240228120157.0e1c41924d1d.I0acaa234e0267227b7e3ef81a59117c8792116bc@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+[Fixed trivial merge conflict in copyright year net/mac80211/sta_info.h]
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/cfg.c         |    2 -
+ net/mac80211/ieee80211_i.h |    2 -
+ net/mac80211/rate.c        |    2 -
+ net/mac80211/sta_info.h    |    6 ++++-
+ net/mac80211/vht.c         |   46 +++++++++++++++++++++------------------------
+ 5 files changed, 30 insertions(+), 28 deletions(-)
+
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1887,7 +1887,7 @@ static int sta_link_apply_parameters(str
+                                             sband->band);
+       }
+-      ieee80211_sta_set_rx_nss(link_sta);
++      ieee80211_sta_init_nss(link_sta);
+       return ret;
+ }
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -2150,7 +2150,7 @@ enum ieee80211_sta_rx_bandwidth
+ ieee80211_sta_cap_rx_bw(struct link_sta_info *link_sta);
+ enum ieee80211_sta_rx_bandwidth
+ ieee80211_sta_cur_vht_bw(struct link_sta_info *link_sta);
+-void ieee80211_sta_set_rx_nss(struct link_sta_info *link_sta);
++void ieee80211_sta_init_nss(struct link_sta_info *link_sta);
+ enum ieee80211_sta_rx_bandwidth
+ ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width);
+ enum nl80211_chan_width
+--- a/net/mac80211/rate.c
++++ b/net/mac80211/rate.c
+@@ -37,7 +37,7 @@ void rate_control_rate_init(struct sta_i
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_chanctx_conf *chanctx_conf;
+-      ieee80211_sta_set_rx_nss(&sta->deflink);
++      ieee80211_sta_init_nss(&sta->deflink);
+       if (!ref)
+               return;
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -3,7 +3,7 @@
+  * Copyright 2002-2005, Devicescape Software, Inc.
+  * Copyright 2013-2014  Intel Mobile Communications GmbH
+  * Copyright(c) 2015-2017 Intel Deutschland GmbH
+- * Copyright(c) 2020-2022 Intel Corporation
++ * Copyright(c) 2020-2024 Intel Corporation
+  */
+ #ifndef STA_INFO_H
+@@ -485,6 +485,8 @@ struct ieee80211_fragment_cache {
+  *    same for non-MLD STA. This is used as key for searching link STA
+  * @link_id: Link ID uniquely identifying the link STA. This is 0 for non-MLD
+  *    and set to the corresponding vif LinkId for MLD STA
++ * @op_mode_nss: NSS limit as set by operating mode notification, or 0
++ * @capa_nss: NSS limit as determined by local and peer capabilities
+  * @link_hash_node: hash node for rhashtable
+  * @sta: Points to the STA info
+  * @gtk: group keys negotiated with this station, if any
+@@ -521,6 +523,8 @@ struct link_sta_info {
+       u8 addr[ETH_ALEN];
+       u8 link_id;
++      u8 op_mode_nss, capa_nss;
++
+       struct rhlist_head link_hash_node;
+       struct sta_info *sta;
+--- a/net/mac80211/vht.c
++++ b/net/mac80211/vht.c
+@@ -4,7 +4,7 @@
+  *
+  * Portions of this file
+  * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
+- * Copyright (C) 2018 - 2023 Intel Corporation
++ * Copyright (C) 2018 - 2024 Intel Corporation
+  */
+ #include <linux/ieee80211.h>
+@@ -541,15 +541,11 @@ ieee80211_sta_cur_vht_bw(struct link_sta
+       return bw;
+ }
+-void ieee80211_sta_set_rx_nss(struct link_sta_info *link_sta)
++void ieee80211_sta_init_nss(struct link_sta_info *link_sta)
+ {
+       u8 ht_rx_nss = 0, vht_rx_nss = 0, he_rx_nss = 0, eht_rx_nss = 0, rx_nss;
+       bool support_160;
+-      /* if we received a notification already don't overwrite it */
+-      if (link_sta->pub->rx_nss)
+-              return;
+-
+       if (link_sta->pub->eht_cap.has_eht) {
+               int i;
+               const u8 *rx_nss_mcs = (void *)&link_sta->pub->eht_cap.eht_mcs_nss_supp;
+@@ -627,7 +623,15 @@ void ieee80211_sta_set_rx_nss(struct lin
+       rx_nss = max(vht_rx_nss, ht_rx_nss);
+       rx_nss = max(he_rx_nss, rx_nss);
+       rx_nss = max(eht_rx_nss, rx_nss);
+-      link_sta->pub->rx_nss = max_t(u8, 1, rx_nss);
++      rx_nss = max_t(u8, 1, rx_nss);
++      link_sta->capa_nss = rx_nss;
++
++      /* that shouldn't be set yet, but we can handle it anyway */
++      if (link_sta->op_mode_nss)
++              link_sta->pub->rx_nss =
++                      min_t(u8, rx_nss, link_sta->op_mode_nss);
++      else
++              link_sta->pub->rx_nss = rx_nss;
+ }
+ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
+@@ -637,7 +641,7 @@ u32 __ieee80211_vht_handle_opmode(struct
+       enum ieee80211_sta_rx_bandwidth new_bw;
+       struct sta_opmode_info sta_opmode = {};
+       u32 changed = 0;
+-      u8 nss, cur_nss;
++      u8 nss;
+       /* ignore - no support for BF yet */
+       if (opmode & IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF)
+@@ -647,23 +651,17 @@ u32 __ieee80211_vht_handle_opmode(struct
+       nss >>= IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
+       nss += 1;
+-      if (link_sta->pub->rx_nss != nss) {
+-              cur_nss = link_sta->pub->rx_nss;
+-              /* Reset rx_nss and call ieee80211_sta_set_rx_nss() which
+-               * will set the same to max nss value calculated based on capability.
+-               */
+-              link_sta->pub->rx_nss = 0;
+-              ieee80211_sta_set_rx_nss(link_sta);
+-              /* Do not allow an nss change to rx_nss greater than max_nss
+-               * negotiated and capped to APs capability during association.
+-               */
+-              if (nss <= link_sta->pub->rx_nss) {
+-                      link_sta->pub->rx_nss = nss;
+-                      sta_opmode.rx_nss = nss;
+-                      changed |= IEEE80211_RC_NSS_CHANGED;
+-                      sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
++      if (link_sta->op_mode_nss != nss) {
++              if (nss <= link_sta->capa_nss) {
++                      link_sta->op_mode_nss = nss;
++
++                      if (nss != link_sta->pub->rx_nss) {
++                              link_sta->pub->rx_nss = nss;
++                              changed |= IEEE80211_RC_NSS_CHANGED;
++                              sta_opmode.rx_nss = link_sta->pub->rx_nss;
++                              sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
++                      }
+               } else {
+-                      link_sta->pub->rx_nss = cur_nss;
+                       pr_warn_ratelimited("Ignoring NSS change in VHT Operating Mode Notification from %pM with invalid nss %d",
+                                           link_sta->pub->addr, nss);
+               }