]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Mon, 22 Jan 2024 22:48:41 +0000 (17:48 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 22 Jan 2024 22:48:41 +0000 (17:48 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
78 files changed:
queue-5.15/apparmor-avoid-crash-when-parsed-profile-name-is-emp.patch [new file with mode: 0644]
queue-5.15/arm-9330-1-davinci-also-select-pinctrl.patch [new file with mode: 0644]
queue-5.15/bpf-reject-variable-offset-alu-on-ptr_to_flow_keys.patch [new file with mode: 0644]
queue-5.15/ethtool-netlink-add-missing-ethnl_ops_begin-complete.patch [new file with mode: 0644]
queue-5.15/i2c-s3c24xx-fix-read-transfers-in-polling-mode.patch [new file with mode: 0644]
queue-5.15/i2c-s3c24xx-fix-transferring-more-than-one-message-i.patch [new file with mode: 0644]
queue-5.15/iio-adc-ad9467-benefit-from-devm_clk_get_enabled-to-.patch [new file with mode: 0644]
queue-5.15/iio-adc-ad9467-don-t-ignore-error-codes.patch [new file with mode: 0644]
queue-5.15/iio-adc-ad9467-fix-reset-gpio-handling.patch [new file with mode: 0644]
queue-5.15/iio-adc-ad9467-fix-scale-setting.patch [new file with mode: 0644]
queue-5.15/ipv6-mcast-fix-data-race-in-ipv6_mc_down-mld_ifc_wor.patch [new file with mode: 0644]
queue-5.15/ipvs-avoid-stat-macros-calls-from-preemptible-contex.patch [new file with mode: 0644]
queue-5.15/kdb-fix-a-potential-buffer-overflow-in-kdb_local.patch [new file with mode: 0644]
queue-5.15/leds-aw2013-select-missing-dependency-regmap_i2c.patch [new file with mode: 0644]
queue-5.15/libapi-add-missing-linux-types.h-header-to-get-the-_.patch [new file with mode: 0644]
queue-5.15/mfd-intel-lpss-fix-the-fractional-clock-divider-flag.patch [new file with mode: 0644]
queue-5.15/mfd-syscon-fix-null-pointer-dereference-in-of_syscon.patch [new file with mode: 0644]
queue-5.15/mips-alchemy-fix-an-out-of-bound-access-in-db1200_de.patch [new file with mode: 0644]
queue-5.15/mips-alchemy-fix-an-out-of-bound-access-in-db1550_de.patch [new file with mode: 0644]
queue-5.15/mips-dmi-fix-early-remap-on-mips32.patch [new file with mode: 0644]
queue-5.15/mips-fix-incorrect-max_low_pfn-adjustment.patch [new file with mode: 0644]
queue-5.15/mlxsw-spectrum-use-bitmap_zalloc-when-applicable.patch [new file with mode: 0644]
queue-5.15/mlxsw-spectrum_acl_erp-fix-error-flow-of-pool-alloca.patch [new file with mode: 0644]
queue-5.15/mlxsw-spectrum_acl_tcam-add-missing-mutex_destroy.patch [new file with mode: 0644]
queue-5.15/mlxsw-spectrum_acl_tcam-fix-stack-corruption.patch [new file with mode: 0644]
queue-5.15/mlxsw-spectrum_acl_tcam-make-fini-symmetric-to-init.patch [new file with mode: 0644]
queue-5.15/mlxsw-spectrum_acl_tcam-reorder-functions-to-avoid-f.patch [new file with mode: 0644]
queue-5.15/mptcp-drop-unused-sk-in-mptcp_get_options.patch [new file with mode: 0644]
queue-5.15/mptcp-mptcp_parse_option-fix-for-mptcpopt_mp_join.patch [new file with mode: 0644]
queue-5.15/mptcp-strict-validation-before-using-mp_opt-hmac.patch [new file with mode: 0644]
queue-5.15/mptcp-use-option_mptcp_mpj_syn-in-subflow_check_req.patch [new file with mode: 0644]
queue-5.15/mptcp-use-option_mptcp_mpj_synack-in-subflow_finish_.patch [new file with mode: 0644]
queue-5.15/net-dsa-vsc73xx-add-null-pointer-check-to-vsc73xx_gp.patch [new file with mode: 0644]
queue-5.15/net-ethernet-ti-am65-cpsw-fix-max-mtu-to-fit-etherne.patch [new file with mode: 0644]
queue-5.15/net-phy-micrel-populate-.soft_reset-for-ksz9131.patch [new file with mode: 0644]
queue-5.15/net-qualcomm-rmnet-fix-global-oob-in-rmnet_policy.patch [new file with mode: 0644]
queue-5.15/net-ravb-fix-dma_addr_t-truncation-in-error-case.patch [new file with mode: 0644]
queue-5.15/net-stmmac-ethtool-fixed-calltrace-caused-by-unbalan.patch [new file with mode: 0644]
queue-5.15/netfilter-nf_tables-do-not-allow-mismatch-field-size.patch [new file with mode: 0644]
queue-5.15/netfilter-nf_tables-memcg-accounting-for-dynamically.patch [new file with mode: 0644]
queue-5.15/netfilter-nf_tables-reject-invalid-set-policy.patch [new file with mode: 0644]
queue-5.15/netfilter-nf_tables-reject-nft_set_concat-with-not-f.patch [new file with mode: 0644]
queue-5.15/netfilter-nf_tables-skip-dead-set-elements-in-netlin.patch [new file with mode: 0644]
queue-5.15/netfilter-nft_connlimit-move-stateful-fields-out-of-.patch [new file with mode: 0644]
queue-5.15/netfilter-nft_last-move-stateful-fields-out-of-expre.patch [new file with mode: 0644]
queue-5.15/netfilter-nft_limit-do-not-ignore-unsupported-flags.patch [new file with mode: 0644]
queue-5.15/netfilter-nft_limit-move-stateful-fields-out-of-expr.patch [new file with mode: 0644]
queue-5.15/netfilter-nft_limit-rename-stateful-structure.patch [new file with mode: 0644]
queue-5.15/netfilter-nft_quota-move-stateful-fields-out-of-expr.patch [new file with mode: 0644]
queue-5.15/nvmet-re-fix-tracing-strncpy-warning.patch [new file with mode: 0644]
queue-5.15/nvmet-tcp-fix-a-crash-in-nvmet_req_complete.patch [new file with mode: 0644]
queue-5.15/nvmet-tcp-fix-a-kernel-panic-when-host-sends-an-inva.patch [new file with mode: 0644]
queue-5.15/nvmet-tcp-fix-the-h2c-expected-pdu-len-calculation.patch [new file with mode: 0644]
queue-5.15/pci-keystone-fix-race-condition-when-initializing-ph.patch [new file with mode: 0644]
queue-5.15/perf-env-avoid-recursively-taking-env-bpf_progs.lock.patch [new file with mode: 0644]
queue-5.15/perf-genelf-set-elf-program-header-addresses-properl.patch [new file with mode: 0644]
queue-5.15/power-supply-bq256xx-fix-some-problem-in-bq256xx_hw_.patch [new file with mode: 0644]
queue-5.15/power-supply-cw2015-correct-time_to_empty-units-in-s.patch [new file with mode: 0644]
queue-5.15/r8152-choose-our-usb-config-with-choose_configuratio.patch [new file with mode: 0644]
queue-5.15/riscv-check-if-the-code-to-patch-lies-in-the-exit-se.patch [new file with mode: 0644]
queue-5.15/riscv-fix-module_alloc-that-did-not-reset-the-linear.patch [new file with mode: 0644]
queue-5.15/s390-pci-fix-max-size-calculation-in-zpci_memcpy_toi.patch [new file with mode: 0644]
queue-5.15/selftests-mlxsw-qos_pfc-adjust-the-test-to-support-8.patch [new file with mode: 0644]
queue-5.15/selftests-sgx-fix-uninitialized-pointer-dereference-.patch [new file with mode: 0644]
queue-5.15/selftests-sgx-skip-non-x86_64-platform.patch [new file with mode: 0644]
queue-5.15/serial-8250-omap-don-t-skip-resource-freeing-if-pm_r.patch [new file with mode: 0644]
queue-5.15/serial-imx-correct-clock-error-message-in-function-p.patch [new file with mode: 0644]
queue-5.15/serial-imx-fix-tx-statemachine-deadlock.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/software-node-let-args-be-null-in-software_node_get_.patch [new file with mode: 0644]
queue-5.15/tty-change-tty_write_lock-s-ndelay-parameter-to-bool.patch [new file with mode: 0644]
queue-5.15/tty-don-t-check-for-signal_pending-in-send_break.patch [new file with mode: 0644]
queue-5.15/tty-early-return-from-send_break-on-tty_driver_hardw.patch [new file with mode: 0644]
queue-5.15/tty-use-if-in-send_break-instead-of-goto.patch [new file with mode: 0644]
queue-5.15/usb-cdc-acm-return-correct-error-code-on-unsupported.patch [new file with mode: 0644]
queue-5.15/usb-core-allow-subclassed-usb-drivers-to-override-us.patch [new file with mode: 0644]
queue-5.15/usb-core-fix-crash-w-usb_choose_configuration-if-no-.patch [new file with mode: 0644]
queue-5.15/usb-xhci-mtk-fix-a-short-packet-issue-of-gen1-isoc-i.patch [new file with mode: 0644]

diff --git a/queue-5.15/apparmor-avoid-crash-when-parsed-profile-name-is-emp.patch b/queue-5.15/apparmor-avoid-crash-when-parsed-profile-name-is-emp.patch
new file mode 100644 (file)
index 0000000..171f6bf
--- /dev/null
@@ -0,0 +1,82 @@
+From d984a956cb7d8532c3c080a95f472202eb81d153 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Dec 2023 19:07:43 +0300
+Subject: apparmor: avoid crash when parsed profile name is empty
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit 55a8210c9e7d21ff2644809699765796d4bfb200 ]
+
+When processing a packed profile in unpack_profile() described like
+
+ "profile :ns::samba-dcerpcd /usr/lib*/samba/{,samba/}samba-dcerpcd {...}"
+
+a string ":samba-dcerpcd" is unpacked as a fully-qualified name and then
+passed to aa_splitn_fqname().
+
+aa_splitn_fqname() treats ":samba-dcerpcd" as only containing a namespace.
+Thus it returns NULL for tmpname, meanwhile tmpns is non-NULL. Later
+aa_alloc_profile() crashes as the new profile name is NULL now.
+
+general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN NOPTI
+KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
+CPU: 6 PID: 1657 Comm: apparmor_parser Not tainted 6.7.0-rc2-dirty #16
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014
+RIP: 0010:strlen+0x1e/0xa0
+Call Trace:
+ <TASK>
+ ? strlen+0x1e/0xa0
+ aa_policy_init+0x1bb/0x230
+ aa_alloc_profile+0xb1/0x480
+ unpack_profile+0x3bc/0x4960
+ aa_unpack+0x309/0x15e0
+ aa_replace_profiles+0x213/0x33c0
+ policy_update+0x261/0x370
+ profile_replace+0x20e/0x2a0
+ vfs_write+0x2af/0xe00
+ ksys_write+0x126/0x250
+ do_syscall_64+0x46/0xf0
+ entry_SYSCALL_64_after_hwframe+0x6e/0x76
+ </TASK>
+---[ end trace 0000000000000000 ]---
+RIP: 0010:strlen+0x1e/0xa0
+
+It seems such behaviour of aa_splitn_fqname() is expected and checked in
+other places where it is called (e.g. aa_remove_profiles). Well, there
+is an explicit comment "a ns name without a following profile is allowed"
+inside.
+
+AFAICS, nothing can prevent unpacked "name" to be in form like
+":samba-dcerpcd" - it is passed from userspace.
+
+Deny the whole profile set replacement in such case and inform user with
+EPROTO and an explaining message.
+
+Found by Linux Verification Center (linuxtesting.org).
+
+Fixes: 04dc715e24d0 ("apparmor: audit policy ns specified in policy load")
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/policy_unpack.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
+index 5f758b289ace..d1a385b44d63 100644
+--- a/security/apparmor/policy_unpack.c
++++ b/security/apparmor/policy_unpack.c
+@@ -696,6 +696,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
+       tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len);
+       if (tmpns) {
++              if (!tmpname) {
++                      info = "empty profile name";
++                      goto fail;
++              }
+               *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL);
+               if (!*ns_name) {
+                       info = "out of memory";
+-- 
+2.43.0
+
diff --git a/queue-5.15/arm-9330-1-davinci-also-select-pinctrl.patch b/queue-5.15/arm-9330-1-davinci-also-select-pinctrl.patch
new file mode 100644 (file)
index 0000000..20d679a
--- /dev/null
@@ -0,0 +1,48 @@
+From a79294635448770b224c736daeab5d2b90b0e335 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Nov 2023 01:36:03 +0100
+Subject: ARM: 9330/1: davinci: also select PINCTRL
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit f54e8634d1366926c807e2af6125b33cff555fa7 ]
+
+kconfig warns when PINCTRL_SINGLE is selected but PINCTRL is not
+set, so also set PINCTRL for ARCH_DAVINCI. This prevents a
+kconfig/build warning:
+
+   WARNING: unmet direct dependencies detected for PINCTRL_SINGLE
+     Depends on [n]: PINCTRL [=n] && OF [=y] && HAS_IOMEM [=y]
+     Selected by [y]:
+     - ARCH_DAVINCI [=y] && ARCH_MULTI_V5 [=y]
+
+Closes: lore.kernel.org/r/202311070548.0f6XfBrh-lkp@intel.com
+
+Fixes: f962396ce292 ("ARM: davinci: support multiplatform build for ARM v5")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reported-by: kernel test robot <lkp@intel.com>
+Cc: Bartosz Golaszewski <brgl@bgdev.pl>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: patches@armlinux.org.uk
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-davinci/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
+index 01684347da9b..889f3b9255c7 100644
+--- a/arch/arm/mach-davinci/Kconfig
++++ b/arch/arm/mach-davinci/Kconfig
+@@ -10,6 +10,7 @@ menuconfig ARCH_DAVINCI
+       select PM_GENERIC_DOMAINS_OF if PM && OF
+       select REGMAP_MMIO
+       select RESET_CONTROLLER
++      select PINCTRL
+       select PINCTRL_SINGLE
+ if ARCH_DAVINCI
+-- 
+2.43.0
+
diff --git a/queue-5.15/bpf-reject-variable-offset-alu-on-ptr_to_flow_keys.patch b/queue-5.15/bpf-reject-variable-offset-alu-on-ptr_to_flow_keys.patch
new file mode 100644 (file)
index 0000000..e2e7a4a
--- /dev/null
@@ -0,0 +1,88 @@
+From 3d91f20874201cbadc3bd23aec5502831360c0ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jan 2024 09:20:27 +0100
+Subject: bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS
+
+From: Hao Sun <sunhao.th@gmail.com>
+
+[ Upstream commit 22c7fa171a02d310e3a3f6ed46a698ca8a0060ed ]
+
+For PTR_TO_FLOW_KEYS, check_flow_keys_access() only uses fixed off
+for validation. However, variable offset ptr alu is not prohibited
+for this ptr kind. So the variable offset is not checked.
+
+The following prog is accepted:
+
+  func#0 @0
+  0: R1=ctx() R10=fp0
+  0: (bf) r6 = r1                       ; R1=ctx() R6_w=ctx()
+  1: (79) r7 = *(u64 *)(r6 +144)        ; R6_w=ctx() R7_w=flow_keys()
+  2: (b7) r8 = 1024                     ; R8_w=1024
+  3: (37) r8 /= 1                       ; R8_w=scalar()
+  4: (57) r8 &= 1024                    ; R8_w=scalar(smin=smin32=0,
+  smax=umax=smax32=umax32=1024,var_off=(0x0; 0x400))
+  5: (0f) r7 += r8
+  mark_precise: frame0: last_idx 5 first_idx 0 subseq_idx -1
+  mark_precise: frame0: regs=r8 stack= before 4: (57) r8 &= 1024
+  mark_precise: frame0: regs=r8 stack= before 3: (37) r8 /= 1
+  mark_precise: frame0: regs=r8 stack= before 2: (b7) r8 = 1024
+  6: R7_w=flow_keys(smin=smin32=0,smax=umax=smax32=umax32=1024,var_off
+  =(0x0; 0x400)) R8_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=1024,
+  var_off=(0x0; 0x400))
+  6: (79) r0 = *(u64 *)(r7 +0)          ; R0_w=scalar()
+  7: (95) exit
+
+This prog loads flow_keys to r7, and adds the variable offset r8
+to r7, and finally causes out-of-bounds access:
+
+  BUG: unable to handle page fault for address: ffffc90014c80038
+  [...]
+  Call Trace:
+   <TASK>
+   bpf_dispatcher_nop_func include/linux/bpf.h:1231 [inline]
+   __bpf_prog_run include/linux/filter.h:651 [inline]
+   bpf_prog_run include/linux/filter.h:658 [inline]
+   bpf_prog_run_pin_on_cpu include/linux/filter.h:675 [inline]
+   bpf_flow_dissect+0x15f/0x350 net/core/flow_dissector.c:991
+   bpf_prog_test_run_flow_dissector+0x39d/0x620 net/bpf/test_run.c:1359
+   bpf_prog_test_run kernel/bpf/syscall.c:4107 [inline]
+   __sys_bpf+0xf8f/0x4560 kernel/bpf/syscall.c:5475
+   __do_sys_bpf kernel/bpf/syscall.c:5561 [inline]
+   __se_sys_bpf kernel/bpf/syscall.c:5559 [inline]
+   __x64_sys_bpf+0x73/0xb0 kernel/bpf/syscall.c:5559
+   do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+   do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:83
+   entry_SYSCALL_64_after_hwframe+0x63/0x6b
+
+Fix this by rejecting ptr alu with variable offset on flow_keys.
+Applying the patch rejects the program with "R7 pointer arithmetic
+on flow_keys prohibited".
+
+Fixes: d58e468b1112 ("flow_dissector: implements flow dissector BPF hook")
+Signed-off-by: Hao Sun <sunhao.th@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Yonghong Song <yonghong.song@linux.dev>
+Link: https://lore.kernel.org/bpf/20240115082028.9992-1-sunhao.th@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index c2ecf349523d..88a468cc0510 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -7295,6 +7295,10 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
+       }
+       switch (base_type(ptr_reg->type)) {
++      case PTR_TO_FLOW_KEYS:
++              if (known)
++                      break;
++              fallthrough;
+       case CONST_PTR_TO_MAP:
+               /* smin_val represents the known value */
+               if (known && smin_val == 0 && opcode == BPF_ADD)
+-- 
+2.43.0
+
diff --git a/queue-5.15/ethtool-netlink-add-missing-ethnl_ops_begin-complete.patch b/queue-5.15/ethtool-netlink-add-missing-ethnl_ops_begin-complete.patch
new file mode 100644 (file)
index 0000000..f196280
--- /dev/null
@@ -0,0 +1,64 @@
+From c8b6efc9b995f506d2b8efe04a26427ee43d4a2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 13:03:14 +0100
+Subject: ethtool: netlink: Add missing ethnl_ops_begin/complete
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ludvig Pärsson <ludvig.parsson@axis.com>
+
+[ Upstream commit f1172f3ee3a98754d95b968968920a7d03fdebcc ]
+
+Accessing an ethernet device that is powered off or clock gated might
+cause the CPU to hang. Add ethnl_ops_begin/complete in
+ethnl_set_features() to protect against this.
+
+Fixes: 0980bfcd6954 ("ethtool: set netdev features with FEATURES_SET request")
+Signed-off-by: Ludvig Pärsson <ludvig.parsson@axis.com>
+Link: https://lore.kernel.org/r/20240117-etht2-v2-1-1a96b6e8c650@axis.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/features.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/features.c b/net/ethtool/features.c
+index 1c9f4df273bd..faccab84d865 100644
+--- a/net/ethtool/features.c
++++ b/net/ethtool/features.c
+@@ -235,17 +235,20 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
+       dev = req_info.dev;
+       rtnl_lock();
++      ret = ethnl_ops_begin(dev);
++      if (ret < 0)
++              goto out_rtnl;
+       ethnl_features_to_bitmap(old_active, dev->features);
+       ethnl_features_to_bitmap(old_wanted, dev->wanted_features);
+       ret = ethnl_parse_bitset(req_wanted, req_mask, NETDEV_FEATURE_COUNT,
+                                tb[ETHTOOL_A_FEATURES_WANTED],
+                                netdev_features_strings, info->extack);
+       if (ret < 0)
+-              goto out_rtnl;
++              goto out_ops;
+       if (ethnl_bitmap_to_features(req_mask) & ~NETIF_F_ETHTOOL_BITS) {
+               GENL_SET_ERR_MSG(info, "attempt to change non-ethtool features");
+               ret = -EINVAL;
+-              goto out_rtnl;
++              goto out_ops;
+       }
+       /* set req_wanted bits not in req_mask from old_wanted */
+@@ -282,6 +285,8 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
+       if (mod)
+               netdev_features_change(dev);
++out_ops:
++      ethnl_ops_complete(dev);
+ out_rtnl:
+       rtnl_unlock();
+       dev_put(dev);
+-- 
+2.43.0
+
diff --git a/queue-5.15/i2c-s3c24xx-fix-read-transfers-in-polling-mode.patch b/queue-5.15/i2c-s3c24xx-fix-read-transfers-in-polling-mode.patch
new file mode 100644 (file)
index 0000000..078c53f
--- /dev/null
@@ -0,0 +1,50 @@
+From 69a7483b1c6999a4b6246f3a6f9b8bbe4ea338f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Nov 2023 17:43:52 +0100
+Subject: i2c: s3c24xx: fix read transfers in polling mode
+
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+
+[ Upstream commit 0d9cf23ed55d7ba3ab26d617a3ae507863674c8f ]
+
+To properly handle read transfers in polling mode, no waiting for the ACK
+state is needed as it will never come. Just wait a bit to ensure start
+state is on the bus and continue processing next bytes.
+
+Fixes: 117053f77a5a ("i2c: s3c2410: Add polling mode support")
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Reviewed-by: Chanho Park <chanho61.park@samsung.com>
+Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-s3c2410.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
+index b49a1b170bb2..9a6fbb38a5ba 100644
+--- a/drivers/i2c/busses/i2c-s3c2410.c
++++ b/drivers/i2c/busses/i2c-s3c2410.c
+@@ -220,8 +220,17 @@ static bool is_ack(struct s3c24xx_i2c *i2c)
+       int tries;
+       for (tries = 50; tries; --tries) {
+-              if (readl(i2c->regs + S3C2410_IICCON)
+-                      & S3C2410_IICCON_IRQPEND) {
++              unsigned long tmp = readl(i2c->regs + S3C2410_IICCON);
++
++              if (!(tmp & S3C2410_IICCON_ACKEN)) {
++                      /*
++                       * Wait a bit for the bus to stabilize,
++                       * delay estimated experimentally.
++                       */
++                      usleep_range(100, 200);
++                      return true;
++              }
++              if (tmp & S3C2410_IICCON_IRQPEND) {
+                       if (!(readl(i2c->regs + S3C2410_IICSTAT)
+                               & S3C2410_IICSTAT_LASTBIT))
+                               return true;
+-- 
+2.43.0
+
diff --git a/queue-5.15/i2c-s3c24xx-fix-transferring-more-than-one-message-i.patch b/queue-5.15/i2c-s3c24xx-fix-transferring-more-than-one-message-i.patch
new file mode 100644 (file)
index 0000000..bcedcb7
--- /dev/null
@@ -0,0 +1,88 @@
+From 275d8dd5450b227a3cb398d18eb89b202c939618 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Nov 2023 17:43:53 +0100
+Subject: i2c: s3c24xx: fix transferring more than one message in polling mode
+
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+
+[ Upstream commit 990489e1042c6c5d6bccf56deca68f8dbeed8180 ]
+
+To properly handle ACK on the bus when transferring more than one
+message in polling mode, move the polling handling loop from
+s3c24xx_i2c_message_start() to s3c24xx_i2c_doxfer(). This way
+i2c_s3c_irq_nextbyte() is always executed till the end, properly
+acknowledging the IRQ bits and no recursive calls to
+i2c_s3c_irq_nextbyte() are made.
+
+While touching this, also fix finishing transfers in polling mode by
+using common code path and always waiting for the bus to become idle
+and disabled.
+
+Fixes: 117053f77a5a ("i2c: s3c2410: Add polling mode support")
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-s3c2410.c | 27 ++++++++++-----------------
+ 1 file changed, 10 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
+index 9a6fbb38a5ba..0777848b3316 100644
+--- a/drivers/i2c/busses/i2c-s3c2410.c
++++ b/drivers/i2c/busses/i2c-s3c2410.c
+@@ -283,16 +283,6 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
+       stat |= S3C2410_IICSTAT_START;
+       writel(stat, i2c->regs + S3C2410_IICSTAT);
+-
+-      if (i2c->quirks & QUIRK_POLL) {
+-              while ((i2c->msg_num != 0) && is_ack(i2c)) {
+-                      i2c_s3c_irq_nextbyte(i2c, stat);
+-                      stat = readl(i2c->regs + S3C2410_IICSTAT);
+-
+-                      if (stat & S3C2410_IICSTAT_ARBITR)
+-                              dev_err(i2c->dev, "deal with arbitration loss\n");
+-              }
+-      }
+ }
+ static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
+@@ -699,7 +689,7 @@ static void s3c24xx_i2c_wait_idle(struct s3c24xx_i2c *i2c)
+ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
+                             struct i2c_msg *msgs, int num)
+ {
+-      unsigned long timeout;
++      unsigned long timeout = 0;
+       int ret;
+       ret = s3c24xx_i2c_set_master(i2c);
+@@ -719,16 +709,19 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
+       s3c24xx_i2c_message_start(i2c, msgs);
+       if (i2c->quirks & QUIRK_POLL) {
+-              ret = i2c->msg_idx;
++              while ((i2c->msg_num != 0) && is_ack(i2c)) {
++                      unsigned long stat = readl(i2c->regs + S3C2410_IICSTAT);
+-              if (ret != num)
+-                      dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
++                      i2c_s3c_irq_nextbyte(i2c, stat);
+-              goto out;
++                      stat = readl(i2c->regs + S3C2410_IICSTAT);
++                      if (stat & S3C2410_IICSTAT_ARBITR)
++                              dev_err(i2c->dev, "deal with arbitration loss\n");
++              }
++      } else {
++              timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+       }
+-      timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+-
+       ret = i2c->msg_idx;
+       /*
+-- 
+2.43.0
+
diff --git a/queue-5.15/iio-adc-ad9467-benefit-from-devm_clk_get_enabled-to-.patch b/queue-5.15/iio-adc-ad9467-benefit-from-devm_clk_get_enabled-to-.patch
new file mode 100644 (file)
index 0000000..e993821
--- /dev/null
@@ -0,0 +1,66 @@
+From 53b7abd07833c92820fbe2868de25b236728aac7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Aug 2022 22:47:30 +0200
+Subject: iio: adc: ad9467: Benefit from devm_clk_get_enabled() to simplify
+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>
+
+[ Upstream commit cdd07b3ab94a020570132558442a26e74b70bc42 ]
+
+Make use of devm_clk_get_enabled() to replace some code that effectively
+open codes this new function.
+
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20220808204740.307667-3-u.kleine-koenig@pengutronix.de
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 76f028539cf3 ("iio: adc: ad9467: fix reset gpio handling")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad9467.c | 17 +----------------
+ 1 file changed, 1 insertion(+), 16 deletions(-)
+
+diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
+index dbfc8517cb8a..a07df0fd3329 100644
+--- a/drivers/iio/adc/ad9467.c
++++ b/drivers/iio/adc/ad9467.c
+@@ -378,13 +378,6 @@ static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv)
+       return ad9467_outputmode_set(st->spi, st->output_mode);
+ }
+-static void ad9467_clk_disable(void *data)
+-{
+-      struct ad9467_state *st = data;
+-
+-      clk_disable_unprepare(st->clk);
+-}
+-
+ static int ad9467_probe(struct spi_device *spi)
+ {
+       const struct ad9467_chip_info *info;
+@@ -404,18 +397,10 @@ static int ad9467_probe(struct spi_device *spi)
+       st = adi_axi_adc_conv_priv(conv);
+       st->spi = spi;
+-      st->clk = devm_clk_get(&spi->dev, "adc-clk");
++      st->clk = devm_clk_get_enabled(&spi->dev, "adc-clk");
+       if (IS_ERR(st->clk))
+               return PTR_ERR(st->clk);
+-      ret = clk_prepare_enable(st->clk);
+-      if (ret < 0)
+-              return ret;
+-
+-      ret = devm_add_action_or_reset(&spi->dev, ad9467_clk_disable, st);
+-      if (ret)
+-              return ret;
+-
+       st->pwrdown_gpio = devm_gpiod_get_optional(&spi->dev, "powerdown",
+                                                  GPIOD_OUT_LOW);
+       if (IS_ERR(st->pwrdown_gpio))
+-- 
+2.43.0
+
diff --git a/queue-5.15/iio-adc-ad9467-don-t-ignore-error-codes.patch b/queue-5.15/iio-adc-ad9467-don-t-ignore-error-codes.patch
new file mode 100644 (file)
index 0000000..3f9e4e6
--- /dev/null
@@ -0,0 +1,85 @@
+From 0481edb91b08c4925358ee30acc2288994a33168 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Dec 2023 13:39:25 +0100
+Subject: iio: adc: ad9467: don't ignore error codes
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit e072e149cfb827e0ab4cafb0547e9658e35393cd ]
+
+Make sure functions that return errors are not ignored.
+
+Fixes: ad6797120238 ("iio: adc: ad9467: add support AD9467 ADC")
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20231207-iio-backend-prep-v2-2-a4a33bc4d70e@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad9467.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
+index 46c85748a07e..09ff5b27cee5 100644
+--- a/drivers/iio/adc/ad9467.c
++++ b/drivers/iio/adc/ad9467.c
+@@ -162,9 +162,10 @@ static int ad9467_reg_access(struct adi_axi_adc_conv *conv, unsigned int reg,
+       if (readval == NULL) {
+               ret = ad9467_spi_write(spi, reg, writeval);
+-              ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER,
+-                               AN877_ADC_TRANSFER_SYNC);
+-              return ret;
++              if (ret)
++                      return ret;
++              return ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER,
++                                      AN877_ADC_TRANSFER_SYNC);
+       }
+       ret = ad9467_spi_read(spi, reg);
+@@ -272,10 +273,13 @@ static int ad9467_get_scale(struct adi_axi_adc_conv *conv, int *val, int *val2)
+       const struct ad9467_chip_info *info1 = to_ad9467_chip_info(info);
+       struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+       unsigned int i, vref_val;
++      int ret;
+-      vref_val = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF);
++      ret = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF);
++      if (ret < 0)
++              return ret;
+-      vref_val &= info1->vref_mask;
++      vref_val = ret & info1->vref_mask;
+       for (i = 0; i < info->num_scales; i++) {
+               if (vref_val == info->scale_table[i][1])
+@@ -296,6 +300,7 @@ static int ad9467_set_scale(struct adi_axi_adc_conv *conv, int val, int val2)
+       struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+       unsigned int scale_val[2];
+       unsigned int i;
++      int ret;
+       if (val != 0)
+               return -EINVAL;
+@@ -305,11 +310,13 @@ static int ad9467_set_scale(struct adi_axi_adc_conv *conv, int val, int val2)
+               if (scale_val[0] != val || scale_val[1] != val2)
+                       continue;
+-              ad9467_spi_write(st->spi, AN877_ADC_REG_VREF,
+-                               info->scale_table[i][1]);
+-              ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER,
+-                               AN877_ADC_TRANSFER_SYNC);
+-              return 0;
++              ret = ad9467_spi_write(st->spi, AN877_ADC_REG_VREF,
++                                     info->scale_table[i][1]);
++              if (ret < 0)
++                      return ret;
++
++              return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER,
++                                      AN877_ADC_TRANSFER_SYNC);
+       }
+       return -EINVAL;
+-- 
+2.43.0
+
diff --git a/queue-5.15/iio-adc-ad9467-fix-reset-gpio-handling.patch b/queue-5.15/iio-adc-ad9467-fix-reset-gpio-handling.patch
new file mode 100644 (file)
index 0000000..aa88c3a
--- /dev/null
@@ -0,0 +1,91 @@
+From 6a93dbb3f9ed5ace92acb2409a1e3b618af4a780 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Dec 2023 13:39:24 +0100
+Subject: iio: adc: ad9467: fix reset gpio handling
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit 76f028539cf360f750efd8cde560edda298e4c6b ]
+
+The reset gpio was being handled with inverted polarity. This means that
+as far as gpiolib is concerned we were actually leaving the pin asserted
+(in theory, this would mean reset). However, inverting the polarity in
+devicetree made things work. Fix it by doing it the proper way and how
+gpiolib expects it to be done.
+
+While at it, moved the handling to it's own function and dropped
+'reset_gpio' from the 'struct ad9467_state' as we only need it during
+probe. On top of that, refactored things so that we now request the gpio
+asserted (i.e in reset) and then de-assert it. Also note that we now use
+gpiod_set_value_cansleep() instead of gpiod_direction_output() as we
+already request the pin as output.
+
+Fixes: ad6797120238 ("iio: adc: ad9467: add support AD9467 ADC")
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20231207-iio-backend-prep-v2-1-a4a33bc4d70e@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad9467.c | 31 ++++++++++++++++++-------------
+ 1 file changed, 18 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
+index a07df0fd3329..46c85748a07e 100644
+--- a/drivers/iio/adc/ad9467.c
++++ b/drivers/iio/adc/ad9467.c
+@@ -121,7 +121,6 @@ struct ad9467_state {
+       unsigned int                    output_mode;
+       struct gpio_desc                *pwrdown_gpio;
+-      struct gpio_desc                *reset_gpio;
+ };
+ static int ad9467_spi_read(struct spi_device *spi, unsigned int reg)
+@@ -378,6 +377,21 @@ static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv)
+       return ad9467_outputmode_set(st->spi, st->output_mode);
+ }
++static int ad9467_reset(struct device *dev)
++{
++      struct gpio_desc *gpio;
++
++      gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
++      if (IS_ERR_OR_NULL(gpio))
++              return PTR_ERR_OR_ZERO(gpio);
++
++      fsleep(1);
++      gpiod_set_value_cansleep(gpio, 0);
++      fsleep(10 * USEC_PER_MSEC);
++
++      return 0;
++}
++
+ static int ad9467_probe(struct spi_device *spi)
+ {
+       const struct ad9467_chip_info *info;
+@@ -406,18 +420,9 @@ static int ad9467_probe(struct spi_device *spi)
+       if (IS_ERR(st->pwrdown_gpio))
+               return PTR_ERR(st->pwrdown_gpio);
+-      st->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset",
+-                                               GPIOD_OUT_LOW);
+-      if (IS_ERR(st->reset_gpio))
+-              return PTR_ERR(st->reset_gpio);
+-
+-      if (st->reset_gpio) {
+-              udelay(1);
+-              ret = gpiod_direction_output(st->reset_gpio, 1);
+-              if (ret)
+-                      return ret;
+-              mdelay(10);
+-      }
++      ret = ad9467_reset(&spi->dev);
++      if (ret)
++              return ret;
+       conv->chip_info = &info->axi_adc_info;
+-- 
+2.43.0
+
diff --git a/queue-5.15/iio-adc-ad9467-fix-scale-setting.patch b/queue-5.15/iio-adc-ad9467-fix-scale-setting.patch
new file mode 100644 (file)
index 0000000..1e9b26d
--- /dev/null
@@ -0,0 +1,255 @@
+From 0f77c48a9f3297ac21fcdab94fac4c0715169187 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Dec 2023 13:39:27 +0100
+Subject: iio: adc: ad9467: fix scale setting
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit b73f08bb7fe5a0901646ca5ceaa1e7a2d5ee6293 ]
+
+When reading in_voltage_scale we can get something like:
+
+root@analog:/sys/bus/iio/devices/iio:device2# cat in_voltage_scale
+0.038146
+
+However, when reading the available options:
+
+root@analog:/sys/bus/iio/devices/iio:device2# cat
+in_voltage_scale_available
+2000.000000 2100.000006 2200.000007 2300.000008 2400.000009 2500.000010
+
+which does not make sense. Moreover, when trying to set a new scale we
+get an error because there's no call to __ad9467_get_scale() to give us
+values as given when reading in_voltage_scale. Fix it by computing the
+available scales during probe and properly pass the list when
+.read_available() is called.
+
+While at it, change to use .read_available() from iio_info. Also note
+that to properly fix this, adi-axi-adc.c has to be changed accordingly.
+
+Fixes: ad6797120238 ("iio: adc: ad9467: add support AD9467 ADC")
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://lore.kernel.org/r/20231207-iio-backend-prep-v2-4-a4a33bc4d70e@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad9467.c            | 47 ++++++++++++++++++
+ drivers/iio/adc/adi-axi-adc.c       | 74 ++++++-----------------------
+ include/linux/iio/adc/adi-axi-adc.h |  4 ++
+ 3 files changed, 66 insertions(+), 59 deletions(-)
+
+diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
+index 09ff5b27cee5..ad94f0abc402 100644
+--- a/drivers/iio/adc/ad9467.c
++++ b/drivers/iio/adc/ad9467.c
+@@ -119,6 +119,7 @@ struct ad9467_state {
+       struct spi_device               *spi;
+       struct clk                      *clk;
+       unsigned int                    output_mode;
++      unsigned int                    (*scales)[2];
+       struct gpio_desc                *pwrdown_gpio;
+ };
+@@ -212,6 +213,7 @@ static void __ad9467_get_scale(struct adi_axi_adc_conv *conv, int index,
+       .channel = _chan,                                               \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |          \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ),                           \
++      .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \
+       .scan_index = _si,                                              \
+       .scan_type = {                                                  \
+               .sign = _sign,                                          \
+@@ -365,6 +367,26 @@ static int ad9467_write_raw(struct adi_axi_adc_conv *conv,
+       }
+ }
++static int ad9467_read_avail(struct adi_axi_adc_conv *conv,
++                           struct iio_chan_spec const *chan,
++                           const int **vals, int *type, int *length,
++                           long mask)
++{
++      const struct adi_axi_adc_chip_info *info = conv->chip_info;
++      struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
++
++      switch (mask) {
++      case IIO_CHAN_INFO_SCALE:
++              *vals = (const int *)st->scales;
++              *type = IIO_VAL_INT_PLUS_MICRO;
++              /* Values are stored in a 2D matrix */
++              *length = info->num_scales * 2;
++              return IIO_AVAIL_LIST;
++      default:
++              return -EINVAL;
++      }
++}
++
+ static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode)
+ {
+       int ret;
+@@ -377,6 +399,26 @@ static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode)
+                               AN877_ADC_TRANSFER_SYNC);
+ }
++static int ad9467_scale_fill(struct adi_axi_adc_conv *conv)
++{
++      const struct adi_axi_adc_chip_info *info = conv->chip_info;
++      struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
++      unsigned int i, val1, val2;
++
++      st->scales = devm_kmalloc_array(&st->spi->dev, info->num_scales,
++                                      sizeof(*st->scales), GFP_KERNEL);
++      if (!st->scales)
++              return -ENOMEM;
++
++      for (i = 0; i < info->num_scales; i++) {
++              __ad9467_get_scale(conv, i, &val1, &val2);
++              st->scales[i][0] = val1;
++              st->scales[i][1] = val2;
++      }
++
++      return 0;
++}
++
+ static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv)
+ {
+       struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+@@ -433,6 +475,10 @@ static int ad9467_probe(struct spi_device *spi)
+       conv->chip_info = &info->axi_adc_info;
++      ret = ad9467_scale_fill(conv);
++      if (ret)
++              return ret;
++
+       id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID);
+       if (id != conv->chip_info->id) {
+               dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n",
+@@ -443,6 +489,7 @@ static int ad9467_probe(struct spi_device *spi)
+       conv->reg_access = ad9467_reg_access;
+       conv->write_raw = ad9467_write_raw;
+       conv->read_raw = ad9467_read_raw;
++      conv->read_avail = ad9467_read_avail;
+       conv->preenable_setup = ad9467_preenable_setup;
+       st->output_mode = info->default_output_mode |
+diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c
+index a9e655e69eaa..c6dac4c10c31 100644
+--- a/drivers/iio/adc/adi-axi-adc.c
++++ b/drivers/iio/adc/adi-axi-adc.c
+@@ -142,6 +142,20 @@ static int adi_axi_adc_write_raw(struct iio_dev *indio_dev,
+       return conv->write_raw(conv, chan, val, val2, mask);
+ }
++static int adi_axi_adc_read_avail(struct iio_dev *indio_dev,
++                                struct iio_chan_spec const *chan,
++                                const int **vals, int *type, int *length,
++                                long mask)
++{
++      struct adi_axi_adc_state *st = iio_priv(indio_dev);
++      struct adi_axi_adc_conv *conv = &st->client->conv;
++
++      if (!conv->read_avail)
++              return -EOPNOTSUPP;
++
++      return conv->read_avail(conv, chan, vals, type, length, mask);
++}
++
+ static int adi_axi_adc_update_scan_mode(struct iio_dev *indio_dev,
+                                       const unsigned long *scan_mask)
+ {
+@@ -226,69 +240,11 @@ struct adi_axi_adc_conv *devm_adi_axi_adc_conv_register(struct device *dev,
+ }
+ EXPORT_SYMBOL_GPL(devm_adi_axi_adc_conv_register);
+-static ssize_t in_voltage_scale_available_show(struct device *dev,
+-                                             struct device_attribute *attr,
+-                                             char *buf)
+-{
+-      struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+-      struct adi_axi_adc_state *st = iio_priv(indio_dev);
+-      struct adi_axi_adc_conv *conv = &st->client->conv;
+-      size_t len = 0;
+-      int i;
+-
+-      for (i = 0; i < conv->chip_info->num_scales; i++) {
+-              const unsigned int *s = conv->chip_info->scale_table[i];
+-
+-              len += scnprintf(buf + len, PAGE_SIZE - len,
+-                               "%u.%06u ", s[0], s[1]);
+-      }
+-      buf[len - 1] = '\n';
+-
+-      return len;
+-}
+-
+-static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0);
+-
+-enum {
+-      ADI_AXI_ATTR_SCALE_AVAIL,
+-};
+-
+-#define ADI_AXI_ATTR(_en_, _file_)                    \
+-      [ADI_AXI_ATTR_##_en_] = &iio_dev_attr_##_file_.dev_attr.attr
+-
+-static struct attribute *adi_axi_adc_attributes[] = {
+-      ADI_AXI_ATTR(SCALE_AVAIL, in_voltage_scale_available),
+-      NULL
+-};
+-
+-static umode_t axi_adc_attr_is_visible(struct kobject *kobj,
+-                                     struct attribute *attr, int n)
+-{
+-      struct device *dev = kobj_to_dev(kobj);
+-      struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+-      struct adi_axi_adc_state *st = iio_priv(indio_dev);
+-      struct adi_axi_adc_conv *conv = &st->client->conv;
+-
+-      switch (n) {
+-      case ADI_AXI_ATTR_SCALE_AVAIL:
+-              if (!conv->chip_info->num_scales)
+-                      return 0;
+-              return attr->mode;
+-      default:
+-              return attr->mode;
+-      }
+-}
+-
+-static const struct attribute_group adi_axi_adc_attribute_group = {
+-      .attrs = adi_axi_adc_attributes,
+-      .is_visible = axi_adc_attr_is_visible,
+-};
+-
+ static const struct iio_info adi_axi_adc_info = {
+       .read_raw = &adi_axi_adc_read_raw,
+       .write_raw = &adi_axi_adc_write_raw,
+-      .attrs = &adi_axi_adc_attribute_group,
+       .update_scan_mode = &adi_axi_adc_update_scan_mode,
++      .read_avail = &adi_axi_adc_read_avail,
+ };
+ static const struct adi_axi_adc_core_info adi_axi_adc_10_0_a_info = {
+diff --git a/include/linux/iio/adc/adi-axi-adc.h b/include/linux/iio/adc/adi-axi-adc.h
+index 52620e5b8052..b7904992d561 100644
+--- a/include/linux/iio/adc/adi-axi-adc.h
++++ b/include/linux/iio/adc/adi-axi-adc.h
+@@ -41,6 +41,7 @@ struct adi_axi_adc_chip_info {
+  * @reg_access                IIO debugfs_reg_access hook for the client ADC
+  * @read_raw          IIO read_raw hook for the client ADC
+  * @write_raw         IIO write_raw hook for the client ADC
++ * @read_avail                IIO read_avail hook for the client ADC
+  */
+ struct adi_axi_adc_conv {
+       const struct adi_axi_adc_chip_info              *chip_info;
+@@ -54,6 +55,9 @@ struct adi_axi_adc_conv {
+       int (*write_raw)(struct adi_axi_adc_conv *conv,
+                        struct iio_chan_spec const *chan,
+                        int val, int val2, long mask);
++      int (*read_avail)(struct adi_axi_adc_conv *conv,
++                        struct iio_chan_spec const *chan,
++                        const int **val, int *type, int *length, long mask);
+ };
+ struct adi_axi_adc_conv *devm_adi_axi_adc_conv_register(struct device *dev,
+-- 
+2.43.0
+
diff --git a/queue-5.15/ipv6-mcast-fix-data-race-in-ipv6_mc_down-mld_ifc_wor.patch b/queue-5.15/ipv6-mcast-fix-data-race-in-ipv6_mc_down-mld_ifc_wor.patch
new file mode 100644 (file)
index 0000000..311d54c
--- /dev/null
@@ -0,0 +1,81 @@
+From 12c4c3273ca265a9e83e697ff13ed7127aee64ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 09:21:02 -0800
+Subject: ipv6: mcast: fix data-race in ipv6_mc_down / mld_ifc_work
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit 2e7ef287f07c74985f1bf2858bedc62bd9ebf155 ]
+
+idev->mc_ifc_count can be written over without proper locking.
+
+Originally found by syzbot [1], fix this issue by encapsulating calls
+to mld_ifc_stop_work() (and mld_gq_stop_work() for good measure) with
+mutex_lock() and mutex_unlock() accordingly as these functions
+should only be called with mc_lock per their declarations.
+
+[1]
+BUG: KCSAN: data-race in ipv6_mc_down / mld_ifc_work
+
+write to 0xffff88813a80c832 of 1 bytes by task 3771 on cpu 0:
+ mld_ifc_stop_work net/ipv6/mcast.c:1080 [inline]
+ ipv6_mc_down+0x10a/0x280 net/ipv6/mcast.c:2725
+ addrconf_ifdown+0xe32/0xf10 net/ipv6/addrconf.c:3949
+ addrconf_notify+0x310/0x980
+ notifier_call_chain kernel/notifier.c:93 [inline]
+ raw_notifier_call_chain+0x6b/0x1c0 kernel/notifier.c:461
+ __dev_notify_flags+0x205/0x3d0
+ dev_change_flags+0xab/0xd0 net/core/dev.c:8685
+ do_setlink+0x9f6/0x2430 net/core/rtnetlink.c:2916
+ rtnl_group_changelink net/core/rtnetlink.c:3458 [inline]
+ __rtnl_newlink net/core/rtnetlink.c:3717 [inline]
+ rtnl_newlink+0xbb3/0x1670 net/core/rtnetlink.c:3754
+ rtnetlink_rcv_msg+0x807/0x8c0 net/core/rtnetlink.c:6558
+ netlink_rcv_skb+0x126/0x220 net/netlink/af_netlink.c:2545
+ rtnetlink_rcv+0x1c/0x20 net/core/rtnetlink.c:6576
+ netlink_unicast_kernel net/netlink/af_netlink.c:1342 [inline]
+ netlink_unicast+0x589/0x650 net/netlink/af_netlink.c:1368
+ netlink_sendmsg+0x66e/0x770 net/netlink/af_netlink.c:1910
+ ...
+
+write to 0xffff88813a80c832 of 1 bytes by task 22 on cpu 1:
+ mld_ifc_work+0x54c/0x7b0 net/ipv6/mcast.c:2653
+ process_one_work kernel/workqueue.c:2627 [inline]
+ process_scheduled_works+0x5b8/0xa30 kernel/workqueue.c:2700
+ worker_thread+0x525/0x730 kernel/workqueue.c:2781
+ ...
+
+Fixes: 2d9a93b4902b ("mld: convert from timer to delayed work")
+Reported-by: syzbot+a9400cabb1d784e49abf@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/000000000000994e09060ebcdffb@google.com/
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Acked-by: Taehee Yoo <ap420073@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Hangbin Liu <liuhangbin@gmail.com>
+Link: https://lore.kernel.org/r/20240117172102.12001-1-n.zhandarovich@fintech.ru
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/mcast.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
+index 87c699d57b36..0ea7d97cdc02 100644
+--- a/net/ipv6/mcast.c
++++ b/net/ipv6/mcast.c
+@@ -2725,8 +2725,12 @@ void ipv6_mc_down(struct inet6_dev *idev)
+       synchronize_net();
+       mld_query_stop_work(idev);
+       mld_report_stop_work(idev);
++
++      mutex_lock(&idev->mc_lock);
+       mld_ifc_stop_work(idev);
+       mld_gq_stop_work(idev);
++      mutex_unlock(&idev->mc_lock);
++
+       mld_dad_stop_work(idev);
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.15/ipvs-avoid-stat-macros-calls-from-preemptible-contex.patch b/queue-5.15/ipvs-avoid-stat-macros-calls-from-preemptible-contex.patch
new file mode 100644 (file)
index 0000000..40b0648
--- /dev/null
@@ -0,0 +1,83 @@
+From 505350d1fc7c5b9497b461e99fcf26d310d14ca2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jan 2024 17:39:22 +0300
+Subject: ipvs: avoid stat macros calls from preemptible context
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit d6938c1c76c64f42363d0d1f051e1b4641c2ad40 ]
+
+Inside decrement_ttl() upon discovering that the packet ttl has exceeded,
+__IP_INC_STATS and __IP6_INC_STATS macros can be called from preemptible
+context having the following backtrace:
+
+check_preemption_disabled: 48 callbacks suppressed
+BUG: using __this_cpu_add() in preemptible [00000000] code: curl/1177
+caller is decrement_ttl+0x217/0x830
+CPU: 5 PID: 1177 Comm: curl Not tainted 6.7.0+ #34
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 04/01/2014
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xbd/0xe0
+ check_preemption_disabled+0xd1/0xe0
+ decrement_ttl+0x217/0x830
+ __ip_vs_get_out_rt+0x4e0/0x1ef0
+ ip_vs_nat_xmit+0x205/0xcd0
+ ip_vs_in_hook+0x9b1/0x26a0
+ nf_hook_slow+0xc2/0x210
+ nf_hook+0x1fb/0x770
+ __ip_local_out+0x33b/0x640
+ ip_local_out+0x2a/0x490
+ __ip_queue_xmit+0x990/0x1d10
+ __tcp_transmit_skb+0x288b/0x3d10
+ tcp_connect+0x3466/0x5180
+ tcp_v4_connect+0x1535/0x1bb0
+ __inet_stream_connect+0x40d/0x1040
+ inet_stream_connect+0x57/0xa0
+ __sys_connect_file+0x162/0x1a0
+ __sys_connect+0x137/0x160
+ __x64_sys_connect+0x72/0xb0
+ do_syscall_64+0x6f/0x140
+ entry_SYSCALL_64_after_hwframe+0x6e/0x76
+RIP: 0033:0x7fe6dbbc34e0
+
+Use the corresponding preemption-aware variants: IP_INC_STATS and
+IP6_INC_STATS.
+
+Found by Linux Verification Center (linuxtesting.org).
+
+Fixes: 8d8e20e2d7bb ("ipvs: Decrement ttl")
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Acked-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_xmit.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
+index cd2130e98836..c87dbc897002 100644
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -271,7 +271,7 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs,
+                       skb->dev = dst->dev;
+                       icmpv6_send(skb, ICMPV6_TIME_EXCEED,
+                                   ICMPV6_EXC_HOPLIMIT, 0);
+-                      __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
++                      IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
+                       return false;
+               }
+@@ -286,7 +286,7 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs,
+       {
+               if (ip_hdr(skb)->ttl <= 1) {
+                       /* Tell the sender its packet died... */
+-                      __IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
++                      IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
+                       icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
+                       return false;
+               }
+-- 
+2.43.0
+
diff --git a/queue-5.15/kdb-fix-a-potential-buffer-overflow-in-kdb_local.patch b/queue-5.15/kdb-fix-a-potential-buffer-overflow-in-kdb_local.patch
new file mode 100644 (file)
index 0000000..481d82c
--- /dev/null
@@ -0,0 +1,45 @@
+From 7757b952b28f0ada9fbb477a58ecff1e9268f861 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Nov 2023 13:05:04 +0100
+Subject: kdb: Fix a potential buffer overflow in kdb_local()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 4f41d30cd6dc865c3cbc1a852372321eba6d4e4c ]
+
+When appending "[defcmd]" to 'kdb_prompt_str', the size of the string
+already in the buffer should be taken into account.
+
+An option could be to switch from strncat() to strlcat() which does the
+correct test to avoid such an overflow.
+
+However, this actually looks as dead code, because 'defcmd_in_progress'
+can't be true here.
+See a more detailed explanation at [1].
+
+[1]: https://lore.kernel.org/all/CAD=FV=WSh7wKN7Yp-3wWiDgX4E3isQ8uh0LCzTmd1v9Cg9j+nQ@mail.gmail.com/
+
+Fixes: 5d5314d6795f ("kdb: core for kgdb back end (1 of 2)")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/debug/kdb/kdb_main.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
+index ead4da947127..23723c5727aa 100644
+--- a/kernel/debug/kdb/kdb_main.c
++++ b/kernel/debug/kdb/kdb_main.c
+@@ -1350,8 +1350,6 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs,
+               /* PROMPT can only be set if we have MEM_READ permission. */
+               snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"),
+                        raw_smp_processor_id());
+-              if (defcmd_in_progress)
+-                      strncat(kdb_prompt_str, "[defcmd]", CMD_BUFLEN);
+               /*
+                * Fetch command from keyboard
+-- 
+2.43.0
+
diff --git a/queue-5.15/leds-aw2013-select-missing-dependency-regmap_i2c.patch b/queue-5.15/leds-aw2013-select-missing-dependency-regmap_i2c.patch
new file mode 100644 (file)
index 0000000..db70542
--- /dev/null
@@ -0,0 +1,41 @@
+From 8b86985b6fc86af0c584caa8730cb6012269a01e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Nov 2023 18:42:03 +0700
+Subject: leds: aw2013: Select missing dependency REGMAP_I2C
+
+From: Dang Huynh <danct12@riseup.net>
+
+[ Upstream commit 75469bb0537ad2ab0fc1fb6e534a79cfc03f3b3f ]
+
+The AW2013 driver uses devm_regmap_init_i2c, so REGMAP_I2C needs to
+be selected.
+
+Otherwise build process may fail with:
+  ld: drivers/leds/leds-aw2013.o: in function `aw2013_probe':
+    leds-aw2013.c:345: undefined reference to `__devm_regmap_init_i2c'
+
+Signed-off-by: Dang Huynh <danct12@riseup.net>
+Acked-by: Nikita Travkin <nikita@trvn.ru>
+Fixes: 59ea3c9faf32 ("leds: add aw2013 driver")
+Link: https://lore.kernel.org/r/20231103114203.1108922-1-danct12@riseup.net
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
+index 8bf545100fb0..fdfc41535c8a 100644
+--- a/drivers/leds/Kconfig
++++ b/drivers/leds/Kconfig
+@@ -97,6 +97,7 @@ config LEDS_ARIEL
+ config LEDS_AW2013
+       tristate "LED support for Awinic AW2013"
+       depends on LEDS_CLASS && I2C && OF
++      select REGMAP_I2C
+       help
+         This option enables support for the AW2013 3-channel
+         LED driver.
+-- 
+2.43.0
+
diff --git a/queue-5.15/libapi-add-missing-linux-types.h-header-to-get-the-_.patch b/queue-5.15/libapi-add-missing-linux-types.h-header-to-get-the-_.patch
new file mode 100644 (file)
index 0000000..273ff0e
--- /dev/null
@@ -0,0 +1,40 @@
+From 8b9b71eb035de31ec1fe82997f1949dc9a36819e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Nov 2023 14:11:45 -0300
+Subject: libapi: Add missing linux/types.h header to get the __u64 type on
+ io.h
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit af76b2dec0984a079d8497bfa37d29a9b55932e1 ]
+
+There are functions using __u64, so we need to have the linux/types.h
+header otherwise we'll break when its not included before api/io.h.
+
+Fixes: e95770af4c4a280f ("tools api: Add a lightweight buffered reading api")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/lkml/ZWjDPL+IzPPsuC3X@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/api/io.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/lib/api/io.h b/tools/lib/api/io.h
+index 777c20f6b604..458acd294237 100644
+--- a/tools/lib/api/io.h
++++ b/tools/lib/api/io.h
+@@ -9,6 +9,7 @@
+ #include <stdlib.h>
+ #include <unistd.h>
++#include <linux/types.h>
+ struct io {
+       /* File descriptor being read/ */
+-- 
+2.43.0
+
diff --git a/queue-5.15/mfd-intel-lpss-fix-the-fractional-clock-divider-flag.patch b/queue-5.15/mfd-intel-lpss-fix-the-fractional-clock-divider-flag.patch
new file mode 100644 (file)
index 0000000..4cc0e01
--- /dev/null
@@ -0,0 +1,40 @@
+From c8438a157ed1e8a402b126411846b0d8cf8c5c23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Dec 2023 13:14:41 +0200
+Subject: mfd: intel-lpss: Fix the fractional clock divider flags
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 03d790f04fb2507173913cad9c213272ac983a60 ]
+
+The conversion to CLK_FRAC_DIVIDER_POWER_OF_TWO_PS uses wrong flags
+in the parameters and hence miscalculates the values in the clock
+divider. Fix this by applying the flag to the proper parameter.
+
+Fixes: 82f53f9ee577 ("clk: fractional-divider: Introduce POWER_OF_TWO_PS flag")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reported-by: Alex Vinarskis <alex.vinarskis@gmail.com>
+Link: https://lore.kernel.org/r/20231211111441.3910083-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/intel-lpss.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c
+index 0e15afc39f54..b1a0cd34e8a9 100644
+--- a/drivers/mfd/intel-lpss.c
++++ b/drivers/mfd/intel-lpss.c
+@@ -301,8 +301,8 @@ static int intel_lpss_register_clock_divider(struct intel_lpss *lpss,
+       snprintf(name, sizeof(name), "%s-div", devname);
+       tmp = clk_register_fractional_divider(NULL, name, __clk_get_name(tmp),
++                                            0, lpss->priv, 1, 15, 16, 15,
+                                             CLK_FRAC_DIVIDER_POWER_OF_TWO_PS,
+-                                            lpss->priv, 1, 15, 16, 15, 0,
+                                             NULL);
+       if (IS_ERR(tmp))
+               return PTR_ERR(tmp);
+-- 
+2.43.0
+
diff --git a/queue-5.15/mfd-syscon-fix-null-pointer-dereference-in-of_syscon.patch b/queue-5.15/mfd-syscon-fix-null-pointer-dereference-in-of_syscon.patch
new file mode 100644 (file)
index 0000000..2cbd216
--- /dev/null
@@ -0,0 +1,40 @@
+From 7f0cf2196766fd555275ffde2d8c874278a258dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Dec 2023 17:24:43 +0800
+Subject: mfd: syscon: Fix null pointer dereference in of_syscon_register()
+
+From: Kunwu Chan <chentao@kylinos.cn>
+
+[ Upstream commit 41673c66b3d0c09915698fec5c13b24336f18dd1 ]
+
+kasprintf() returns a pointer to dynamically allocated memory
+which can be NULL upon failure.
+
+Fixes: e15d7f2b81d2 ("mfd: syscon: Use a unique name with regmap_config")
+Signed-off-by: Kunwu Chan <chentao@kylinos.cn>
+Reviewed-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20231204092443.2462115-1-chentao@kylinos.cn
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/syscon.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
+index 191fdb87c424..552b1861adad 100644
+--- a/drivers/mfd/syscon.c
++++ b/drivers/mfd/syscon.c
+@@ -103,6 +103,10 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk)
+       syscon_config.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", np,
+                                      (u64)res.start);
++      if (!syscon_config.name) {
++              ret = -ENOMEM;
++              goto err_regmap;
++      }
+       syscon_config.reg_stride = reg_io_width;
+       syscon_config.val_bits = reg_io_width * 8;
+       syscon_config.max_register = resource_size(&res) - reg_io_width;
+-- 
+2.43.0
+
diff --git a/queue-5.15/mips-alchemy-fix-an-out-of-bound-access-in-db1200_de.patch b/queue-5.15/mips-alchemy-fix-an-out-of-bound-access-in-db1200_de.patch
new file mode 100644 (file)
index 0000000..fd75508
--- /dev/null
@@ -0,0 +1,36 @@
+From ab01b5d5a86d5456e53c0ba60d0be0d0e68eb0f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 19:07:36 +0100
+Subject: MIPS: Alchemy: Fix an out-of-bound access in db1200_dev_setup()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 89c4b588d11e9acf01d604de4b0c715884f59213 ]
+
+When calling spi_register_board_info(), we should pass the number of
+elements in 'db1200_spi_devs', not 'db1200_i2c_devs'.
+
+Fixes: 63323ec54a7e ("MIPS: Alchemy: Extended DB1200 board support.")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/alchemy/devboards/db1200.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c
+index f521874ebb07..67f067706af2 100644
+--- a/arch/mips/alchemy/devboards/db1200.c
++++ b/arch/mips/alchemy/devboards/db1200.c
+@@ -847,7 +847,7 @@ int __init db1200_dev_setup(void)
+       i2c_register_board_info(0, db1200_i2c_devs,
+                               ARRAY_SIZE(db1200_i2c_devs));
+       spi_register_board_info(db1200_spi_devs,
+-                              ARRAY_SIZE(db1200_i2c_devs));
++                              ARRAY_SIZE(db1200_spi_devs));
+       /* SWITCHES:    S6.8 I2C/SPI selector  (OFF=I2C  ON=SPI)
+        *              S6.7 AC97/I2S selector (OFF=AC97 ON=I2S)
+-- 
+2.43.0
+
diff --git a/queue-5.15/mips-alchemy-fix-an-out-of-bound-access-in-db1550_de.patch b/queue-5.15/mips-alchemy-fix-an-out-of-bound-access-in-db1550_de.patch
new file mode 100644 (file)
index 0000000..22869c0
--- /dev/null
@@ -0,0 +1,35 @@
+From f16e698e9bec3ca96b3335d03cb73850efa2a185 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 19:09:46 +0100
+Subject: MIPS: Alchemy: Fix an out-of-bound access in db1550_dev_setup()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 3c1e5abcda64bed0c7bffa65af2316995f269a61 ]
+
+When calling spi_register_board_info(),
+
+Fixes: f869d42e580f ("MIPS: Alchemy: Improved DB1550 support, with audio and serial busses.")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/alchemy/devboards/db1550.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c
+index 752b93d91ac9..06811a5db71d 100644
+--- a/arch/mips/alchemy/devboards/db1550.c
++++ b/arch/mips/alchemy/devboards/db1550.c
+@@ -588,7 +588,7 @@ int __init db1550_dev_setup(void)
+       i2c_register_board_info(0, db1550_i2c_devs,
+                               ARRAY_SIZE(db1550_i2c_devs));
+       spi_register_board_info(db1550_spi_devs,
+-                              ARRAY_SIZE(db1550_i2c_devs));
++                              ARRAY_SIZE(db1550_spi_devs));
+       c = clk_get(NULL, "psc0_intclk");
+       if (!IS_ERR(c)) {
+-- 
+2.43.0
+
diff --git a/queue-5.15/mips-dmi-fix-early-remap-on-mips32.patch b/queue-5.15/mips-dmi-fix-early-remap-on-mips32.patch
new file mode 100644 (file)
index 0000000..0f5621c
--- /dev/null
@@ -0,0 +1,44 @@
+From f197b067958e87848377a2b193c34154f87a0031 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Dec 2023 14:14:18 +0300
+Subject: mips: dmi: Fix early remap on MIPS32
+
+From: Serge Semin <fancer.lancer@gmail.com>
+
+[ Upstream commit 0d0a3748a2cb38f9da1f08d357688ebd982eb788 ]
+
+dmi_early_remap() has been defined as ioremap_cache() which on MIPS32 gets
+to be converted to the VM-based mapping. DMI early remapping is performed
+at the setup_arch() stage with no VM available. So calling the
+dmi_early_remap() for MIPS32 causes the system to crash at the early boot
+time. Fix that by converting dmi_early_remap() to the uncached remapping
+which is always available on both 32 and 64-bits MIPS systems.
+
+Note this change shall not cause any regressions on the current DMI
+support implementation because on the early boot-up stage neither MIPS32
+nor MIPS64 has the cacheable ioremapping support anyway.
+
+Fixes: be8fa1cb444c ("MIPS: Add support for Desktop Management Interface (DMI)")
+Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/include/asm/dmi.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/mips/include/asm/dmi.h b/arch/mips/include/asm/dmi.h
+index 27415a288adf..dc397f630c66 100644
+--- a/arch/mips/include/asm/dmi.h
++++ b/arch/mips/include/asm/dmi.h
+@@ -5,7 +5,7 @@
+ #include <linux/io.h>
+ #include <linux/memblock.h>
+-#define dmi_early_remap(x, l)         ioremap_cache(x, l)
++#define dmi_early_remap(x, l)         ioremap(x, l)
+ #define dmi_early_unmap(x, l)         iounmap(x)
+ #define dmi_remap(x, l)                       ioremap_cache(x, l)
+ #define dmi_unmap(x)                  iounmap(x)
+-- 
+2.43.0
+
diff --git a/queue-5.15/mips-fix-incorrect-max_low_pfn-adjustment.patch b/queue-5.15/mips-fix-incorrect-max_low_pfn-adjustment.patch
new file mode 100644 (file)
index 0000000..c01d527
--- /dev/null
@@ -0,0 +1,80 @@
+From 7214296dd4b81d7693d47a3c8300ab59d5651f5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Dec 2023 14:14:19 +0300
+Subject: mips: Fix incorrect max_low_pfn adjustment
+
+From: Serge Semin <fancer.lancer@gmail.com>
+
+[ Upstream commit 0f5cc249ff73552d3bd864e62f85841dafaa107d ]
+
+max_low_pfn variable is incorrectly adjusted if the kernel is built with
+high memory support and the later is detected in a running system, so the
+memory which actually can be directly mapped is getting into the highmem
+zone. See the ZONE_NORMAL range on my MIPS32r5 system:
+
+> Zone ranges:
+>   DMA      [mem 0x0000000000000000-0x0000000000ffffff]
+>   Normal   [mem 0x0000000001000000-0x0000000007ffffff]
+>   HighMem  [mem 0x0000000008000000-0x000000020fffffff]
+
+while the zones are supposed to look as follows:
+
+> Zone ranges:
+>   DMA      [mem 0x0000000000000000-0x0000000000ffffff]
+>   Normal   [mem 0x0000000001000000-0x000000001fffffff]
+>   HighMem  [mem 0x0000000020000000-0x000000020fffffff]
+
+Even though the physical memory within the range [0x08000000;0x20000000]
+belongs to MMIO on our system, we don't really want it to be considered as
+high memory since on MIPS32 that range still can be directly mapped.
+
+Note there might be other problems caused by the max_low_pfn variable
+misconfiguration. For instance high_memory variable is initialize with
+virtual address corresponding to the max_low_pfn PFN, and by design it
+must define the upper bound on direct map memory, then end of the normal
+zone. That in its turn potentially may cause problems in accessing the
+memory by means of the /dev/mem and /dev/kmem devices.
+
+Let's fix the discovered misconfiguration then. It turns out the commit
+a94e4f24ec83 ("MIPS: init: Drop boot_mem_map") didn't introduce the
+max_low_pfn adjustment quite correct. If the kernel is built with high
+memory support and the system is equipped with high memory, the
+max_low_pfn variable will need to be initialized with PFN of the most
+upper directly reachable memory address so the zone normal would be
+correctly setup. On MIPS that PFN corresponds to PFN_DOWN(HIGHMEM_START).
+If the system is built with no high memory support and one is detected in
+the running system, we'll just need to adjust the max_pfn variable to
+discard the found high memory from the system and leave the max_low_pfn as
+is, since the later will be less than PFN_DOWN(HIGHMEM_START) anyway by
+design of the for_each_memblock() loop performed a bit early in the
+bootmem_init() method.
+
+Fixes: a94e4f24ec83 ("MIPS: init: Drop boot_mem_map")
+Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/kernel/setup.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
+index 145f905fb362..9d53498682d2 100644
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -324,11 +324,11 @@ static void __init bootmem_init(void)
+               panic("Incorrect memory mapping !!!");
+       if (max_pfn > PFN_DOWN(HIGHMEM_START)) {
++              max_low_pfn = PFN_DOWN(HIGHMEM_START);
+ #ifdef CONFIG_HIGHMEM
+-              highstart_pfn = PFN_DOWN(HIGHMEM_START);
++              highstart_pfn = max_low_pfn;
+               highend_pfn = max_pfn;
+ #else
+-              max_low_pfn = PFN_DOWN(HIGHMEM_START);
+               max_pfn = max_low_pfn;
+ #endif
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.15/mlxsw-spectrum-use-bitmap_zalloc-when-applicable.patch b/queue-5.15/mlxsw-spectrum-use-bitmap_zalloc-when-applicable.patch
new file mode 100644 (file)
index 0000000..d2a0e13
--- /dev/null
@@ -0,0 +1,205 @@
+From 85b0a3dbfa3abde367e154c63392d3db9a5f63e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Oct 2021 21:17:51 +0200
+Subject: mlxsw: spectrum: Use 'bitmap_zalloc()' when applicable
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 2c087dfcc9d5e7e8557d217f01f58ba42d1ddbf1 ]
+
+Use 'bitmap_zalloc()' to simplify code, improve the semantic and avoid
+some open-coded arithmetic in allocator arguments.
+
+Also change the corresponding 'kfree()' into 'bitmap_free()' to keep
+consistency.
+
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 483ae90d8f97 ("mlxsw: spectrum_acl_tcam: Fix stack corruption")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlxsw/spectrum_acl_atcam.c  |  8 +++-----
+ .../ethernet/mellanox/mlxsw/spectrum_acl_tcam.c   | 15 ++++++---------
+ .../net/ethernet/mellanox/mlxsw/spectrum_cnt.c    |  9 +++------
+ .../ethernet/mellanox/mlxsw/spectrum_switchdev.c  | 11 ++++-------
+ 4 files changed, 16 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c
+index ded4cf658680..4b713832fdd5 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c
+@@ -119,7 +119,6 @@ mlxsw_sp_acl_atcam_region_12kb_init(struct mlxsw_sp_acl_atcam_region *aregion)
+ {
+       struct mlxsw_sp *mlxsw_sp = aregion->region->mlxsw_sp;
+       struct mlxsw_sp_acl_atcam_region_12kb *region_12kb;
+-      size_t alloc_size;
+       u64 max_lkey_id;
+       int err;
+@@ -131,8 +130,7 @@ mlxsw_sp_acl_atcam_region_12kb_init(struct mlxsw_sp_acl_atcam_region *aregion)
+       if (!region_12kb)
+               return -ENOMEM;
+-      alloc_size = BITS_TO_LONGS(max_lkey_id) * sizeof(unsigned long);
+-      region_12kb->used_lkey_id = kzalloc(alloc_size, GFP_KERNEL);
++      region_12kb->used_lkey_id = bitmap_zalloc(max_lkey_id, GFP_KERNEL);
+       if (!region_12kb->used_lkey_id) {
+               err = -ENOMEM;
+               goto err_used_lkey_id_alloc;
+@@ -149,7 +147,7 @@ mlxsw_sp_acl_atcam_region_12kb_init(struct mlxsw_sp_acl_atcam_region *aregion)
+       return 0;
+ err_rhashtable_init:
+-      kfree(region_12kb->used_lkey_id);
++      bitmap_free(region_12kb->used_lkey_id);
+ err_used_lkey_id_alloc:
+       kfree(region_12kb);
+       return err;
+@@ -161,7 +159,7 @@ mlxsw_sp_acl_atcam_region_12kb_fini(struct mlxsw_sp_acl_atcam_region *aregion)
+       struct mlxsw_sp_acl_atcam_region_12kb *region_12kb = aregion->priv;
+       rhashtable_destroy(&region_12kb->lkey_ht);
+-      kfree(region_12kb->used_lkey_id);
++      bitmap_free(region_12kb->used_lkey_id);
+       kfree(region_12kb);
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+index 7cccc41dd69c..31f7f4c3acc3 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+@@ -36,7 +36,6 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
+       u64 max_tcam_regions;
+       u64 max_regions;
+       u64 max_groups;
+-      size_t alloc_size;
+       int err;
+       mutex_init(&tcam->lock);
+@@ -52,15 +51,13 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
+       if (max_tcam_regions < max_regions)
+               max_regions = max_tcam_regions;
+-      alloc_size = sizeof(tcam->used_regions[0]) * BITS_TO_LONGS(max_regions);
+-      tcam->used_regions = kzalloc(alloc_size, GFP_KERNEL);
++      tcam->used_regions = bitmap_zalloc(max_regions, GFP_KERNEL);
+       if (!tcam->used_regions)
+               return -ENOMEM;
+       tcam->max_regions = max_regions;
+       max_groups = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_GROUPS);
+-      alloc_size = sizeof(tcam->used_groups[0]) * BITS_TO_LONGS(max_groups);
+-      tcam->used_groups = kzalloc(alloc_size, GFP_KERNEL);
++      tcam->used_groups = bitmap_zalloc(max_groups, GFP_KERNEL);
+       if (!tcam->used_groups) {
+               err = -ENOMEM;
+               goto err_alloc_used_groups;
+@@ -76,9 +73,9 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
+       return 0;
+ err_tcam_init:
+-      kfree(tcam->used_groups);
++      bitmap_free(tcam->used_groups);
+ err_alloc_used_groups:
+-      kfree(tcam->used_regions);
++      bitmap_free(tcam->used_regions);
+       return err;
+ }
+@@ -89,8 +86,8 @@ void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
+       mutex_destroy(&tcam->lock);
+       ops->fini(mlxsw_sp, tcam->priv);
+-      kfree(tcam->used_groups);
+-      kfree(tcam->used_regions);
++      bitmap_free(tcam->used_groups);
++      bitmap_free(tcam->used_regions);
+ }
+ int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp,
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c
+index b65b93a2b9bc..fc2257753b9b 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c
+@@ -122,7 +122,6 @@ int mlxsw_sp_counter_pool_init(struct mlxsw_sp *mlxsw_sp)
+       unsigned int sub_pools_count = ARRAY_SIZE(mlxsw_sp_counter_sub_pools);
+       struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
+       struct mlxsw_sp_counter_pool *pool;
+-      unsigned int map_size;
+       int err;
+       pool = kzalloc(struct_size(pool, sub_pools, sub_pools_count),
+@@ -143,9 +142,7 @@ int mlxsw_sp_counter_pool_init(struct mlxsw_sp *mlxsw_sp)
+       devlink_resource_occ_get_register(devlink, MLXSW_SP_RESOURCE_COUNTERS,
+                                         mlxsw_sp_counter_pool_occ_get, pool);
+-      map_size = BITS_TO_LONGS(pool->pool_size) * sizeof(unsigned long);
+-
+-      pool->usage = kzalloc(map_size, GFP_KERNEL);
++      pool->usage = bitmap_zalloc(pool->pool_size, GFP_KERNEL);
+       if (!pool->usage) {
+               err = -ENOMEM;
+               goto err_usage_alloc;
+@@ -158,7 +155,7 @@ int mlxsw_sp_counter_pool_init(struct mlxsw_sp *mlxsw_sp)
+       return 0;
+ err_sub_pools_init:
+-      kfree(pool->usage);
++      bitmap_free(pool->usage);
+ err_usage_alloc:
+       devlink_resource_occ_get_unregister(devlink,
+                                           MLXSW_SP_RESOURCE_COUNTERS);
+@@ -176,7 +173,7 @@ void mlxsw_sp_counter_pool_fini(struct mlxsw_sp *mlxsw_sp)
+       WARN_ON(find_first_bit(pool->usage, pool->pool_size) !=
+                              pool->pool_size);
+       WARN_ON(atomic_read(&pool->active_entries_count));
+-      kfree(pool->usage);
++      bitmap_free(pool->usage);
+       devlink_resource_occ_get_unregister(devlink,
+                                           MLXSW_SP_RESOURCE_COUNTERS);
+       kfree(pool);
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+index 22fede5cb32c..81c7e8a7fcf5 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+@@ -1635,16 +1635,13 @@ mlxsw_sp_mid *__mlxsw_sp_mc_alloc(struct mlxsw_sp *mlxsw_sp,
+                                 u16 fid)
+ {
+       struct mlxsw_sp_mid *mid;
+-      size_t alloc_size;
+       mid = kzalloc(sizeof(*mid), GFP_KERNEL);
+       if (!mid)
+               return NULL;
+-      alloc_size = sizeof(unsigned long) *
+-                   BITS_TO_LONGS(mlxsw_core_max_ports(mlxsw_sp->core));
+-
+-      mid->ports_in_mid = kzalloc(alloc_size, GFP_KERNEL);
++      mid->ports_in_mid = bitmap_zalloc(mlxsw_core_max_ports(mlxsw_sp->core),
++                                        GFP_KERNEL);
+       if (!mid->ports_in_mid)
+               goto err_ports_in_mid_alloc;
+@@ -1663,7 +1660,7 @@ mlxsw_sp_mid *__mlxsw_sp_mc_alloc(struct mlxsw_sp *mlxsw_sp,
+       return mid;
+ err_write_mdb_entry:
+-      kfree(mid->ports_in_mid);
++      bitmap_free(mid->ports_in_mid);
+ err_ports_in_mid_alloc:
+       kfree(mid);
+       return NULL;
+@@ -1680,7 +1677,7 @@ static int mlxsw_sp_port_remove_from_mid(struct mlxsw_sp_port *mlxsw_sp_port,
+                        mlxsw_core_max_ports(mlxsw_sp->core))) {
+               err = mlxsw_sp_mc_remove_mdb_entry(mlxsw_sp, mid);
+               list_del(&mid->list);
+-              kfree(mid->ports_in_mid);
++              bitmap_free(mid->ports_in_mid);
+               kfree(mid);
+       }
+       return err;
+-- 
+2.43.0
+
diff --git a/queue-5.15/mlxsw-spectrum_acl_erp-fix-error-flow-of-pool-alloca.patch b/queue-5.15/mlxsw-spectrum_acl_erp-fix-error-flow-of-pool-alloca.patch
new file mode 100644 (file)
index 0000000..0994fa0
--- /dev/null
@@ -0,0 +1,185 @@
+From a3b71156d42e03a831406bf804827f95e3b74e8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 16:04:16 +0100
+Subject: mlxsw: spectrum_acl_erp: Fix error flow of pool allocation failure
+
+From: Amit Cohen <amcohen@nvidia.com>
+
+[ Upstream commit 6d6eeabcfaba2fcadf5443b575789ea606f9de83 ]
+
+Lately, a bug was found when many TC filters are added - at some point,
+several bugs are printed to dmesg [1] and the switch is crashed with
+segmentation fault.
+
+The issue starts when gen_pool_free() fails because of unexpected
+behavior - a try to free memory which is already freed, this leads to BUG()
+call which crashes the switch and makes many other bugs.
+
+Trying to track down the unexpected behavior led to a bug in eRP code. The
+function mlxsw_sp_acl_erp_table_alloc() gets a pointer to the allocated
+index, sets the value and returns an error code. When gen_pool_alloc()
+fails it returns address 0, we track it and return -ENOBUFS outside, BUT
+the call for gen_pool_alloc() already override the index in erp_table
+structure. This is a problem when such allocation is done as part of
+table expansion. This is not a new table, which will not be used in case
+of allocation failure. We try to expand eRP table and override the
+current index (non-zero) with zero. Then, it leads to an unexpected
+behavior when address 0 is freed twice. Note that address 0 is valid in
+erp_table->base_index and indeed other tables use it.
+
+gen_pool_alloc() fails in case that there is no space left in the
+pre-allocated pool, in our case, the pool is limited to
+ACL_MAX_ERPT_BANK_SIZE, which is read from hardware. When more than max
+erp entries are required, we exceed the limit and return an error, this
+error leads to "Failed to migrate vregion" print.
+
+Fix this by changing erp_table->base_index only in case of a successful
+allocation.
+
+Add a test case for such a scenario. Without this fix it causes
+segmentation fault:
+
+$ TESTS="max_erp_entries_test" ./tc_flower.sh
+./tc_flower.sh: line 988:  1560 Segmentation fault      tc filter del dev $h2 ingress chain $i protocol ip pref $i handle $j flower &>/dev/null
+
+[1]:
+kernel BUG at lib/genalloc.c:508!
+invalid opcode: 0000 [#1] PREEMPT SMP
+CPU: 6 PID: 3531 Comm: tc Not tainted 6.7.0-rc5-custom-ga6893f479f5e #1
+Hardware name: Mellanox Technologies Ltd. MSN4700/VMOD0010, BIOS 5.11 07/12/2021
+RIP: 0010:gen_pool_free_owner+0xc9/0xe0
+...
+Call Trace:
+ <TASK>
+ __mlxsw_sp_acl_erp_table_other_dec+0x70/0xa0 [mlxsw_spectrum]
+ mlxsw_sp_acl_erp_mask_destroy+0xf5/0x110 [mlxsw_spectrum]
+ objagg_obj_root_destroy+0x18/0x80 [objagg]
+ objagg_obj_destroy+0x12c/0x130 [objagg]
+ mlxsw_sp_acl_erp_mask_put+0x37/0x50 [mlxsw_spectrum]
+ mlxsw_sp_acl_ctcam_region_entry_remove+0x74/0xa0 [mlxsw_spectrum]
+ mlxsw_sp_acl_ctcam_entry_del+0x1e/0x40 [mlxsw_spectrum]
+ mlxsw_sp_acl_tcam_ventry_del+0x78/0xd0 [mlxsw_spectrum]
+ mlxsw_sp_flower_destroy+0x4d/0x70 [mlxsw_spectrum]
+ mlxsw_sp_flow_block_cb+0x73/0xb0 [mlxsw_spectrum]
+ tc_setup_cb_destroy+0xc1/0x180
+ fl_hw_destroy_filter+0x94/0xc0 [cls_flower]
+ __fl_delete+0x1ac/0x1c0 [cls_flower]
+ fl_destroy+0xc2/0x150 [cls_flower]
+ tcf_proto_destroy+0x1a/0xa0
+...
+mlxsw_spectrum3 0000:07:00.0: Failed to migrate vregion
+mlxsw_spectrum3 0000:07:00.0: Failed to migrate vregion
+
+Fixes: f465261aa105 ("mlxsw: spectrum_acl: Implement common eRP core")
+Signed-off-by: Amit Cohen <amcohen@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Link: https://lore.kernel.org/r/4cfca254dfc0e5d283974801a24371c7b6db5989.1705502064.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlxsw/spectrum_acl_erp.c         |  8 +--
+ .../drivers/net/mlxsw/spectrum-2/tc_flower.sh | 52 ++++++++++++++++++-
+ 2 files changed, 56 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c
+index 4c98950380d5..d231f4d2888b 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c
+@@ -301,6 +301,7 @@ mlxsw_sp_acl_erp_table_alloc(struct mlxsw_sp_acl_erp_core *erp_core,
+                            unsigned long *p_index)
+ {
+       unsigned int num_rows, entry_size;
++      unsigned long index;
+       /* We only allow allocations of entire rows */
+       if (num_erps % erp_core->num_erp_banks != 0)
+@@ -309,10 +310,11 @@ mlxsw_sp_acl_erp_table_alloc(struct mlxsw_sp_acl_erp_core *erp_core,
+       entry_size = erp_core->erpt_entries_size[region_type];
+       num_rows = num_erps / erp_core->num_erp_banks;
+-      *p_index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size);
+-      if (*p_index == 0)
++      index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size);
++      if (!index)
+               return -ENOBUFS;
+-      *p_index -= MLXSW_SP_ACL_ERP_GENALLOC_OFFSET;
++
++      *p_index = index - MLXSW_SP_ACL_ERP_GENALLOC_OFFSET;
+       return 0;
+ }
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh
+index fb850e0ec837..7bf56ea161e3 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh
+@@ -10,7 +10,8 @@ lib_dir=$(dirname $0)/../../../../net/forwarding
+ ALL_TESTS="single_mask_test identical_filters_test two_masks_test \
+       multiple_masks_test ctcam_edge_cases_test delta_simple_test \
+       delta_two_masks_one_key_test delta_simple_rehash_test \
+-      bloom_simple_test bloom_complex_test bloom_delta_test"
++      bloom_simple_test bloom_complex_test bloom_delta_test \
++      max_erp_entries_test"
+ NUM_NETIFS=2
+ source $lib_dir/lib.sh
+ source $lib_dir/tc_common.sh
+@@ -983,6 +984,55 @@ bloom_delta_test()
+       log_test "bloom delta test ($tcflags)"
+ }
++max_erp_entries_test()
++{
++      # The number of eRP entries is limited. Once the maximum number of eRPs
++      # has been reached, filters cannot be added. This test verifies that
++      # when this limit is reached, inserstion fails without crashing.
++
++      RET=0
++
++      local num_masks=32
++      local num_regions=15
++      local chain_failed
++      local mask_failed
++      local ret
++
++      if [[ "$tcflags" != "skip_sw" ]]; then
++              return 0;
++      fi
++
++      for ((i=1; i < $num_regions; i++)); do
++              for ((j=$num_masks; j >= 0; j--)); do
++                      tc filter add dev $h2 ingress chain $i protocol ip \
++                              pref $i handle $j flower $tcflags \
++                              dst_ip 192.1.0.0/$j &> /dev/null
++                      ret=$?
++
++                      if [ $ret -ne 0 ]; then
++                              chain_failed=$i
++                              mask_failed=$j
++                              break 2
++                      fi
++              done
++      done
++
++      # We expect to exceed the maximum number of eRP entries, so that
++      # insertion eventually fails. Otherwise, the test should be adjusted to
++      # add more filters.
++      check_fail $ret "expected to exceed number of eRP entries"
++
++      for ((; i >= 1; i--)); do
++              for ((j=0; j <= $num_masks; j++)); do
++                      tc filter del dev $h2 ingress chain $i protocol ip \
++                              pref $i handle $j flower &> /dev/null
++              done
++      done
++
++      log_test "max eRP entries test ($tcflags). " \
++              "max chain $chain_failed, mask $mask_failed"
++}
++
+ setup_prepare()
+ {
+       h1=${NETIFS[p1]}
+-- 
+2.43.0
+
diff --git a/queue-5.15/mlxsw-spectrum_acl_tcam-add-missing-mutex_destroy.patch b/queue-5.15/mlxsw-spectrum_acl_tcam-add-missing-mutex_destroy.patch
new file mode 100644 (file)
index 0000000..35e4ae9
--- /dev/null
@@ -0,0 +1,52 @@
+From 7c0369394351558f0d254249c6ff8de4a9766e00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Feb 2023 16:39:19 +0100
+Subject: mlxsw: spectrum_acl_tcam: Add missing mutex_destroy()
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 65823e07b1e4055b6278725fd92f4d7e6f8d53fd ]
+
+Pair mutex_init() with a mutex_destroy() in the error path. Found during
+code review. No functional changes.
+
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 483ae90d8f97 ("mlxsw: spectrum_acl_tcam: Fix stack corruption")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+index 31f7f4c3acc3..c8d9f523242e 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+@@ -52,8 +52,10 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
+               max_regions = max_tcam_regions;
+       tcam->used_regions = bitmap_zalloc(max_regions, GFP_KERNEL);
+-      if (!tcam->used_regions)
+-              return -ENOMEM;
++      if (!tcam->used_regions) {
++              err = -ENOMEM;
++              goto err_alloc_used_regions;
++      }
+       tcam->max_regions = max_regions;
+       max_groups = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_GROUPS);
+@@ -76,6 +78,8 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
+       bitmap_free(tcam->used_groups);
+ err_alloc_used_groups:
+       bitmap_free(tcam->used_regions);
++err_alloc_used_regions:
++      mutex_destroy(&tcam->lock);
+       return err;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.15/mlxsw-spectrum_acl_tcam-fix-stack-corruption.patch b/queue-5.15/mlxsw-spectrum_acl_tcam-fix-stack-corruption.patch
new file mode 100644 (file)
index 0000000..3d8fa77
--- /dev/null
@@ -0,0 +1,162 @@
+From 5e224c0d6ace0ef25be32df1b7dbcbd8f005a409 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 16:04:18 +0100
+Subject: mlxsw: spectrum_acl_tcam: Fix stack corruption
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 483ae90d8f976f8339cf81066312e1329f2d3706 ]
+
+When tc filters are first added to a net device, the corresponding local
+port gets bound to an ACL group in the device. The group contains a list
+of ACLs. In turn, each ACL points to a different TCAM region where the
+filters are stored. During forwarding, the ACLs are sequentially
+evaluated until a match is found.
+
+One reason to place filters in different regions is when they are added
+with decreasing priorities and in an alternating order so that two
+consecutive filters can never fit in the same region because of their
+key usage.
+
+In Spectrum-2 and newer ASICs the firmware started to report that the
+maximum number of ACLs in a group is more than 16, but the layout of the
+register that configures ACL groups (PAGT) was not updated to account
+for that. It is therefore possible to hit stack corruption [1] in the
+rare case where more than 16 ACLs in a group are required.
+
+Fix by limiting the maximum ACL group size to the minimum between what
+the firmware reports and the maximum ACLs that fit in the PAGT register.
+
+Add a test case to make sure the machine does not crash when this
+condition is hit.
+
+[1]
+Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: mlxsw_sp_acl_tcam_group_update+0x116/0x120
+[...]
+ dump_stack_lvl+0x36/0x50
+ panic+0x305/0x330
+ __stack_chk_fail+0x15/0x20
+ mlxsw_sp_acl_tcam_group_update+0x116/0x120
+ mlxsw_sp_acl_tcam_group_region_attach+0x69/0x110
+ mlxsw_sp_acl_tcam_vchunk_get+0x492/0xa20
+ mlxsw_sp_acl_tcam_ventry_add+0x25/0xe0
+ mlxsw_sp_acl_rule_add+0x47/0x240
+ mlxsw_sp_flower_replace+0x1a9/0x1d0
+ tc_setup_cb_add+0xdc/0x1c0
+ fl_hw_replace_filter+0x146/0x1f0
+ fl_change+0xc17/0x1360
+ tc_new_tfilter+0x472/0xb90
+ rtnetlink_rcv_msg+0x313/0x3b0
+ netlink_rcv_skb+0x58/0x100
+ netlink_unicast+0x244/0x390
+ netlink_sendmsg+0x1e4/0x440
+ ____sys_sendmsg+0x164/0x260
+ ___sys_sendmsg+0x9a/0xe0
+ __sys_sendmsg+0x7a/0xc0
+ do_syscall_64+0x40/0xe0
+ entry_SYSCALL_64_after_hwframe+0x63/0x6b
+
+Fixes: c3ab435466d5 ("mlxsw: spectrum: Extend to support Spectrum-2 ASIC")
+Reported-by: Orel Hagag <orelh@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Amit Cohen <amcohen@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Link: https://lore.kernel.org/r/2d91c89afba59c22587b444994ae419dbea8d876.1705502064.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlxsw/spectrum_acl_tcam.c        |  2 +
+ .../drivers/net/mlxsw/spectrum-2/tc_flower.sh | 56 ++++++++++++++++++-
+ 2 files changed, 57 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+index ab897b8be39f..483c8b75bebb 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+@@ -1519,6 +1519,8 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
+       tcam->max_groups = max_groups;
+       tcam->max_group_size = MLXSW_CORE_RES_GET(mlxsw_sp->core,
+                                                 ACL_MAX_GROUP_SIZE);
++      tcam->max_group_size = min_t(unsigned int, tcam->max_group_size,
++                                   MLXSW_REG_PAGT_ACL_MAX_NUM);
+       err = ops->init(mlxsw_sp, tcam->priv, tcam);
+       if (err)
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh
+index 7bf56ea161e3..616d3581419c 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh
+@@ -11,7 +11,7 @@ ALL_TESTS="single_mask_test identical_filters_test two_masks_test \
+       multiple_masks_test ctcam_edge_cases_test delta_simple_test \
+       delta_two_masks_one_key_test delta_simple_rehash_test \
+       bloom_simple_test bloom_complex_test bloom_delta_test \
+-      max_erp_entries_test"
++      max_erp_entries_test max_group_size_test"
+ NUM_NETIFS=2
+ source $lib_dir/lib.sh
+ source $lib_dir/tc_common.sh
+@@ -1033,6 +1033,60 @@ max_erp_entries_test()
+               "max chain $chain_failed, mask $mask_failed"
+ }
++max_group_size_test()
++{
++      # The number of ACLs in an ACL group is limited. Once the maximum
++      # number of ACLs has been reached, filters cannot be added. This test
++      # verifies that when this limit is reached, insertion fails without
++      # crashing.
++
++      RET=0
++
++      local num_acls=32
++      local max_size
++      local ret
++
++      if [[ "$tcflags" != "skip_sw" ]]; then
++              return 0;
++      fi
++
++      for ((i=1; i < $num_acls; i++)); do
++              if [[ $(( i % 2 )) == 1 ]]; then
++                      tc filter add dev $h2 ingress pref $i proto ipv4 \
++                              flower $tcflags dst_ip 198.51.100.1/32 \
++                              ip_proto tcp tcp_flags 0x01/0x01 \
++                              action drop &> /dev/null
++              else
++                      tc filter add dev $h2 ingress pref $i proto ipv6 \
++                              flower $tcflags dst_ip 2001:db8:1::1/128 \
++                              action drop &> /dev/null
++              fi
++
++              ret=$?
++              [[ $ret -ne 0 ]] && max_size=$((i - 1)) && break
++      done
++
++      # We expect to exceed the maximum number of ACLs in a group, so that
++      # insertion eventually fails. Otherwise, the test should be adjusted to
++      # add more filters.
++      check_fail $ret "expected to exceed number of ACLs in a group"
++
++      for ((; i >= 1; i--)); do
++              if [[ $(( i % 2 )) == 1 ]]; then
++                      tc filter del dev $h2 ingress pref $i proto ipv4 \
++                              flower $tcflags dst_ip 198.51.100.1/32 \
++                              ip_proto tcp tcp_flags 0x01/0x01 \
++                              action drop &> /dev/null
++              else
++                      tc filter del dev $h2 ingress pref $i proto ipv6 \
++                              flower $tcflags dst_ip 2001:db8:1::1/128 \
++                              action drop &> /dev/null
++              fi
++      done
++
++      log_test "max ACL group size test ($tcflags). max size $max_size"
++}
++
+ setup_prepare()
+ {
+       h1=${NETIFS[p1]}
+-- 
+2.43.0
+
diff --git a/queue-5.15/mlxsw-spectrum_acl_tcam-make-fini-symmetric-to-init.patch b/queue-5.15/mlxsw-spectrum_acl_tcam-make-fini-symmetric-to-init.patch
new file mode 100644 (file)
index 0000000..6472e28
--- /dev/null
@@ -0,0 +1,42 @@
+From 357d6bc4b8a4a6f8c5271cfcbc3db3a579a94cf4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Feb 2023 16:39:20 +0100
+Subject: mlxsw: spectrum_acl_tcam: Make fini symmetric to init
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 61fe3b9102ac84ba479ab84d8f5454af2e21e468 ]
+
+Move mutex_destroy() to the end to make the function symmetric with
+mlxsw_sp_acl_tcam_init(). No functional changes.
+
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 483ae90d8f97 ("mlxsw: spectrum_acl_tcam: Fix stack corruption")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+index c8d9f523242e..08d91bfa7b39 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+@@ -88,10 +88,10 @@ void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
+ {
+       const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
+-      mutex_destroy(&tcam->lock);
+       ops->fini(mlxsw_sp, tcam->priv);
+       bitmap_free(tcam->used_groups);
+       bitmap_free(tcam->used_regions);
++      mutex_destroy(&tcam->lock);
+ }
+ int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp,
+-- 
+2.43.0
+
diff --git a/queue-5.15/mlxsw-spectrum_acl_tcam-reorder-functions-to-avoid-f.patch b/queue-5.15/mlxsw-spectrum_acl_tcam-reorder-functions-to-avoid-f.patch
new file mode 100644 (file)
index 0000000..8493ef3
--- /dev/null
@@ -0,0 +1,176 @@
+From 495d4848d549853cada7c608e08c7cda8906d720 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Feb 2023 16:39:21 +0100
+Subject: mlxsw: spectrum_acl_tcam: Reorder functions to avoid forward
+ declarations
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 194ab9476089bbfc021073214e071a404e375ee6 ]
+
+Move the initialization and de-initialization code further below in
+order to avoid forward declarations in the next patch. No functional
+changes.
+
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 483ae90d8f97 ("mlxsw: spectrum_acl_tcam: Fix stack corruption")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlxsw/spectrum_acl_tcam.c        | 130 +++++++++---------
+ 1 file changed, 65 insertions(+), 65 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+index 08d91bfa7b39..ab897b8be39f 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+@@ -29,71 +29,6 @@ size_t mlxsw_sp_acl_tcam_priv_size(struct mlxsw_sp *mlxsw_sp)
+ #define MLXSW_SP_ACL_TCAM_VREGION_REHASH_INTRVL_MIN 3000 /* ms */
+ #define MLXSW_SP_ACL_TCAM_VREGION_REHASH_CREDITS 100 /* number of entries */
+-int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
+-                         struct mlxsw_sp_acl_tcam *tcam)
+-{
+-      const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
+-      u64 max_tcam_regions;
+-      u64 max_regions;
+-      u64 max_groups;
+-      int err;
+-
+-      mutex_init(&tcam->lock);
+-      tcam->vregion_rehash_intrvl =
+-                      MLXSW_SP_ACL_TCAM_VREGION_REHASH_INTRVL_DFLT;
+-      INIT_LIST_HEAD(&tcam->vregion_list);
+-
+-      max_tcam_regions = MLXSW_CORE_RES_GET(mlxsw_sp->core,
+-                                            ACL_MAX_TCAM_REGIONS);
+-      max_regions = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_REGIONS);
+-
+-      /* Use 1:1 mapping between ACL region and TCAM region */
+-      if (max_tcam_regions < max_regions)
+-              max_regions = max_tcam_regions;
+-
+-      tcam->used_regions = bitmap_zalloc(max_regions, GFP_KERNEL);
+-      if (!tcam->used_regions) {
+-              err = -ENOMEM;
+-              goto err_alloc_used_regions;
+-      }
+-      tcam->max_regions = max_regions;
+-
+-      max_groups = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_GROUPS);
+-      tcam->used_groups = bitmap_zalloc(max_groups, GFP_KERNEL);
+-      if (!tcam->used_groups) {
+-              err = -ENOMEM;
+-              goto err_alloc_used_groups;
+-      }
+-      tcam->max_groups = max_groups;
+-      tcam->max_group_size = MLXSW_CORE_RES_GET(mlxsw_sp->core,
+-                                               ACL_MAX_GROUP_SIZE);
+-
+-      err = ops->init(mlxsw_sp, tcam->priv, tcam);
+-      if (err)
+-              goto err_tcam_init;
+-
+-      return 0;
+-
+-err_tcam_init:
+-      bitmap_free(tcam->used_groups);
+-err_alloc_used_groups:
+-      bitmap_free(tcam->used_regions);
+-err_alloc_used_regions:
+-      mutex_destroy(&tcam->lock);
+-      return err;
+-}
+-
+-void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
+-                          struct mlxsw_sp_acl_tcam *tcam)
+-{
+-      const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
+-
+-      ops->fini(mlxsw_sp, tcam->priv);
+-      bitmap_free(tcam->used_groups);
+-      bitmap_free(tcam->used_regions);
+-      mutex_destroy(&tcam->lock);
+-}
+-
+ int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp,
+                                  struct mlxsw_sp_acl_rule_info *rulei,
+                                  u32 *priority, bool fillup_priority)
+@@ -1546,6 +1481,71 @@ mlxsw_sp_acl_tcam_vregion_rehash(struct mlxsw_sp *mlxsw_sp,
+               mlxsw_sp_acl_tcam_vregion_rehash_end(mlxsw_sp, vregion, ctx);
+ }
++int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
++                         struct mlxsw_sp_acl_tcam *tcam)
++{
++      const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
++      u64 max_tcam_regions;
++      u64 max_regions;
++      u64 max_groups;
++      int err;
++
++      mutex_init(&tcam->lock);
++      tcam->vregion_rehash_intrvl =
++                      MLXSW_SP_ACL_TCAM_VREGION_REHASH_INTRVL_DFLT;
++      INIT_LIST_HEAD(&tcam->vregion_list);
++
++      max_tcam_regions = MLXSW_CORE_RES_GET(mlxsw_sp->core,
++                                            ACL_MAX_TCAM_REGIONS);
++      max_regions = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_REGIONS);
++
++      /* Use 1:1 mapping between ACL region and TCAM region */
++      if (max_tcam_regions < max_regions)
++              max_regions = max_tcam_regions;
++
++      tcam->used_regions = bitmap_zalloc(max_regions, GFP_KERNEL);
++      if (!tcam->used_regions) {
++              err = -ENOMEM;
++              goto err_alloc_used_regions;
++      }
++      tcam->max_regions = max_regions;
++
++      max_groups = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_GROUPS);
++      tcam->used_groups = bitmap_zalloc(max_groups, GFP_KERNEL);
++      if (!tcam->used_groups) {
++              err = -ENOMEM;
++              goto err_alloc_used_groups;
++      }
++      tcam->max_groups = max_groups;
++      tcam->max_group_size = MLXSW_CORE_RES_GET(mlxsw_sp->core,
++                                                ACL_MAX_GROUP_SIZE);
++
++      err = ops->init(mlxsw_sp, tcam->priv, tcam);
++      if (err)
++              goto err_tcam_init;
++
++      return 0;
++
++err_tcam_init:
++      bitmap_free(tcam->used_groups);
++err_alloc_used_groups:
++      bitmap_free(tcam->used_regions);
++err_alloc_used_regions:
++      mutex_destroy(&tcam->lock);
++      return err;
++}
++
++void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
++                          struct mlxsw_sp_acl_tcam *tcam)
++{
++      const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
++
++      ops->fini(mlxsw_sp, tcam->priv);
++      bitmap_free(tcam->used_groups);
++      bitmap_free(tcam->used_regions);
++      mutex_destroy(&tcam->lock);
++}
++
+ static const enum mlxsw_afk_element mlxsw_sp_acl_tcam_pattern_ipv4[] = {
+       MLXSW_AFK_ELEMENT_SRC_SYS_PORT,
+       MLXSW_AFK_ELEMENT_DMAC_32_47,
+-- 
+2.43.0
+
diff --git a/queue-5.15/mptcp-drop-unused-sk-in-mptcp_get_options.patch b/queue-5.15/mptcp-drop-unused-sk-in-mptcp_get_options.patch
new file mode 100644 (file)
index 0000000..b936984
--- /dev/null
@@ -0,0 +1,113 @@
+From a315cfe48b1b5f1b186a6cf7be60a027da3816e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Feb 2022 18:11:25 -0800
+Subject: mptcp: drop unused sk in mptcp_get_options
+
+From: Geliang Tang <geliang.tang@suse.com>
+
+[ Upstream commit 0799e21b5a76d9f14d8a8f024d0b6b9847ad1a03 ]
+
+The parameter 'sk' became useless since the code using it was dropped
+from mptcp_get_options() in the commit 8d548ea1dd15 ("mptcp: do not set
+unconditionally csum_reqd on incoming opt"). Let's drop it.
+
+Signed-off-by: Geliang Tang <geliang.tang@suse.com>
+Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: c1665273bdc7 ("mptcp: strict validation before using mp_opt->hmac")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/options.c  |  5 ++---
+ net/mptcp/protocol.h |  3 +--
+ net/mptcp/subflow.c  | 10 +++++-----
+ 3 files changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/net/mptcp/options.c b/net/mptcp/options.c
+index c7d6997b31c8..3b4ce8a06f99 100644
+--- a/net/mptcp/options.c
++++ b/net/mptcp/options.c
+@@ -354,8 +354,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
+       }
+ }
+-void mptcp_get_options(const struct sock *sk,
+-                     const struct sk_buff *skb,
++void mptcp_get_options(const struct sk_buff *skb,
+                      struct mptcp_options_received *mp_opt)
+ {
+       const struct tcphdr *th = tcp_hdr(skb);
+@@ -1091,7 +1090,7 @@ bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
+               return true;
+       }
+-      mptcp_get_options(sk, skb, &mp_opt);
++      mptcp_get_options(skb, &mp_opt);
+       /* The subflow can be in close state only if check_fully_established()
+        * just sent a reset. If so, tell the caller to ignore the current packet.
+diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
+index e193b710b471..78aa6125eafb 100644
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -636,8 +636,7 @@ int __init mptcp_proto_v6_init(void);
+ struct sock *mptcp_sk_clone(const struct sock *sk,
+                           const struct mptcp_options_received *mp_opt,
+                           struct request_sock *req);
+-void mptcp_get_options(const struct sock *sk,
+-                     const struct sk_buff *skb,
++void mptcp_get_options(const struct sk_buff *skb,
+                      struct mptcp_options_received *mp_opt);
+ void mptcp_finish_connect(struct sock *sk);
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 666f6720db76..a1349c6eda46 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -152,7 +152,7 @@ static int subflow_check_req(struct request_sock *req,
+               return -EINVAL;
+ #endif
+-      mptcp_get_options(sk_listener, skb, &mp_opt);
++      mptcp_get_options(skb, &mp_opt);
+       opt_mp_capable = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPC);
+       opt_mp_join = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ);
+@@ -249,7 +249,7 @@ int mptcp_subflow_init_cookie_req(struct request_sock *req,
+       int err;
+       subflow_init_req(req, sk_listener);
+-      mptcp_get_options(sk_listener, skb, &mp_opt);
++      mptcp_get_options(skb, &mp_opt);
+       opt_mp_capable = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPC);
+       opt_mp_join = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ);
+@@ -407,7 +407,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
+       subflow->ssn_offset = TCP_SKB_CB(skb)->seq;
+       pr_debug("subflow=%p synack seq=%x", subflow, subflow->ssn_offset);
+-      mptcp_get_options(sk, skb, &mp_opt);
++      mptcp_get_options(skb, &mp_opt);
+       if (subflow->request_mptcp) {
+               if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPC)) {
+                       MPTCP_INC_STATS(sock_net(sk),
+@@ -687,7 +687,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
+                * reordered MPC will cause fallback, but we don't have other
+                * options.
+                */
+-              mptcp_get_options(sk, skb, &mp_opt);
++              mptcp_get_options(skb, &mp_opt);
+               if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPC)) {
+                       fallback = true;
+                       goto create_child;
+@@ -697,7 +697,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
+               if (!new_msk)
+                       fallback = true;
+       } else if (subflow_req->mp_join) {
+-              mptcp_get_options(sk, skb, &mp_opt);
++              mptcp_get_options(skb, &mp_opt);
+               if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ) ||
+                   !subflow_hmac_valid(req, &mp_opt) ||
+                   !mptcp_can_accept_new_subflow(subflow_req->msk)) {
+-- 
+2.43.0
+
diff --git a/queue-5.15/mptcp-mptcp_parse_option-fix-for-mptcpopt_mp_join.patch b/queue-5.15/mptcp-mptcp_parse_option-fix-for-mptcpopt_mp_join.patch
new file mode 100644 (file)
index 0000000..96171ca
--- /dev/null
@@ -0,0 +1,77 @@
+From 07710ea21122473c7761312bf2792dcab5508fed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 19:49:13 +0000
+Subject: mptcp: mptcp_parse_option() fix for MPTCPOPT_MP_JOIN
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 89e23277f9c16df6f9f9c1a1a07f8f132339c15c ]
+
+mptcp_parse_option() currently sets OPTIONS_MPTCP_MPJ, for the three
+possible cases handled for MPTCPOPT_MP_JOIN option.
+
+OPTIONS_MPTCP_MPJ is the combination of three flags:
+- OPTION_MPTCP_MPJ_SYN
+- OPTION_MPTCP_MPJ_SYNACK
+- OPTION_MPTCP_MPJ_ACK
+
+This is a problem, because backup, join_id, token, nonce and/or hmac fields
+could be left uninitialized in some cases.
+
+Distinguish the three cases, as following patches will need this step.
+
+Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Florian Westphal <fw@strlen.de>
+Cc: Peter Krystad <peter.krystad@linux.intel.com>
+Cc: Matthieu Baerts <matttbe@kernel.org>
+Cc: Mat Martineau <martineau@kernel.org>
+Cc: Geliang Tang <geliang.tang@linux.dev>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Link: https://lore.kernel.org/r/20240111194917.4044654-2-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/options.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/mptcp/options.c b/net/mptcp/options.c
+index 012e0e352276..c7d6997b31c8 100644
+--- a/net/mptcp/options.c
++++ b/net/mptcp/options.c
+@@ -118,8 +118,8 @@ static void mptcp_parse_option(const struct sk_buff *skb,
+               break;
+       case MPTCPOPT_MP_JOIN:
+-              mp_opt->suboptions |= OPTIONS_MPTCP_MPJ;
+               if (opsize == TCPOLEN_MPTCP_MPJ_SYN) {
++                      mp_opt->suboptions |= OPTION_MPTCP_MPJ_SYN;
+                       mp_opt->backup = *ptr++ & MPTCPOPT_BACKUP;
+                       mp_opt->join_id = *ptr++;
+                       mp_opt->token = get_unaligned_be32(ptr);
+@@ -130,6 +130,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
+                                mp_opt->backup, mp_opt->join_id,
+                                mp_opt->token, mp_opt->nonce);
+               } else if (opsize == TCPOLEN_MPTCP_MPJ_SYNACK) {
++                      mp_opt->suboptions |= OPTION_MPTCP_MPJ_SYNACK;
+                       mp_opt->backup = *ptr++ & MPTCPOPT_BACKUP;
+                       mp_opt->join_id = *ptr++;
+                       mp_opt->thmac = get_unaligned_be64(ptr);
+@@ -140,11 +141,10 @@ static void mptcp_parse_option(const struct sk_buff *skb,
+                                mp_opt->backup, mp_opt->join_id,
+                                mp_opt->thmac, mp_opt->nonce);
+               } else if (opsize == TCPOLEN_MPTCP_MPJ_ACK) {
++                      mp_opt->suboptions |= OPTION_MPTCP_MPJ_ACK;
+                       ptr += 2;
+                       memcpy(mp_opt->hmac, ptr, MPTCPOPT_HMAC_LEN);
+                       pr_debug("MP_JOIN hmac");
+-              } else {
+-                      mp_opt->suboptions &= ~OPTIONS_MPTCP_MPJ;
+               }
+               break;
+-- 
+2.43.0
+
diff --git a/queue-5.15/mptcp-strict-validation-before-using-mp_opt-hmac.patch b/queue-5.15/mptcp-strict-validation-before-using-mp_opt-hmac.patch
new file mode 100644 (file)
index 0000000..5dc0bfc
--- /dev/null
@@ -0,0 +1,47 @@
+From 25885a0904ce38e632fd319f709cdacd5ae4c043 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 19:49:14 +0000
+Subject: mptcp: strict validation before using mp_opt->hmac
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit c1665273bdc7c201766c65e561c06711f2e050dc ]
+
+mp_opt->hmac contains uninitialized data unless OPTION_MPTCP_MPJ_ACK
+was set in mptcp_parse_option().
+
+We must refine the condition before we call subflow_hmac_valid().
+
+Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Florian Westphal <fw@strlen.de>
+Cc: Peter Krystad <peter.krystad@linux.intel.com>
+Cc: Matthieu Baerts <matttbe@kernel.org>
+Cc: Mat Martineau <martineau@kernel.org>
+Cc: Geliang Tang <geliang.tang@linux.dev>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Link: https://lore.kernel.org/r/20240111194917.4044654-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/subflow.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index a1349c6eda46..c2c30724b322 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -698,7 +698,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
+                       fallback = true;
+       } else if (subflow_req->mp_join) {
+               mptcp_get_options(skb, &mp_opt);
+-              if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ) ||
++              if (!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK) ||
+                   !subflow_hmac_valid(req, &mp_opt) ||
+                   !mptcp_can_accept_new_subflow(subflow_req->msk)) {
+                       SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
+-- 
+2.43.0
+
diff --git a/queue-5.15/mptcp-use-option_mptcp_mpj_syn-in-subflow_check_req.patch b/queue-5.15/mptcp-use-option_mptcp_mpj_syn-in-subflow_check_req.patch
new file mode 100644 (file)
index 0000000..f016ddc
--- /dev/null
@@ -0,0 +1,105 @@
+From 2ef44173346ebd42a8f49153332acbf455a5a3cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 19:49:16 +0000
+Subject: mptcp: use OPTION_MPTCP_MPJ_SYN in subflow_check_req()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 66ff70df1a919a066942844bb095d6fcb748d78d ]
+
+syzbot reported that subflow_check_req() was using uninitialized data in
+subflow_check_req() [1]
+
+This is because mp_opt.token is only set when OPTION_MPTCP_MPJ_SYN is also set.
+
+While we are are it, fix mptcp_subflow_init_cookie_req()
+to test for OPTION_MPTCP_MPJ_ACK.
+
+[1]
+
+BUG: KMSAN: uninit-value in subflow_token_join_request net/mptcp/subflow.c:91 [inline]
+ BUG: KMSAN: uninit-value in subflow_check_req+0x1028/0x15d0 net/mptcp/subflow.c:209
+  subflow_token_join_request net/mptcp/subflow.c:91 [inline]
+  subflow_check_req+0x1028/0x15d0 net/mptcp/subflow.c:209
+  subflow_v6_route_req+0x269/0x410 net/mptcp/subflow.c:367
+  tcp_conn_request+0x153a/0x4240 net/ipv4/tcp_input.c:7164
+ subflow_v6_conn_request+0x3ee/0x510
+  tcp_rcv_state_process+0x2e1/0x4ac0 net/ipv4/tcp_input.c:6659
+  tcp_v6_do_rcv+0x11bf/0x1fe0 net/ipv6/tcp_ipv6.c:1669
+  tcp_v6_rcv+0x480b/0x4fb0 net/ipv6/tcp_ipv6.c:1900
+  ip6_protocol_deliver_rcu+0xda6/0x2a60 net/ipv6/ip6_input.c:438
+  ip6_input_finish net/ipv6/ip6_input.c:483 [inline]
+  NF_HOOK include/linux/netfilter.h:314 [inline]
+  ip6_input+0x15d/0x430 net/ipv6/ip6_input.c:492
+  dst_input include/net/dst.h:461 [inline]
+  ip6_rcv_finish+0x5db/0x870 net/ipv6/ip6_input.c:79
+  NF_HOOK include/linux/netfilter.h:314 [inline]
+  ipv6_rcv+0xda/0x390 net/ipv6/ip6_input.c:310
+  __netif_receive_skb_one_core net/core/dev.c:5532 [inline]
+  __netif_receive_skb+0x1a6/0x5a0 net/core/dev.c:5646
+  netif_receive_skb_internal net/core/dev.c:5732 [inline]
+  netif_receive_skb+0x58/0x660 net/core/dev.c:5791
+  tun_rx_batched+0x3ee/0x980 drivers/net/tun.c:1555
+  tun_get_user+0x53af/0x66d0 drivers/net/tun.c:2002
+  tun_chr_write_iter+0x3af/0x5d0 drivers/net/tun.c:2048
+  call_write_iter include/linux/fs.h:2020 [inline]
+  new_sync_write fs/read_write.c:491 [inline]
+  vfs_write+0x8ef/0x1490 fs/read_write.c:584
+  ksys_write+0x20f/0x4c0 fs/read_write.c:637
+  __do_sys_write fs/read_write.c:649 [inline]
+  __se_sys_write fs/read_write.c:646 [inline]
+  __x64_sys_write+0x93/0xd0 fs/read_write.c:646
+  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+  do_syscall_64+0x44/0x110 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x63/0x6b
+
+Local variable mp_opt created at:
+  subflow_check_req+0x6d/0x15d0 net/mptcp/subflow.c:145
+  subflow_v6_route_req+0x269/0x410 net/mptcp/subflow.c:367
+
+CPU: 1 PID: 5924 Comm: syz-executor.3 Not tainted 6.7.0-rc8-syzkaller-00055-g5eff55d725a4 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023
+
+Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Florian Westphal <fw@strlen.de>
+Cc: Peter Krystad <peter.krystad@linux.intel.com>
+Cc: Matthieu Baerts <matttbe@kernel.org>
+Cc: Mat Martineau <martineau@kernel.org>
+Cc: Geliang Tang <geliang.tang@linux.dev>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Link: https://lore.kernel.org/r/20240111194917.4044654-5-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/subflow.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 297d2465c413..099bdfc12da9 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -155,7 +155,7 @@ static int subflow_check_req(struct request_sock *req,
+       mptcp_get_options(skb, &mp_opt);
+       opt_mp_capable = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPC);
+-      opt_mp_join = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ);
++      opt_mp_join = !!(mp_opt.suboptions & OPTION_MPTCP_MPJ_SYN);
+       if (opt_mp_capable) {
+               SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE);
+@@ -252,7 +252,7 @@ int mptcp_subflow_init_cookie_req(struct request_sock *req,
+       mptcp_get_options(skb, &mp_opt);
+       opt_mp_capable = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPC);
+-      opt_mp_join = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ);
++      opt_mp_join = !!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK);
+       if (opt_mp_capable && opt_mp_join)
+               return -EINVAL;
+-- 
+2.43.0
+
diff --git a/queue-5.15/mptcp-use-option_mptcp_mpj_synack-in-subflow_finish_.patch b/queue-5.15/mptcp-use-option_mptcp_mpj_synack-in-subflow_finish_.patch
new file mode 100644 (file)
index 0000000..221583b
--- /dev/null
@@ -0,0 +1,46 @@
+From 88bd7ab728f8cfa016ebbd0a1de3b2e31d2d8365 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 19:49:15 +0000
+Subject: mptcp: use OPTION_MPTCP_MPJ_SYNACK in subflow_finish_connect()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit be1d9d9d38da922bd4beeec5b6dd821ff5a1dfeb ]
+
+subflow_finish_connect() uses four fields (backup, join_id, thmac, none)
+that may contain garbage unless OPTION_MPTCP_MPJ_SYNACK has been set
+in mptcp_parse_option()
+
+Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Florian Westphal <fw@strlen.de>
+Cc: Peter Krystad <peter.krystad@linux.intel.com>
+Cc: Matthieu Baerts <matttbe@kernel.org>
+Cc: Mat Martineau <martineau@kernel.org>
+Cc: Geliang Tang <geliang.tang@linux.dev>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Link: https://lore.kernel.org/r/20240111194917.4044654-4-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/subflow.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index c2c30724b322..297d2465c413 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -432,7 +432,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
+       } else if (subflow->request_join) {
+               u8 hmac[SHA256_DIGEST_SIZE];
+-              if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ)) {
++              if (!(mp_opt.suboptions & OPTION_MPTCP_MPJ_SYNACK)) {
+                       subflow->reset_reason = MPTCP_RST_EMPTCP;
+                       goto do_reset;
+               }
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-dsa-vsc73xx-add-null-pointer-check-to-vsc73xx_gp.patch b/queue-5.15/net-dsa-vsc73xx-add-null-pointer-check-to-vsc73xx_gp.patch
new file mode 100644 (file)
index 0000000..676cacf
--- /dev/null
@@ -0,0 +1,39 @@
+From e5799c4a7453d5ee7535e49d5b2625d63852966e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 15:20:18 +0800
+Subject: net: dsa: vsc73xx: Add null pointer check to vsc73xx_gpio_probe
+
+From: Kunwu Chan <chentao@kylinos.cn>
+
+[ Upstream commit 776dac5a662774f07a876b650ba578d0a62d20db ]
+
+devm_kasprintf() returns a pointer to dynamically allocated memory
+which can be NULL upon failure.
+
+Fixes: 05bd97fc559d ("net: dsa: Add Vitesse VSC73xx DSA router driver")
+Signed-off-by: Kunwu Chan <chentao@kylinos.cn>
+Suggested-by: Jakub Kicinski <kuba@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20240111072018.75971-1-chentao@kylinos.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/vitesse-vsc73xx-core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c
+index 0c0bc78b1788..6b6470ef2ae9 100644
+--- a/drivers/net/dsa/vitesse-vsc73xx-core.c
++++ b/drivers/net/dsa/vitesse-vsc73xx-core.c
+@@ -1119,6 +1119,8 @@ static int vsc73xx_gpio_probe(struct vsc73xx *vsc)
+       vsc->gc.label = devm_kasprintf(vsc->dev, GFP_KERNEL, "VSC%04x",
+                                      vsc->chipid);
++      if (!vsc->gc.label)
++              return -ENOMEM;
+       vsc->gc.ngpio = 4;
+       vsc->gc.owner = THIS_MODULE;
+       vsc->gc.parent = vsc->dev;
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-ethernet-ti-am65-cpsw-fix-max-mtu-to-fit-etherne.patch b/queue-5.15/net-ethernet-ti-am65-cpsw-fix-max-mtu-to-fit-etherne.patch
new file mode 100644 (file)
index 0000000..804bb95
--- /dev/null
@@ -0,0 +1,63 @@
+From da030359709d0d14376a1bdf60145debffbd5cde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jan 2024 08:55:43 +0000
+Subject: net: ethernet: ti: am65-cpsw: Fix max mtu to fit ethernet frames
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sanjuán García, Jorge <Jorge.SanjuanGarcia@duagon.com>
+
+[ Upstream commit 64e47d8afb5ca533b27efc006405e5bcae2c4a7b ]
+
+The value of AM65_CPSW_MAX_PACKET_SIZE represents the maximum length
+of a received frame. This value is written to the register
+AM65_CPSW_PORT_REG_RX_MAXLEN.
+
+The maximum MTU configured on the network device should then leave
+some room for the ethernet headers and frame check. Otherwise, if
+the network interface is configured to its maximum mtu possible,
+the frames will be larger than AM65_CPSW_MAX_PACKET_SIZE and will
+get dropped as oversized.
+
+The switch supports ethernet frame sizes between 64 and 2024 bytes
+(including VLAN) as stated in the technical reference manual, so
+define AM65_CPSW_MAX_PACKET_SIZE with that maximum size.
+
+Fixes: 93a76530316a ("net: ethernet: ti: introduce am65x/j721e gigabit eth subsystem driver")
+Signed-off-by: Jorge Sanjuan Garcia <jorge.sanjuangarcia@duagon.com>
+Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Siddharth Vadapalli <s-vadapalli@ti.com>
+Link: https://lore.kernel.org/r/20240105085530.14070-2-jorge.sanjuangarcia@duagon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index 4aa9477ac597..1fa6f0dacd2d 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -53,7 +53,7 @@
+ #define AM65_CPSW_MAX_PORTS   8
+ #define AM65_CPSW_MIN_PACKET_SIZE     VLAN_ETH_ZLEN
+-#define AM65_CPSW_MAX_PACKET_SIZE     (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)
++#define AM65_CPSW_MAX_PACKET_SIZE     2024
+ #define AM65_CPSW_REG_CTL             0x004
+ #define AM65_CPSW_REG_STAT_PORT_EN    0x014
+@@ -1985,7 +1985,8 @@ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx)
+       eth_hw_addr_set(port->ndev, port->slave.mac_addr);
+       port->ndev->min_mtu = AM65_CPSW_MIN_PACKET_SIZE;
+-      port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE;
++      port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE -
++                            (VLAN_ETH_HLEN + ETH_FCS_LEN);
+       port->ndev->hw_features = NETIF_F_SG |
+                                 NETIF_F_RXCSUM |
+                                 NETIF_F_HW_CSUM |
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-phy-micrel-populate-.soft_reset-for-ksz9131.patch b/queue-5.15/net-phy-micrel-populate-.soft_reset-for-ksz9131.patch
new file mode 100644 (file)
index 0000000..4f9bc8a
--- /dev/null
@@ -0,0 +1,100 @@
+From 5472d1c88e9ab24aff2ea6d9c9c04bcd2e417f7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jan 2024 10:52:42 +0200
+Subject: net: phy: micrel: populate .soft_reset for KSZ9131
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+[ Upstream commit e398822c4751017fe401f57409488f5948d12fb5 ]
+
+The RZ/G3S SMARC Module has 2 KSZ9131 PHYs. In this setup, the KSZ9131 PHY
+is used with the ravb Ethernet driver. It has been discovered that when
+bringing the Ethernet interface down/up continuously, e.g., with the
+following sh script:
+
+$ while :; do ifconfig eth0 down; ifconfig eth0 up; done
+
+the link speed and duplex are wrong after interrupting the bring down/up
+operation even though the Ethernet interface is up. To recover from this
+state the following configuration sequence is necessary (executed
+manually):
+
+$ ifconfig eth0 down
+$ ifconfig eth0 up
+
+The behavior has been identified also on the Microchip SAMA7G5-EK board
+which runs the macb driver and uses the same PHY.
+
+The order of PHY-related operations in ravb_open() is as follows:
+ravb_open() ->
+  ravb_phy_start() ->
+    ravb_phy_init() ->
+      of_phy_connect() ->
+        phy_connect_direct() ->
+         phy_attach_direct() ->
+           phy_init_hw() ->
+             phydev->drv->soft_reset()
+             phydev->drv->config_init()
+             phydev->drv->config_intr()
+           phy_resume()
+             kszphy_resume()
+
+The order of PHY-related operations in ravb_close is as follows:
+ravb_close() ->
+  phy_stop() ->
+    phy_suspend() ->
+      kszphy_suspend() ->
+        genphy_suspend()
+         // set BMCR_PDOWN bit in MII_BMCR
+
+In genphy_suspend() setting the BMCR_PDWN bit in MII_BMCR switches the PHY
+to Software Power-Down (SPD) mode (according to the KSZ9131 datasheet).
+Thus, when opening the interface after it has been  previously closed (via
+ravb_close()), the phydev->drv->config_init() and
+phydev->drv->config_intr() reach the KSZ9131 PHY driver via the
+ksz9131_config_init() and kszphy_config_intr() functions.
+
+KSZ9131 specifies that the MII management interface remains operational
+during SPD (Software Power-Down), but (according to manual):
+- Only access to the standard registers (0 through 31) is supported.
+- Access to MMD address spaces other than MMD address space 1 is possible
+  if the spd_clock_gate_override bit is set.
+- Access to MMD address space 1 is not possible.
+
+The spd_clock_gate_override bit is not used in the KSZ9131 driver.
+
+ksz9131_config_init() configures RGMII delay, pad skews and LEDs by
+accessesing MMD registers other than those in address space 1.
+
+The datasheet for the KSZ9131 does not specify what happens if registers
+from an unsupported address space are accessed while the PHY is in SPD.
+
+To fix the issue the .soft_reset method has been instantiated for KSZ9131,
+too. This resets the PHY to the default state before doing any
+configurations to it, thus switching it out of SPD.
+
+Fixes: bff5b4b37372 ("net: phy: micrel: add Microchip KSZ9131 initial driver")
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/micrel.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
+index 05a8985d7107..dc209ad8a0fe 100644
+--- a/drivers/net/phy/micrel.c
++++ b/drivers/net/phy/micrel.c
+@@ -1728,6 +1728,7 @@ static struct phy_driver ksphy_driver[] = {
+       /* PHY_GBIT_FEATURES */
+       .driver_data    = &ksz9021_type,
+       .probe          = kszphy_probe,
++      .soft_reset     = genphy_soft_reset,
+       .config_init    = ksz9131_config_init,
+       .config_intr    = kszphy_config_intr,
+       .handle_interrupt = kszphy_handle_interrupt,
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-qualcomm-rmnet-fix-global-oob-in-rmnet_policy.patch b/queue-5.15/net-qualcomm-rmnet-fix-global-oob-in-rmnet_policy.patch
new file mode 100644 (file)
index 0000000..918e567
--- /dev/null
@@ -0,0 +1,105 @@
+From e69aa765d4fe31a4320e3ce2680fbdc7cfaedce7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 14:14:00 +0800
+Subject: net: qualcomm: rmnet: fix global oob in rmnet_policy
+
+From: Lin Ma <linma@zju.edu.cn>
+
+[ Upstream commit b33fb5b801c6db408b774a68e7c8722796b59ecc ]
+
+The variable rmnet_link_ops assign a *bigger* maxtype which leads to a
+global out-of-bounds read when parsing the netlink attributes. See bug
+trace below:
+
+==================================================================
+BUG: KASAN: global-out-of-bounds in validate_nla lib/nlattr.c:386 [inline]
+BUG: KASAN: global-out-of-bounds in __nla_validate_parse+0x24af/0x2750 lib/nlattr.c:600
+Read of size 1 at addr ffffffff92c438d0 by task syz-executor.6/84207
+
+CPU: 0 PID: 84207 Comm: syz-executor.6 Tainted: G                 N 6.1.0 #3
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x8b/0xb3 lib/dump_stack.c:106
+ print_address_description mm/kasan/report.c:284 [inline]
+ print_report+0x172/0x475 mm/kasan/report.c:395
+ kasan_report+0xbb/0x1c0 mm/kasan/report.c:495
+ validate_nla lib/nlattr.c:386 [inline]
+ __nla_validate_parse+0x24af/0x2750 lib/nlattr.c:600
+ __nla_parse+0x3e/0x50 lib/nlattr.c:697
+ nla_parse_nested_deprecated include/net/netlink.h:1248 [inline]
+ __rtnl_newlink+0x50a/0x1880 net/core/rtnetlink.c:3485
+ rtnl_newlink+0x64/0xa0 net/core/rtnetlink.c:3594
+ rtnetlink_rcv_msg+0x43c/0xd70 net/core/rtnetlink.c:6091
+ netlink_rcv_skb+0x14f/0x410 net/netlink/af_netlink.c:2540
+ netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline]
+ netlink_unicast+0x54e/0x800 net/netlink/af_netlink.c:1345
+ netlink_sendmsg+0x930/0xe50 net/netlink/af_netlink.c:1921
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ sock_sendmsg+0x154/0x190 net/socket.c:734
+ ____sys_sendmsg+0x6df/0x840 net/socket.c:2482
+ ___sys_sendmsg+0x110/0x1b0 net/socket.c:2536
+ __sys_sendmsg+0xf3/0x1c0 net/socket.c:2565
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+RIP: 0033:0x7fdcf2072359
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 f1 19 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007fdcf13e3168 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007fdcf219ff80 RCX: 00007fdcf2072359
+RDX: 0000000000000000 RSI: 0000000020000200 RDI: 0000000000000003
+RBP: 00007fdcf20bd493 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+R13: 00007fffbb8d7bdf R14: 00007fdcf13e3300 R15: 0000000000022000
+ </TASK>
+
+The buggy address belongs to the variable:
+ rmnet_policy+0x30/0xe0
+
+The buggy address belongs to the physical page:
+page:0000000065bdeb3c refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x155243
+flags: 0x200000000001000(reserved|node=0|zone=2)
+raw: 0200000000001000 ffffea00055490c8 ffffea00055490c8 0000000000000000
+raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
+page dumped because: kasan: bad access detected
+
+Memory state around the buggy address:
+ ffffffff92c43780: f9 f9 f9 f9 00 00 00 02 f9 f9 f9 f9 00 00 00 07
+ ffffffff92c43800: f9 f9 f9 f9 00 00 00 05 f9 f9 f9 f9 06 f9 f9 f9
+>ffffffff92c43880: f9 f9 f9 f9 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9
+                                                 ^
+ ffffffff92c43900: 00 00 00 00 00 00 00 00 07 f9 f9 f9 f9 f9 f9 f9
+ ffffffff92c43980: 00 00 00 07 f9 f9 f9 f9 00 00 00 05 f9 f9 f9 f9
+
+According to the comment of `nla_parse_nested_deprecated`, the maxtype
+should be len(destination array) - 1. Hence use `IFLA_RMNET_MAX` here.
+
+Fixes: 14452ca3b5ce ("net: qualcomm: rmnet: Export mux_id and flags to netlink")
+Signed-off-by: Lin Ma <linma@zju.edu.cn>
+Reviewed-by: Subash Abhinov Kasiviswanathan <quic_subashab@quicinc.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://lore.kernel.org/r/20240110061400.3356108-1-linma@zju.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+index 27b1663c476e..64b209a0ad21 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+@@ -391,7 +391,7 @@ static int rmnet_fill_info(struct sk_buff *skb, const struct net_device *dev)
+ struct rtnl_link_ops rmnet_link_ops __read_mostly = {
+       .kind           = "rmnet",
+-      .maxtype        = __IFLA_RMNET_MAX,
++      .maxtype        = IFLA_RMNET_MAX,
+       .priv_size      = sizeof(struct rmnet_priv),
+       .setup          = rmnet_vnd_setup,
+       .validate       = rmnet_rtnl_validate,
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-ravb-fix-dma_addr_t-truncation-in-error-case.patch b/queue-5.15/net-ravb-fix-dma_addr_t-truncation-in-error-case.patch
new file mode 100644 (file)
index 0000000..c155922
--- /dev/null
@@ -0,0 +1,53 @@
+From b45a1241c93ea258ec7c92313c09b7d4ee2273a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Jan 2024 10:22:21 +0600
+Subject: net: ravb: Fix dma_addr_t truncation in error case
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+
+[ Upstream commit e327b2372bc0f18c30433ac40be07741b59231c5 ]
+
+In ravb_start_xmit(), ravb driver uses u32 variable to store result of
+dma_map_single() call. Since ravb hardware has 32-bit address fields in
+descriptors, this works properly when mapping is successful - it is
+platform's job to provide mapping addresses that fit into hardware
+limitations.
+
+However, in failure case dma_map_single() returns DMA_MAPPING_ERROR
+constant that is 64-bit when dma_addr_t is 64-bit. Storing this constant
+in u32 leads to truncation, and further call to dma_mapping_error()
+fails to notice the error.
+
+Fix that by storing result of dma_map_single() in a dma_addr_t
+variable.
+
+Fixes: c156633f1353 ("Renesas Ethernet AVB driver proper")
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/renesas/ravb_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
+index 1fa002c42c88..2bf5d4c208d3 100644
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -1567,7 +1567,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+       struct ravb_tstamp_skb *ts_skb;
+       struct ravb_tx_desc *desc;
+       unsigned long flags;
+-      u32 dma_addr;
++      dma_addr_t dma_addr;
+       void *buffer;
+       u32 entry;
+       u32 len;
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-stmmac-ethtool-fixed-calltrace-caused-by-unbalan.patch b/queue-5.15/net-stmmac-ethtool-fixed-calltrace-caused-by-unbalan.patch
new file mode 100644 (file)
index 0000000..b87fde2
--- /dev/null
@@ -0,0 +1,105 @@
+From 54f8ca8162f36678981123270be2d3bc6aa9a0d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 10:12:49 +0800
+Subject: net: stmmac: ethtool: Fixed calltrace caused by unbalanced
+ disable_irq_wake calls
+
+From: Qiang Ma <maqianga@uniontech.com>
+
+[ Upstream commit a23aa04042187cbde16f470b49d4ad60d32e9206 ]
+
+We found the following dmesg calltrace when testing the GMAC NIC notebook:
+
+[9.448656] ------------[ cut here ]------------
+[9.448658] Unbalanced IRQ 43 wake disable
+[9.448673] WARNING: CPU: 3 PID: 1083 at kernel/irq/manage.c:688 irq_set_irq_wake+0xe0/0x128
+[9.448717] CPU: 3 PID: 1083 Comm: ethtool Tainted: G           O      4.19 #1
+[9.448773]         ...
+[9.448774] Call Trace:
+[9.448781] [<9000000000209b5c>] show_stack+0x34/0x140
+[9.448788] [<9000000000d52700>] dump_stack+0x98/0xd0
+[9.448794] [<9000000000228610>] __warn+0xa8/0x120
+[9.448797] [<9000000000d2fb60>] report_bug+0x98/0x130
+[9.448800] [<900000000020a418>] do_bp+0x248/0x2f0
+[9.448805] [<90000000002035f4>] handle_bp_int+0x4c/0x78
+[9.448808] [<900000000029ea40>] irq_set_irq_wake+0xe0/0x128
+[9.448813] [<9000000000a96a7c>] stmmac_set_wol+0x134/0x150
+[9.448819] [<9000000000be6ed0>] dev_ethtool+0x1368/0x2440
+[9.448824] [<9000000000c08350>] dev_ioctl+0x1f8/0x3e0
+[9.448827] [<9000000000bb2a34>] sock_ioctl+0x2a4/0x450
+[9.448832] [<900000000046f044>] do_vfs_ioctl+0xa4/0x738
+[9.448834] [<900000000046f778>] ksys_ioctl+0xa0/0xe8
+[9.448837] [<900000000046f7d8>] sys_ioctl+0x18/0x28
+[9.448840] [<9000000000211ab4>] syscall_common+0x20/0x34
+[9.448842] ---[ end trace 40c18d9aec863c3e ]---
+
+Multiple disable_irq_wake() calls will keep decreasing the IRQ
+wake_depth, When wake_depth is 0, calling disable_irq_wake() again,
+will report the above calltrace.
+
+Due to the need to appear in pairs, we cannot call disable_irq_wake()
+without calling enable_irq_wake(). Fix this by making sure there are
+no unbalanced disable_irq_wake() calls.
+
+Fixes: 3172d3afa998 ("stmmac: support wake up irq from external sources (v3)")
+Signed-off-by: Qiang Ma <maqianga@uniontech.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20240112021249.24598-1-maqianga@uniontech.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h         |  1 +
+ drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 10 ++++++++--
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c    |  1 +
+ 3 files changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+index f03779205ade..1a74437787c0 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+@@ -241,6 +241,7 @@ struct stmmac_priv {
+       u32 msg_enable;
+       int wolopts;
+       int wol_irq;
++      bool wol_irq_disabled;
+       int clk_csr;
+       struct timer_list eee_ctrl_timer;
+       int lpi_irq;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+index 9e8ae4384e4f..7b954365e564 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+@@ -758,10 +758,16 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+       if (wol->wolopts) {
+               pr_info("stmmac: wakeup enable\n");
+               device_set_wakeup_enable(priv->device, 1);
+-              enable_irq_wake(priv->wol_irq);
++              /* Avoid unbalanced enable_irq_wake calls */
++              if (priv->wol_irq_disabled)
++                      enable_irq_wake(priv->wol_irq);
++              priv->wol_irq_disabled = false;
+       } else {
+               device_set_wakeup_enable(priv->device, 0);
+-              disable_irq_wake(priv->wol_irq);
++              /* Avoid unbalanced disable_irq_wake calls */
++              if (!priv->wol_irq_disabled)
++                      disable_irq_wake(priv->wol_irq);
++              priv->wol_irq_disabled = true;
+       }
+       mutex_lock(&priv->lock);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 08693d7458d1..ede630bfad2f 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -3506,6 +3506,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
+       /* Request the Wake IRQ in case of another line
+        * is used for WoL
+        */
++      priv->wol_irq_disabled = true;
+       if (priv->wol_irq > 0 && priv->wol_irq != dev->irq) {
+               int_name = priv->int_name_wol;
+               sprintf(int_name, "%s:%s", dev->name, "wol");
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-nf_tables-do-not-allow-mismatch-field-size.patch b/queue-5.15/netfilter-nf_tables-do-not-allow-mismatch-field-size.patch
new file mode 100644 (file)
index 0000000..8aec85c
--- /dev/null
@@ -0,0 +1,51 @@
+From 50f596b1aa53ba7f6c15d6554c5c364178776ec9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 Jan 2024 23:53:39 +0100
+Subject: netfilter: nf_tables: do not allow mismatch field size and set key
+ length
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 3ce67e3793f48c1b9635beb9bb71116ca1e51b58 ]
+
+The set description provides the size of each field in the set whose sum
+should not mismatch the set key length, bail out otherwise.
+
+I did not manage to crash nft_set_pipapo with mismatch fields and set key
+length so far, but this is UB which must be disallowed.
+
+Fixes: f3a2181e16f1 ("netfilter: nf_tables: Support for sets with multiple ranged fields")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index e1a06d5a386f..9f22f62a9b4d 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -4453,8 +4453,8 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr,
+ static int nft_set_desc_concat(struct nft_set_desc *desc,
+                              const struct nlattr *nla)
+ {
++      u32 num_regs = 0, key_num_regs = 0;
+       struct nlattr *attr;
+-      u32 num_regs = 0;
+       int rem, err, i;
+       nla_for_each_nested(attr, nla, rem) {
+@@ -4469,6 +4469,10 @@ static int nft_set_desc_concat(struct nft_set_desc *desc,
+       for (i = 0; i < desc->field_count; i++)
+               num_regs += DIV_ROUND_UP(desc->field_len[i], sizeof(u32));
++      key_num_regs = DIV_ROUND_UP(desc->klen, sizeof(u32));
++      if (key_num_regs != num_regs)
++              return -EINVAL;
++
+       if (num_regs > NFT_REG32_COUNT)
+               return -E2BIG;
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-nf_tables-memcg-accounting-for-dynamically.patch b/queue-5.15/netfilter-nf_tables-memcg-accounting-for-dynamically.patch
new file mode 100644 (file)
index 0000000..9ca18e0
--- /dev/null
@@ -0,0 +1,115 @@
+From ae8479ed5a692ad9c6caba731797a8b1371f73b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Apr 2022 12:50:37 +0300
+Subject: netfilter: nf_tables: memcg accounting for dynamically allocated
+ objects
+
+From: Vasily Averin <vasily.averin@linux.dev>
+
+[ Upstream commit 42193ffd79bd3acd91bd947e53f3548a3661d0a1 ]
+
+nft_*.c files whose NFT_EXPR_STATEFUL flag is set on need to
+use __GFP_ACCOUNT flag for objects that are dynamically
+allocated from the packet path.
+
+Such objects are allocated inside nft_expr_ops->init() callbacks
+executed in task context while processing netlink messages.
+
+In addition, this patch adds accounting to nft_set_elem_expr_clone()
+used for the same purposes.
+
+Signed-off-by: Vasily Averin <vvs@openvz.org>
+Acked-by: Roman Gushchin <roman.gushchin@linux.dev>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: 91a139cee120 ("netfilter: nft_limit: do not ignore unsupported flags")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 2 +-
+ net/netfilter/nft_connlimit.c | 2 +-
+ net/netfilter/nft_counter.c   | 2 +-
+ net/netfilter/nft_last.c      | 2 +-
+ net/netfilter/nft_limit.c     | 2 +-
+ net/netfilter/nft_quota.c     | 2 +-
+ 6 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 8a5fca1e61be..e1a06d5a386f 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -5896,7 +5896,7 @@ int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set,
+       int err, i, k;
+       for (i = 0; i < set->num_exprs; i++) {
+-              expr = kzalloc(set->exprs[i]->ops->size, GFP_KERNEL);
++              expr = kzalloc(set->exprs[i]->ops->size, GFP_KERNEL_ACCOUNT);
+               if (!expr)
+                       goto err_expr;
+diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c
+index 58dcafe8bf79..2a2042adf3b1 100644
+--- a/net/netfilter/nft_connlimit.c
++++ b/net/netfilter/nft_connlimit.c
+@@ -76,7 +76,7 @@ static int nft_connlimit_do_init(const struct nft_ctx *ctx,
+                       invert = true;
+       }
+-      priv->list = kmalloc(sizeof(*priv->list), GFP_KERNEL);
++      priv->list = kmalloc(sizeof(*priv->list), GFP_KERNEL_ACCOUNT);
+       if (!priv->list)
+               return -ENOMEM;
+diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c
+index 8edd3b3c173d..9f78f8ad4ee1 100644
+--- a/net/netfilter/nft_counter.c
++++ b/net/netfilter/nft_counter.c
+@@ -61,7 +61,7 @@ static int nft_counter_do_init(const struct nlattr * const tb[],
+       struct nft_counter __percpu *cpu_stats;
+       struct nft_counter *this_cpu;
+-      cpu_stats = alloc_percpu(struct nft_counter);
++      cpu_stats = alloc_percpu_gfp(struct nft_counter, GFP_KERNEL_ACCOUNT);
+       if (cpu_stats == NULL)
+               return -ENOMEM;
+diff --git a/net/netfilter/nft_last.c b/net/netfilter/nft_last.c
+index 5ee33d0ccd4e..df48a11e224e 100644
+--- a/net/netfilter/nft_last.c
++++ b/net/netfilter/nft_last.c
+@@ -30,7 +30,7 @@ static int nft_last_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
+       u64 last_jiffies;
+       int err;
+-      last = kzalloc(sizeof(*last), GFP_KERNEL);
++      last = kzalloc(sizeof(*last), GFP_KERNEL_ACCOUNT);
+       if (!last)
+               return -ENOMEM;
+diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c
+index f04be5be73a0..ac0979febdac 100644
+--- a/net/netfilter/nft_limit.c
++++ b/net/netfilter/nft_limit.c
+@@ -90,7 +90,7 @@ static int nft_limit_init(struct nft_limit_priv *priv,
+                                priv->rate);
+       }
+-      priv->limit = kmalloc(sizeof(*priv->limit), GFP_KERNEL);
++      priv->limit = kmalloc(sizeof(*priv->limit), GFP_KERNEL_ACCOUNT);
+       if (!priv->limit)
+               return -ENOMEM;
+diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c
+index 0484aef74273..18ff38682de4 100644
+--- a/net/netfilter/nft_quota.c
++++ b/net/netfilter/nft_quota.c
+@@ -90,7 +90,7 @@ static int nft_quota_do_init(const struct nlattr * const tb[],
+                       return -EOPNOTSUPP;
+       }
+-      priv->consumed = kmalloc(sizeof(*priv->consumed), GFP_KERNEL);
++      priv->consumed = kmalloc(sizeof(*priv->consumed), GFP_KERNEL_ACCOUNT);
+       if (!priv->consumed)
+               return -ENOMEM;
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-nf_tables-reject-invalid-set-policy.patch b/queue-5.15/netfilter-nf_tables-reject-invalid-set-policy.patch
new file mode 100644 (file)
index 0000000..f77cf99
--- /dev/null
@@ -0,0 +1,44 @@
+From 7a9808ba556c445a8a56cc928e7dafe1192511c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jan 2024 23:34:58 +0100
+Subject: netfilter: nf_tables: reject invalid set policy
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 0617c3de9b4026b87be12b0cb5c35f42c7c66fcb ]
+
+Report -EINVAL in case userspace provides a unsupported set backend
+policy.
+
+Fixes: c50b960ccc59 ("netfilter: nf_tables: implement proper set selection")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 54ff4d3bcd54..8a5fca1e61be 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -4683,8 +4683,16 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+       }
+       desc.policy = NFT_SET_POL_PERFORMANCE;
+-      if (nla[NFTA_SET_POLICY] != NULL)
++      if (nla[NFTA_SET_POLICY] != NULL) {
+               desc.policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
++              switch (desc.policy) {
++              case NFT_SET_POL_PERFORMANCE:
++              case NFT_SET_POL_MEMORY:
++                      break;
++              default:
++                      return -EOPNOTSUPP;
++              }
++      }
+       if (nla[NFTA_SET_DESC] != NULL) {
+               err = nf_tables_set_desc_parse(&desc, nla[NFTA_SET_DESC]);
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-nf_tables-reject-nft_set_concat-with-not-f.patch b/queue-5.15/netfilter-nf_tables-reject-nft_set_concat-with-not-f.patch
new file mode 100644 (file)
index 0000000..25ca59b
--- /dev/null
@@ -0,0 +1,41 @@
+From 80f40c785b47e060ec74ec1487edfb68e33ae3d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jan 2024 12:50:29 +0100
+Subject: netfilter: nf_tables: reject NFT_SET_CONCAT with not field length
+ description
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 113661e07460a6604aacc8ae1b23695a89e7d4b3 ]
+
+It is still possible to set on the NFT_SET_CONCAT flag by specifying a
+set size and no field description, report EINVAL in such case.
+
+Fixes: 1b6345d4160e ("netfilter: nf_tables: check NFT_SET_CONCAT flag if field_count is specified")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 967ad439e6b3..e2e3ccbb635f 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -4703,8 +4703,12 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+               if (err < 0)
+                       return err;
+-              if (desc.field_count > 1 && !(flags & NFT_SET_CONCAT))
++              if (desc.field_count > 1) {
++                      if (!(flags & NFT_SET_CONCAT))
++                              return -EINVAL;
++              } else if (flags & NFT_SET_CONCAT) {
+                       return -EINVAL;
++              }
+       } else if (flags & NFT_SET_CONCAT) {
+               return -EINVAL;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-nf_tables-skip-dead-set-elements-in-netlin.patch b/queue-5.15/netfilter-nf_tables-skip-dead-set-elements-in-netlin.patch
new file mode 100644 (file)
index 0000000..dbd5269
--- /dev/null
@@ -0,0 +1,47 @@
+From 6a5a89daa4c77ac9838ce62778db7da870a54bb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jan 2024 00:14:38 +0100
+Subject: netfilter: nf_tables: skip dead set elements in netlink dump
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 6b1ca88e4bb63673dc9f9c7f23c899f22c3cb17a ]
+
+Delete from packet path relies on the garbage collector to purge
+elements with NFT_SET_ELEM_DEAD_BIT on.
+
+Skip these dead elements from nf_tables_dump_setelem() path, I very
+rarely see tests/shell/testcases/maps/typeof_maps_add_delete reports
+[DUMP FAILED] showing a mismatch in the expected output with an element
+that should not be there.
+
+If the netlink dump happens before GC worker run, it might show dead
+elements in the ruleset listing.
+
+nft_rhash_get() already skips dead elements in nft_rhash_cmp(),
+therefore, it already does not show the element when getting a single
+element via netlink control plane.
+
+Fixes: 5f68718b34a5 ("netfilter: nf_tables: GC transaction API to avoid race with control plane")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 9f22f62a9b4d..967ad439e6b3 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -5348,7 +5348,7 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
+       const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
+       struct nft_set_dump_args *args;
+-      if (nft_set_elem_expired(ext))
++      if (nft_set_elem_expired(ext) || nft_set_elem_is_dead(ext))
+               return 0;
+       args = container_of(iter, struct nft_set_dump_args, iter);
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-nft_connlimit-move-stateful-fields-out-of-.patch b/queue-5.15/netfilter-nft_connlimit-move-stateful-fields-out-of-.patch
new file mode 100644 (file)
index 0000000..f397878
--- /dev/null
@@ -0,0 +1,104 @@
+From 7a8d95762229678a78a12e22bacdc27eba953e9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Jan 2022 17:11:13 +0100
+Subject: netfilter: nft_connlimit: move stateful fields out of expression data
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 37f319f37d9005693dff085bb72852eeebc803ef ]
+
+In preparation for the rule blob representation.
+
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: 91a139cee120 ("netfilter: nft_limit: do not ignore unsupported flags")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_connlimit.c | 26 ++++++++++++++++++--------
+ 1 file changed, 18 insertions(+), 8 deletions(-)
+
+diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c
+index 7d0761fad37e..58dcafe8bf79 100644
+--- a/net/netfilter/nft_connlimit.c
++++ b/net/netfilter/nft_connlimit.c
+@@ -14,7 +14,7 @@
+ #include <net/netfilter/nf_conntrack_zones.h>
+ struct nft_connlimit {
+-      struct nf_conncount_list        list;
++      struct nf_conncount_list        *list;
+       u32                             limit;
+       bool                            invert;
+ };
+@@ -43,12 +43,12 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv,
+               return;
+       }
+-      if (nf_conncount_add(nft_net(pkt), &priv->list, tuple_ptr, zone)) {
++      if (nf_conncount_add(nft_net(pkt), priv->list, tuple_ptr, zone)) {
+               regs->verdict.code = NF_DROP;
+               return;
+       }
+-      count = priv->list.count;
++      count = priv->list->count;
+       if ((count > priv->limit) ^ priv->invert) {
+               regs->verdict.code = NFT_BREAK;
+@@ -76,7 +76,11 @@ static int nft_connlimit_do_init(const struct nft_ctx *ctx,
+                       invert = true;
+       }
+-      nf_conncount_list_init(&priv->list);
++      priv->list = kmalloc(sizeof(*priv->list), GFP_KERNEL);
++      if (!priv->list)
++              return -ENOMEM;
++
++      nf_conncount_list_init(priv->list);
+       priv->limit     = limit;
+       priv->invert    = invert;
+@@ -87,7 +91,8 @@ static void nft_connlimit_do_destroy(const struct nft_ctx *ctx,
+                                    struct nft_connlimit *priv)
+ {
+       nf_ct_netns_put(ctx->net, ctx->family);
+-      nf_conncount_cache_free(&priv->list);
++      nf_conncount_cache_free(priv->list);
++      kfree(priv->list);
+ }
+ static int nft_connlimit_do_dump(struct sk_buff *skb,
+@@ -200,7 +205,11 @@ static int nft_connlimit_clone(struct nft_expr *dst, const struct nft_expr *src)
+       struct nft_connlimit *priv_dst = nft_expr_priv(dst);
+       struct nft_connlimit *priv_src = nft_expr_priv(src);
+-      nf_conncount_list_init(&priv_dst->list);
++      priv_dst->list = kmalloc(sizeof(*priv_dst->list), GFP_ATOMIC);
++      if (priv_dst->list)
++              return -ENOMEM;
++
++      nf_conncount_list_init(priv_dst->list);
+       priv_dst->limit  = priv_src->limit;
+       priv_dst->invert = priv_src->invert;
+@@ -212,7 +221,8 @@ static void nft_connlimit_destroy_clone(const struct nft_ctx *ctx,
+ {
+       struct nft_connlimit *priv = nft_expr_priv(expr);
+-      nf_conncount_cache_free(&priv->list);
++      nf_conncount_cache_free(priv->list);
++      kfree(priv->list);
+ }
+ static bool nft_connlimit_gc(struct net *net, const struct nft_expr *expr)
+@@ -221,7 +231,7 @@ static bool nft_connlimit_gc(struct net *net, const struct nft_expr *expr)
+       bool ret;
+       local_bh_disable();
+-      ret = nf_conncount_gc_list(net, &priv->list);
++      ret = nf_conncount_gc_list(net, priv->list);
+       local_bh_enable();
+       return ret;
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-nft_last-move-stateful-fields-out-of-expre.patch b/queue-5.15/netfilter-nft_last-move-stateful-fields-out-of-expre.patch
new file mode 100644 (file)
index 0000000..dc3697d
--- /dev/null
@@ -0,0 +1,146 @@
+From 0e0cbad29ca156cfb5c85c8fdc9335baddb551e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Jan 2022 17:11:14 +0100
+Subject: netfilter: nft_last: move stateful fields out of expression data
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 33a24de37e814572491bcb35f42c0de74ad67586 ]
+
+In preparation for the rule blob representation.
+
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: 91a139cee120 ("netfilter: nft_limit: do not ignore unsupported flags")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_last.c | 69 +++++++++++++++++++++++++++++-----------
+ 1 file changed, 51 insertions(+), 18 deletions(-)
+
+diff --git a/net/netfilter/nft_last.c b/net/netfilter/nft_last.c
+index 304e33cbed9b..5ee33d0ccd4e 100644
+--- a/net/netfilter/nft_last.c
++++ b/net/netfilter/nft_last.c
+@@ -8,9 +8,13 @@
+ #include <net/netfilter/nf_tables_core.h>
+ #include <net/netfilter/nf_tables.h>
++struct nft_last {
++      unsigned long   jiffies;
++      unsigned int    set;
++};
++
+ struct nft_last_priv {
+-      unsigned long   last_jiffies;
+-      unsigned int    last_set;
++      struct nft_last *last;
+ };
+ static const struct nla_policy nft_last_policy[NFTA_LAST_MAX + 1] = {
+@@ -22,47 +26,55 @@ static int nft_last_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
+                        const struct nlattr * const tb[])
+ {
+       struct nft_last_priv *priv = nft_expr_priv(expr);
++      struct nft_last *last;
+       u64 last_jiffies;
+-      u32 last_set = 0;
+       int err;
+-      if (tb[NFTA_LAST_SET]) {
+-              last_set = ntohl(nla_get_be32(tb[NFTA_LAST_SET]));
+-              if (last_set == 1)
+-                      priv->last_set = 1;
+-      }
++      last = kzalloc(sizeof(*last), GFP_KERNEL);
++      if (!last)
++              return -ENOMEM;
++
++      if (tb[NFTA_LAST_SET])
++              last->set = ntohl(nla_get_be32(tb[NFTA_LAST_SET]));
+-      if (last_set && tb[NFTA_LAST_MSECS]) {
++      if (last->set && tb[NFTA_LAST_MSECS]) {
+               err = nf_msecs_to_jiffies64(tb[NFTA_LAST_MSECS], &last_jiffies);
+               if (err < 0)
+-                      return err;
++                      goto err;
+-              priv->last_jiffies = jiffies - (unsigned long)last_jiffies;
++              last->jiffies = jiffies - (unsigned long)last_jiffies;
+       }
++      priv->last = last;
+       return 0;
++err:
++      kfree(last);
++
++      return err;
+ }
+ static void nft_last_eval(const struct nft_expr *expr,
+                         struct nft_regs *regs, const struct nft_pktinfo *pkt)
+ {
+       struct nft_last_priv *priv = nft_expr_priv(expr);
++      struct nft_last *last = priv->last;
+-      if (READ_ONCE(priv->last_jiffies) != jiffies)
+-              WRITE_ONCE(priv->last_jiffies, jiffies);
+-      if (READ_ONCE(priv->last_set) == 0)
+-              WRITE_ONCE(priv->last_set, 1);
++      if (READ_ONCE(last->jiffies) != jiffies)
++              WRITE_ONCE(last->jiffies, jiffies);
++      if (READ_ONCE(last->set) == 0)
++              WRITE_ONCE(last->set, 1);
+ }
+ static int nft_last_dump(struct sk_buff *skb, const struct nft_expr *expr)
+ {
+       struct nft_last_priv *priv = nft_expr_priv(expr);
+-      unsigned long last_jiffies = READ_ONCE(priv->last_jiffies);
+-      u32 last_set = READ_ONCE(priv->last_set);
++      struct nft_last *last = priv->last;
++      unsigned long last_jiffies = READ_ONCE(last->jiffies);
++      u32 last_set = READ_ONCE(last->set);
+       __be64 msecs;
+       if (time_before(jiffies, last_jiffies)) {
+-              WRITE_ONCE(priv->last_set, 0);
++              WRITE_ONCE(last->set, 0);
+               last_set = 0;
+       }
+@@ -81,11 +93,32 @@ static int nft_last_dump(struct sk_buff *skb, const struct nft_expr *expr)
+       return -1;
+ }
++static void nft_last_destroy(const struct nft_ctx *ctx,
++                           const struct nft_expr *expr)
++{
++      struct nft_last_priv *priv = nft_expr_priv(expr);
++
++      kfree(priv->last);
++}
++
++static int nft_last_clone(struct nft_expr *dst, const struct nft_expr *src)
++{
++      struct nft_last_priv *priv_dst = nft_expr_priv(dst);
++
++      priv_dst->last = kzalloc(sizeof(*priv_dst->last), GFP_ATOMIC);
++      if (priv_dst->last)
++              return -ENOMEM;
++
++      return 0;
++}
++
+ static const struct nft_expr_ops nft_last_ops = {
+       .type           = &nft_last_type,
+       .size           = NFT_EXPR_SIZE(sizeof(struct nft_last_priv)),
+       .eval           = nft_last_eval,
+       .init           = nft_last_init,
++      .destroy        = nft_last_destroy,
++      .clone          = nft_last_clone,
+       .dump           = nft_last_dump,
+ };
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-nft_limit-do-not-ignore-unsupported-flags.patch b/queue-5.15/netfilter-nft_limit-do-not-ignore-unsupported-flags.patch
new file mode 100644 (file)
index 0000000..4f04870
--- /dev/null
@@ -0,0 +1,66 @@
+From 6850c64da86f3b94c8462e40f5e90994833d3819 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 00:42:37 +0100
+Subject: netfilter: nft_limit: do not ignore unsupported flags
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 91a139cee1202a4599a380810d93c69b5bac6197 ]
+
+Bail out if userspace provides unsupported flags, otherwise future
+extensions to the limit expression will be silently ignored by the
+kernel.
+
+Fixes: c7862a5f0de5 ("netfilter: nft_limit: allow to invert matching criteria")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_limit.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c
+index ac0979febdac..a355fbabe99f 100644
+--- a/net/netfilter/nft_limit.c
++++ b/net/netfilter/nft_limit.c
+@@ -58,6 +58,7 @@ static inline bool nft_limit_eval(struct nft_limit_priv *priv, u64 cost)
+ static int nft_limit_init(struct nft_limit_priv *priv,
+                         const struct nlattr * const tb[], bool pkts)
+ {
++      bool invert = false;
+       u64 unit, tokens;
+       if (tb[NFTA_LIMIT_RATE] == NULL ||
+@@ -90,19 +91,23 @@ static int nft_limit_init(struct nft_limit_priv *priv,
+                                priv->rate);
+       }
++      if (tb[NFTA_LIMIT_FLAGS]) {
++              u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS]));
++
++              if (flags & ~NFT_LIMIT_F_INV)
++                      return -EOPNOTSUPP;
++
++              if (flags & NFT_LIMIT_F_INV)
++                      invert = true;
++      }
++
+       priv->limit = kmalloc(sizeof(*priv->limit), GFP_KERNEL_ACCOUNT);
+       if (!priv->limit)
+               return -ENOMEM;
+       priv->limit->tokens = tokens;
+       priv->tokens_max = priv->limit->tokens;
+-
+-      if (tb[NFTA_LIMIT_FLAGS]) {
+-              u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS]));
+-
+-              if (flags & NFT_LIMIT_F_INV)
+-                      priv->invert = true;
+-      }
++      priv->invert = invert;
+       priv->limit->last = ktime_get_ns();
+       spin_lock_init(&priv->limit->lock);
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-nft_limit-move-stateful-fields-out-of-expr.patch b/queue-5.15/netfilter-nft_limit-move-stateful-fields-out-of-expr.patch
new file mode 100644 (file)
index 0000000..26101b6
--- /dev/null
@@ -0,0 +1,191 @@
+From d0054c54cdb5f1302f179778b69b8fc779cb8555 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Jan 2022 17:11:18 +0100
+Subject: netfilter: nft_limit: move stateful fields out of expression data
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 3b9e2ea6c11bff72ac1d607f6b954e7666b47409 ]
+
+In preparation for the rule blob representation.
+
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: 91a139cee120 ("netfilter: nft_limit: do not ignore unsupported flags")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_limit.c | 94 ++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 82 insertions(+), 12 deletions(-)
+
+diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c
+index d6e0226b7603..f04be5be73a0 100644
+--- a/net/netfilter/nft_limit.c
++++ b/net/netfilter/nft_limit.c
+@@ -14,10 +14,14 @@
+ #include <linux/netfilter/nf_tables.h>
+ #include <net/netfilter/nf_tables.h>
+-struct nft_limit_priv {
++struct nft_limit {
+       spinlock_t      lock;
+       u64             last;
+       u64             tokens;
++};
++
++struct nft_limit_priv {
++      struct nft_limit *limit;
+       u64             tokens_max;
+       u64             rate;
+       u64             nsecs;
+@@ -30,21 +34,21 @@ static inline bool nft_limit_eval(struct nft_limit_priv *priv, u64 cost)
+       u64 now, tokens;
+       s64 delta;
+-      spin_lock_bh(&priv->lock);
++      spin_lock_bh(&priv->limit->lock);
+       now = ktime_get_ns();
+-      tokens = priv->tokens + now - priv->last;
++      tokens = priv->limit->tokens + now - priv->limit->last;
+       if (tokens > priv->tokens_max)
+               tokens = priv->tokens_max;
+-      priv->last = now;
++      priv->limit->last = now;
+       delta = tokens - cost;
+       if (delta >= 0) {
+-              priv->tokens = delta;
+-              spin_unlock_bh(&priv->lock);
++              priv->limit->tokens = delta;
++              spin_unlock_bh(&priv->limit->lock);
+               return priv->invert;
+       }
+-      priv->tokens = tokens;
+-      spin_unlock_bh(&priv->lock);
++      priv->limit->tokens = tokens;
++      spin_unlock_bh(&priv->limit->lock);
+       return !priv->invert;
+ }
+@@ -86,8 +90,12 @@ static int nft_limit_init(struct nft_limit_priv *priv,
+                                priv->rate);
+       }
+-      priv->tokens = tokens;
+-      priv->tokens_max = priv->tokens;
++      priv->limit = kmalloc(sizeof(*priv->limit), GFP_KERNEL);
++      if (!priv->limit)
++              return -ENOMEM;
++
++      priv->limit->tokens = tokens;
++      priv->tokens_max = priv->limit->tokens;
+       if (tb[NFTA_LIMIT_FLAGS]) {
+               u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS]));
+@@ -95,8 +103,8 @@ static int nft_limit_init(struct nft_limit_priv *priv,
+               if (flags & NFT_LIMIT_F_INV)
+                       priv->invert = true;
+       }
+-      priv->last = ktime_get_ns();
+-      spin_lock_init(&priv->lock);
++      priv->limit->last = ktime_get_ns();
++      spin_lock_init(&priv->limit->lock);
+       return 0;
+ }
+@@ -121,6 +129,32 @@ static int nft_limit_dump(struct sk_buff *skb, const struct nft_limit_priv *priv
+       return -1;
+ }
++static void nft_limit_destroy(const struct nft_ctx *ctx,
++                            const struct nft_limit_priv *priv)
++{
++      kfree(priv->limit);
++}
++
++static int nft_limit_clone(struct nft_limit_priv *priv_dst,
++                         const struct nft_limit_priv *priv_src)
++{
++      priv_dst->tokens_max = priv_src->tokens_max;
++      priv_dst->rate = priv_src->rate;
++      priv_dst->nsecs = priv_src->nsecs;
++      priv_dst->burst = priv_src->burst;
++      priv_dst->invert = priv_src->invert;
++
++      priv_dst->limit = kmalloc(sizeof(*priv_dst->limit), GFP_ATOMIC);
++      if (priv_dst->limit)
++              return -ENOMEM;
++
++      spin_lock_init(&priv_dst->limit->lock);
++      priv_dst->limit->tokens = priv_src->tokens_max;
++      priv_dst->limit->last = ktime_get_ns();
++
++      return 0;
++}
++
+ struct nft_limit_priv_pkts {
+       struct nft_limit_priv   limit;
+       u64                     cost;
+@@ -166,12 +200,30 @@ static int nft_limit_pkts_dump(struct sk_buff *skb, const struct nft_expr *expr)
+       return nft_limit_dump(skb, &priv->limit, NFT_LIMIT_PKTS);
+ }
++static void nft_limit_pkts_destroy(const struct nft_ctx *ctx,
++                                 const struct nft_expr *expr)
++{
++      const struct nft_limit_priv_pkts *priv = nft_expr_priv(expr);
++
++      nft_limit_destroy(ctx, &priv->limit);
++}
++
++static int nft_limit_pkts_clone(struct nft_expr *dst, const struct nft_expr *src)
++{
++      struct nft_limit_priv_pkts *priv_dst = nft_expr_priv(dst);
++      struct nft_limit_priv_pkts *priv_src = nft_expr_priv(src);
++
++      return nft_limit_clone(&priv_dst->limit, &priv_src->limit);
++}
++
+ static struct nft_expr_type nft_limit_type;
+ static const struct nft_expr_ops nft_limit_pkts_ops = {
+       .type           = &nft_limit_type,
+       .size           = NFT_EXPR_SIZE(sizeof(struct nft_limit_priv_pkts)),
+       .eval           = nft_limit_pkts_eval,
+       .init           = nft_limit_pkts_init,
++      .destroy        = nft_limit_pkts_destroy,
++      .clone          = nft_limit_pkts_clone,
+       .dump           = nft_limit_pkts_dump,
+ };
+@@ -203,12 +255,30 @@ static int nft_limit_bytes_dump(struct sk_buff *skb,
+       return nft_limit_dump(skb, priv, NFT_LIMIT_PKT_BYTES);
+ }
++static void nft_limit_bytes_destroy(const struct nft_ctx *ctx,
++                                  const struct nft_expr *expr)
++{
++      const struct nft_limit_priv *priv = nft_expr_priv(expr);
++
++      nft_limit_destroy(ctx, priv);
++}
++
++static int nft_limit_bytes_clone(struct nft_expr *dst, const struct nft_expr *src)
++{
++      struct nft_limit_priv *priv_dst = nft_expr_priv(dst);
++      struct nft_limit_priv *priv_src = nft_expr_priv(src);
++
++      return nft_limit_clone(priv_dst, priv_src);
++}
++
+ static const struct nft_expr_ops nft_limit_bytes_ops = {
+       .type           = &nft_limit_type,
+       .size           = NFT_EXPR_SIZE(sizeof(struct nft_limit_priv)),
+       .eval           = nft_limit_bytes_eval,
+       .init           = nft_limit_bytes_init,
+       .dump           = nft_limit_bytes_dump,
++      .clone          = nft_limit_bytes_clone,
++      .destroy        = nft_limit_bytes_destroy,
+ };
+ static const struct nft_expr_ops *
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-nft_limit-rename-stateful-structure.patch b/queue-5.15/netfilter-nft_limit-rename-stateful-structure.patch
new file mode 100644 (file)
index 0000000..84d3ce7
--- /dev/null
@@ -0,0 +1,314 @@
+From aeb5ecd5b40716636fe56d51af9cf4f7bce2f349 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Jan 2022 17:11:17 +0100
+Subject: netfilter: nft_limit: rename stateful structure
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 369b6cb5d391750fc01ce951c2500281d2975705 ]
+
+From struct nft_limit to nft_limit_priv.
+
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: 91a139cee120 ("netfilter: nft_limit: do not ignore unsupported flags")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_limit.c | 104 +++++++++++++++++++-------------------
+ 1 file changed, 52 insertions(+), 52 deletions(-)
+
+diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c
+index 82ec27bdf941..d6e0226b7603 100644
+--- a/net/netfilter/nft_limit.c
++++ b/net/netfilter/nft_limit.c
+@@ -14,7 +14,7 @@
+ #include <linux/netfilter/nf_tables.h>
+ #include <net/netfilter/nf_tables.h>
+-struct nft_limit {
++struct nft_limit_priv {
+       spinlock_t      lock;
+       u64             last;
+       u64             tokens;
+@@ -25,33 +25,33 @@ struct nft_limit {
+       bool            invert;
+ };
+-static inline bool nft_limit_eval(struct nft_limit *limit, u64 cost)
++static inline bool nft_limit_eval(struct nft_limit_priv *priv, u64 cost)
+ {
+       u64 now, tokens;
+       s64 delta;
+-      spin_lock_bh(&limit->lock);
++      spin_lock_bh(&priv->lock);
+       now = ktime_get_ns();
+-      tokens = limit->tokens + now - limit->last;
+-      if (tokens > limit->tokens_max)
+-              tokens = limit->tokens_max;
++      tokens = priv->tokens + now - priv->last;
++      if (tokens > priv->tokens_max)
++              tokens = priv->tokens_max;
+-      limit->last = now;
++      priv->last = now;
+       delta = tokens - cost;
+       if (delta >= 0) {
+-              limit->tokens = delta;
+-              spin_unlock_bh(&limit->lock);
+-              return limit->invert;
++              priv->tokens = delta;
++              spin_unlock_bh(&priv->lock);
++              return priv->invert;
+       }
+-      limit->tokens = tokens;
+-      spin_unlock_bh(&limit->lock);
+-      return !limit->invert;
++      priv->tokens = tokens;
++      spin_unlock_bh(&priv->lock);
++      return !priv->invert;
+ }
+ /* Use same default as in iptables. */
+ #define NFT_LIMIT_PKT_BURST_DEFAULT   5
+-static int nft_limit_init(struct nft_limit *limit,
++static int nft_limit_init(struct nft_limit_priv *priv,
+                         const struct nlattr * const tb[], bool pkts)
+ {
+       u64 unit, tokens;
+@@ -60,58 +60,58 @@ static int nft_limit_init(struct nft_limit *limit,
+           tb[NFTA_LIMIT_UNIT] == NULL)
+               return -EINVAL;
+-      limit->rate = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_RATE]));
++      priv->rate = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_RATE]));
+       unit = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_UNIT]));
+-      limit->nsecs = unit * NSEC_PER_SEC;
+-      if (limit->rate == 0 || limit->nsecs < unit)
++      priv->nsecs = unit * NSEC_PER_SEC;
++      if (priv->rate == 0 || priv->nsecs < unit)
+               return -EOVERFLOW;
+       if (tb[NFTA_LIMIT_BURST])
+-              limit->burst = ntohl(nla_get_be32(tb[NFTA_LIMIT_BURST]));
++              priv->burst = ntohl(nla_get_be32(tb[NFTA_LIMIT_BURST]));
+-      if (pkts && limit->burst == 0)
+-              limit->burst = NFT_LIMIT_PKT_BURST_DEFAULT;
++      if (pkts && priv->burst == 0)
++              priv->burst = NFT_LIMIT_PKT_BURST_DEFAULT;
+-      if (limit->rate + limit->burst < limit->rate)
++      if (priv->rate + priv->burst < priv->rate)
+               return -EOVERFLOW;
+       if (pkts) {
+-              tokens = div64_u64(limit->nsecs, limit->rate) * limit->burst;
++              tokens = div64_u64(priv->nsecs, priv->rate) * priv->burst;
+       } else {
+               /* The token bucket size limits the number of tokens can be
+                * accumulated. tokens_max specifies the bucket size.
+                * tokens_max = unit * (rate + burst) / rate.
+                */
+-              tokens = div64_u64(limit->nsecs * (limit->rate + limit->burst),
+-                               limit->rate);
++              tokens = div64_u64(priv->nsecs * (priv->rate + priv->burst),
++                               priv->rate);
+       }
+-      limit->tokens = tokens;
+-      limit->tokens_max = limit->tokens;
++      priv->tokens = tokens;
++      priv->tokens_max = priv->tokens;
+       if (tb[NFTA_LIMIT_FLAGS]) {
+               u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS]));
+               if (flags & NFT_LIMIT_F_INV)
+-                      limit->invert = true;
++                      priv->invert = true;
+       }
+-      limit->last = ktime_get_ns();
+-      spin_lock_init(&limit->lock);
++      priv->last = ktime_get_ns();
++      spin_lock_init(&priv->lock);
+       return 0;
+ }
+-static int nft_limit_dump(struct sk_buff *skb, const struct nft_limit *limit,
++static int nft_limit_dump(struct sk_buff *skb, const struct nft_limit_priv *priv,
+                         enum nft_limit_type type)
+ {
+-      u32 flags = limit->invert ? NFT_LIMIT_F_INV : 0;
+-      u64 secs = div_u64(limit->nsecs, NSEC_PER_SEC);
++      u32 flags = priv->invert ? NFT_LIMIT_F_INV : 0;
++      u64 secs = div_u64(priv->nsecs, NSEC_PER_SEC);
+-      if (nla_put_be64(skb, NFTA_LIMIT_RATE, cpu_to_be64(limit->rate),
++      if (nla_put_be64(skb, NFTA_LIMIT_RATE, cpu_to_be64(priv->rate),
+                        NFTA_LIMIT_PAD) ||
+           nla_put_be64(skb, NFTA_LIMIT_UNIT, cpu_to_be64(secs),
+                        NFTA_LIMIT_PAD) ||
+-          nla_put_be32(skb, NFTA_LIMIT_BURST, htonl(limit->burst)) ||
++          nla_put_be32(skb, NFTA_LIMIT_BURST, htonl(priv->burst)) ||
+           nla_put_be32(skb, NFTA_LIMIT_TYPE, htonl(type)) ||
+           nla_put_be32(skb, NFTA_LIMIT_FLAGS, htonl(flags)))
+               goto nla_put_failure;
+@@ -121,8 +121,8 @@ static int nft_limit_dump(struct sk_buff *skb, const struct nft_limit *limit,
+       return -1;
+ }
+-struct nft_limit_pkts {
+-      struct nft_limit        limit;
++struct nft_limit_priv_pkts {
++      struct nft_limit_priv   limit;
+       u64                     cost;
+ };
+@@ -130,7 +130,7 @@ static void nft_limit_pkts_eval(const struct nft_expr *expr,
+                               struct nft_regs *regs,
+                               const struct nft_pktinfo *pkt)
+ {
+-      struct nft_limit_pkts *priv = nft_expr_priv(expr);
++      struct nft_limit_priv_pkts *priv = nft_expr_priv(expr);
+       if (nft_limit_eval(&priv->limit, priv->cost))
+               regs->verdict.code = NFT_BREAK;
+@@ -148,7 +148,7 @@ static int nft_limit_pkts_init(const struct nft_ctx *ctx,
+                              const struct nft_expr *expr,
+                              const struct nlattr * const tb[])
+ {
+-      struct nft_limit_pkts *priv = nft_expr_priv(expr);
++      struct nft_limit_priv_pkts *priv = nft_expr_priv(expr);
+       int err;
+       err = nft_limit_init(&priv->limit, tb, true);
+@@ -161,7 +161,7 @@ static int nft_limit_pkts_init(const struct nft_ctx *ctx,
+ static int nft_limit_pkts_dump(struct sk_buff *skb, const struct nft_expr *expr)
+ {
+-      const struct nft_limit_pkts *priv = nft_expr_priv(expr);
++      const struct nft_limit_priv_pkts *priv = nft_expr_priv(expr);
+       return nft_limit_dump(skb, &priv->limit, NFT_LIMIT_PKTS);
+ }
+@@ -169,7 +169,7 @@ static int nft_limit_pkts_dump(struct sk_buff *skb, const struct nft_expr *expr)
+ static struct nft_expr_type nft_limit_type;
+ static const struct nft_expr_ops nft_limit_pkts_ops = {
+       .type           = &nft_limit_type,
+-      .size           = NFT_EXPR_SIZE(sizeof(struct nft_limit_pkts)),
++      .size           = NFT_EXPR_SIZE(sizeof(struct nft_limit_priv_pkts)),
+       .eval           = nft_limit_pkts_eval,
+       .init           = nft_limit_pkts_init,
+       .dump           = nft_limit_pkts_dump,
+@@ -179,7 +179,7 @@ static void nft_limit_bytes_eval(const struct nft_expr *expr,
+                                struct nft_regs *regs,
+                                const struct nft_pktinfo *pkt)
+ {
+-      struct nft_limit *priv = nft_expr_priv(expr);
++      struct nft_limit_priv *priv = nft_expr_priv(expr);
+       u64 cost = div64_u64(priv->nsecs * pkt->skb->len, priv->rate);
+       if (nft_limit_eval(priv, cost))
+@@ -190,7 +190,7 @@ static int nft_limit_bytes_init(const struct nft_ctx *ctx,
+                               const struct nft_expr *expr,
+                               const struct nlattr * const tb[])
+ {
+-      struct nft_limit *priv = nft_expr_priv(expr);
++      struct nft_limit_priv *priv = nft_expr_priv(expr);
+       return nft_limit_init(priv, tb, false);
+ }
+@@ -198,14 +198,14 @@ static int nft_limit_bytes_init(const struct nft_ctx *ctx,
+ static int nft_limit_bytes_dump(struct sk_buff *skb,
+                               const struct nft_expr *expr)
+ {
+-      const struct nft_limit *priv = nft_expr_priv(expr);
++      const struct nft_limit_priv *priv = nft_expr_priv(expr);
+       return nft_limit_dump(skb, priv, NFT_LIMIT_PKT_BYTES);
+ }
+ static const struct nft_expr_ops nft_limit_bytes_ops = {
+       .type           = &nft_limit_type,
+-      .size           = NFT_EXPR_SIZE(sizeof(struct nft_limit)),
++      .size           = NFT_EXPR_SIZE(sizeof(struct nft_limit_priv)),
+       .eval           = nft_limit_bytes_eval,
+       .init           = nft_limit_bytes_init,
+       .dump           = nft_limit_bytes_dump,
+@@ -240,7 +240,7 @@ static void nft_limit_obj_pkts_eval(struct nft_object *obj,
+                                   struct nft_regs *regs,
+                                   const struct nft_pktinfo *pkt)
+ {
+-      struct nft_limit_pkts *priv = nft_obj_data(obj);
++      struct nft_limit_priv_pkts *priv = nft_obj_data(obj);
+       if (nft_limit_eval(&priv->limit, priv->cost))
+               regs->verdict.code = NFT_BREAK;
+@@ -250,7 +250,7 @@ static int nft_limit_obj_pkts_init(const struct nft_ctx *ctx,
+                                  const struct nlattr * const tb[],
+                                  struct nft_object *obj)
+ {
+-      struct nft_limit_pkts *priv = nft_obj_data(obj);
++      struct nft_limit_priv_pkts *priv = nft_obj_data(obj);
+       int err;
+       err = nft_limit_init(&priv->limit, tb, true);
+@@ -265,7 +265,7 @@ static int nft_limit_obj_pkts_dump(struct sk_buff *skb,
+                                  struct nft_object *obj,
+                                  bool reset)
+ {
+-      const struct nft_limit_pkts *priv = nft_obj_data(obj);
++      const struct nft_limit_priv_pkts *priv = nft_obj_data(obj);
+       return nft_limit_dump(skb, &priv->limit, NFT_LIMIT_PKTS);
+ }
+@@ -273,7 +273,7 @@ static int nft_limit_obj_pkts_dump(struct sk_buff *skb,
+ static struct nft_object_type nft_limit_obj_type;
+ static const struct nft_object_ops nft_limit_obj_pkts_ops = {
+       .type           = &nft_limit_obj_type,
+-      .size           = NFT_EXPR_SIZE(sizeof(struct nft_limit_pkts)),
++      .size           = NFT_EXPR_SIZE(sizeof(struct nft_limit_priv_pkts)),
+       .init           = nft_limit_obj_pkts_init,
+       .eval           = nft_limit_obj_pkts_eval,
+       .dump           = nft_limit_obj_pkts_dump,
+@@ -283,7 +283,7 @@ static void nft_limit_obj_bytes_eval(struct nft_object *obj,
+                                    struct nft_regs *regs,
+                                    const struct nft_pktinfo *pkt)
+ {
+-      struct nft_limit *priv = nft_obj_data(obj);
++      struct nft_limit_priv *priv = nft_obj_data(obj);
+       u64 cost = div64_u64(priv->nsecs * pkt->skb->len, priv->rate);
+       if (nft_limit_eval(priv, cost))
+@@ -294,7 +294,7 @@ static int nft_limit_obj_bytes_init(const struct nft_ctx *ctx,
+                                   const struct nlattr * const tb[],
+                                   struct nft_object *obj)
+ {
+-      struct nft_limit *priv = nft_obj_data(obj);
++      struct nft_limit_priv *priv = nft_obj_data(obj);
+       return nft_limit_init(priv, tb, false);
+ }
+@@ -303,7 +303,7 @@ static int nft_limit_obj_bytes_dump(struct sk_buff *skb,
+                                   struct nft_object *obj,
+                                   bool reset)
+ {
+-      const struct nft_limit *priv = nft_obj_data(obj);
++      const struct nft_limit_priv *priv = nft_obj_data(obj);
+       return nft_limit_dump(skb, priv, NFT_LIMIT_PKT_BYTES);
+ }
+@@ -311,7 +311,7 @@ static int nft_limit_obj_bytes_dump(struct sk_buff *skb,
+ static struct nft_object_type nft_limit_obj_type;
+ static const struct nft_object_ops nft_limit_obj_bytes_ops = {
+       .type           = &nft_limit_obj_type,
+-      .size           = sizeof(struct nft_limit),
++      .size           = sizeof(struct nft_limit_priv),
+       .init           = nft_limit_obj_bytes_init,
+       .eval           = nft_limit_obj_bytes_eval,
+       .dump           = nft_limit_obj_bytes_dump,
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-nft_quota-move-stateful-fields-out-of-expr.patch b/queue-5.15/netfilter-nft_quota-move-stateful-fields-out-of-expr.patch
new file mode 100644 (file)
index 0000000..9384571
--- /dev/null
@@ -0,0 +1,141 @@
+From a5f16ce8b66dc08c87014e785d425cdc56fd22f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Jan 2022 17:11:15 +0100
+Subject: netfilter: nft_quota: move stateful fields out of expression data
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit ed0a0c60f0e50fa52853620672af97edde3d3a03 ]
+
+In preparation for the rule blob representation.
+
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: 91a139cee120 ("netfilter: nft_limit: do not ignore unsupported flags")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_quota.c | 52 +++++++++++++++++++++++++++++++++++----
+ 1 file changed, 47 insertions(+), 5 deletions(-)
+
+diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c
+index c4d1389f7185..0484aef74273 100644
+--- a/net/netfilter/nft_quota.c
++++ b/net/netfilter/nft_quota.c
+@@ -15,13 +15,13 @@
+ struct nft_quota {
+       atomic64_t      quota;
+       unsigned long   flags;
+-      atomic64_t      consumed;
++      atomic64_t      *consumed;
+ };
+ static inline bool nft_overquota(struct nft_quota *priv,
+                                const struct sk_buff *skb)
+ {
+-      return atomic64_add_return(skb->len, &priv->consumed) >=
++      return atomic64_add_return(skb->len, priv->consumed) >=
+              atomic64_read(&priv->quota);
+ }
+@@ -90,13 +90,23 @@ static int nft_quota_do_init(const struct nlattr * const tb[],
+                       return -EOPNOTSUPP;
+       }
++      priv->consumed = kmalloc(sizeof(*priv->consumed), GFP_KERNEL);
++      if (!priv->consumed)
++              return -ENOMEM;
++
+       atomic64_set(&priv->quota, quota);
+       priv->flags = flags;
+-      atomic64_set(&priv->consumed, consumed);
++      atomic64_set(priv->consumed, consumed);
+       return 0;
+ }
++static void nft_quota_do_destroy(const struct nft_ctx *ctx,
++                               struct nft_quota *priv)
++{
++      kfree(priv->consumed);
++}
++
+ static int nft_quota_obj_init(const struct nft_ctx *ctx,
+                             const struct nlattr * const tb[],
+                             struct nft_object *obj)
+@@ -128,7 +138,7 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
+        * that we see, don't go over the quota boundary in what we send to
+        * userspace.
+        */
+-      consumed = atomic64_read(&priv->consumed);
++      consumed = atomic64_read(priv->consumed);
+       quota = atomic64_read(&priv->quota);
+       if (consumed >= quota) {
+               consumed_cap = quota;
+@@ -145,7 +155,7 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
+               goto nla_put_failure;
+       if (reset) {
+-              atomic64_sub(consumed, &priv->consumed);
++              atomic64_sub(consumed, priv->consumed);
+               clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags);
+       }
+       return 0;
+@@ -162,11 +172,20 @@ static int nft_quota_obj_dump(struct sk_buff *skb, struct nft_object *obj,
+       return nft_quota_do_dump(skb, priv, reset);
+ }
++static void nft_quota_obj_destroy(const struct nft_ctx *ctx,
++                                struct nft_object *obj)
++{
++      struct nft_quota *priv = nft_obj_data(obj);
++
++      return nft_quota_do_destroy(ctx, priv);
++}
++
+ static struct nft_object_type nft_quota_obj_type;
+ static const struct nft_object_ops nft_quota_obj_ops = {
+       .type           = &nft_quota_obj_type,
+       .size           = sizeof(struct nft_quota),
+       .init           = nft_quota_obj_init,
++      .destroy        = nft_quota_obj_destroy,
+       .eval           = nft_quota_obj_eval,
+       .dump           = nft_quota_obj_dump,
+       .update         = nft_quota_obj_update,
+@@ -205,12 +224,35 @@ static int nft_quota_dump(struct sk_buff *skb, const struct nft_expr *expr)
+       return nft_quota_do_dump(skb, priv, false);
+ }
++static void nft_quota_destroy(const struct nft_ctx *ctx,
++                            const struct nft_expr *expr)
++{
++      struct nft_quota *priv = nft_expr_priv(expr);
++
++      return nft_quota_do_destroy(ctx, priv);
++}
++
++static int nft_quota_clone(struct nft_expr *dst, const struct nft_expr *src)
++{
++      struct nft_quota *priv_dst = nft_expr_priv(dst);
++
++      priv_dst->consumed = kmalloc(sizeof(*priv_dst->consumed), GFP_ATOMIC);
++      if (priv_dst->consumed)
++              return -ENOMEM;
++
++      atomic64_set(priv_dst->consumed, 0);
++
++      return 0;
++}
++
+ static struct nft_expr_type nft_quota_type;
+ static const struct nft_expr_ops nft_quota_ops = {
+       .type           = &nft_quota_type,
+       .size           = NFT_EXPR_SIZE(sizeof(struct nft_quota)),
+       .eval           = nft_quota_eval,
+       .init           = nft_quota_init,
++      .destroy        = nft_quota_destroy,
++      .clone          = nft_quota_clone,
+       .dump           = nft_quota_dump,
+ };
+-- 
+2.43.0
+
diff --git a/queue-5.15/nvmet-re-fix-tracing-strncpy-warning.patch b/queue-5.15/nvmet-re-fix-tracing-strncpy-warning.patch
new file mode 100644 (file)
index 0000000..ece0d36
--- /dev/null
@@ -0,0 +1,51 @@
+From 043ddab9e52750fb0137766c8099fa361514e5ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jan 2024 16:56:55 +0100
+Subject: nvmet: re-fix tracing strncpy() warning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 4ee7ffeb4ce50c80bc4504db6f39b25a2df6bcf4 ]
+
+An earlier patch had tried to address a warning about a string copy with
+missing zero termination:
+
+drivers/nvme/target/trace.h:52:3: warning: â€˜strncpy’ specified bound 32 equals destination size [-Wstringop-truncation]
+
+The new version causes a different warning with some compiler versions, notably
+gcc-9 and gcc-10, and also misses the zero padding that was apparently done
+intentionally in the original code:
+
+drivers/nvme/target/trace.h:56:2: error: 'strncpy' specified bound depends on the length of the source argument [-Werror=stringop-overflow=]
+
+Change it to use strscpy_pad() with the original length, which will give
+a properly padded and zero-terminated string as well as avoiding the warning.
+
+Fixes: d86481e924a7 ("nvmet: use min of device_path and disk len")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/trace.h | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/target/trace.h b/drivers/nvme/target/trace.h
+index 6109b3806b12..155334ddc13f 100644
+--- a/drivers/nvme/target/trace.h
++++ b/drivers/nvme/target/trace.h
+@@ -53,8 +53,7 @@ static inline void __assign_req_name(char *name, struct nvmet_req *req)
+               return;
+       }
+-      strncpy(name, req->ns->device_path,
+-              min_t(size_t, DISK_NAME_LEN, strlen(req->ns->device_path)));
++      strscpy_pad(name, req->ns->device_path, DISK_NAME_LEN);
+ }
+ #endif
+-- 
+2.43.0
+
diff --git a/queue-5.15/nvmet-tcp-fix-a-crash-in-nvmet_req_complete.patch b/queue-5.15/nvmet-tcp-fix-a-crash-in-nvmet_req_complete.patch
new file mode 100644 (file)
index 0000000..75bc190
--- /dev/null
@@ -0,0 +1,45 @@
+From 9b2e2211495be8c568b3467963e29d4531fd35a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Dec 2023 16:17:49 +0100
+Subject: nvmet-tcp: fix a crash in nvmet_req_complete()
+
+From: Maurizio Lombardi <mlombard@redhat.com>
+
+[ Upstream commit 0849a5441358cef02586fb2d60f707c0db195628 ]
+
+in nvmet_tcp_handle_h2c_data_pdu(), if the host sends a data_offset
+different from rbytes_done, the driver ends up calling nvmet_req_complete()
+passing a status error.
+The problem is that at this point cmd->req is not yet initialized,
+the kernel will crash after dereferencing a NULL pointer.
+
+Fix the bug by replacing the call to nvmet_req_complete() with
+nvmet_tcp_fatal_error().
+
+Fixes: 872d26a391da ("nvmet-tcp: add NVMe over TCP target driver")
+Reviewed-by: Keith Busch <kbsuch@kernel.org>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/tcp.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
+index a0a7540f048e..d25ca0742f91 100644
+--- a/drivers/nvme/target/tcp.c
++++ b/drivers/nvme/target/tcp.c
+@@ -950,8 +950,7 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
+                       data->ttag, le32_to_cpu(data->data_offset),
+                       cmd->rbytes_done);
+               /* FIXME: use path and transport errors */
+-              nvmet_req_complete(&cmd->req,
+-                      NVME_SC_INVALID_FIELD | NVME_SC_DNR);
++              nvmet_tcp_fatal_error(queue);
+               return -EPROTO;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.15/nvmet-tcp-fix-a-kernel-panic-when-host-sends-an-inva.patch b/queue-5.15/nvmet-tcp-fix-a-kernel-panic-when-host-sends-an-inva.patch
new file mode 100644 (file)
index 0000000..069985c
--- /dev/null
@@ -0,0 +1,84 @@
+From 2bb7d0362ce0f209eb453ce235cffa50abe08d6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Dec 2023 16:17:48 +0100
+Subject: nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU
+ length
+
+From: Maurizio Lombardi <mlombard@redhat.com>
+
+[ Upstream commit efa56305908ba20de2104f1b8508c6a7401833be ]
+
+If the host sends an H2CData command with an invalid DATAL,
+the kernel may crash in nvmet_tcp_build_pdu_iovec().
+
+Unable to handle kernel NULL pointer dereference at
+virtual address 0000000000000000
+lr : nvmet_tcp_io_work+0x6ac/0x718 [nvmet_tcp]
+Call trace:
+  process_one_work+0x174/0x3c8
+  worker_thread+0x2d0/0x3e8
+  kthread+0x104/0x110
+
+Fix the bug by raising a fatal error if DATAL isn't coherent
+with the packet size.
+Also, the PDU length should never exceed the MAXH2CDATA parameter which
+has been communicated to the host in nvmet_tcp_handle_icreq().
+
+Fixes: 872d26a391da ("nvmet-tcp: add NVMe over TCP target driver")
+Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/tcp.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
+index 6a57cf885db1..a0a7540f048e 100644
+--- a/drivers/nvme/target/tcp.c
++++ b/drivers/nvme/target/tcp.c
+@@ -18,6 +18,7 @@
+ #include "nvmet.h"
+ #define NVMET_TCP_DEF_INLINE_DATA_SIZE        (4 * PAGE_SIZE)
++#define NVMET_TCP_MAXH2CDATA          0x400000 /* 16M arbitrary limit */
+ /* Define the socket priority to use for connections were it is desirable
+  * that the NIC consider performing optimized packet processing or filtering.
+@@ -884,7 +885,7 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue)
+       icresp->hdr.pdo = 0;
+       icresp->hdr.plen = cpu_to_le32(icresp->hdr.hlen);
+       icresp->pfv = cpu_to_le16(NVME_TCP_PFV_1_0);
+-      icresp->maxdata = cpu_to_le32(0x400000); /* 16M arbitrary limit */
++      icresp->maxdata = cpu_to_le32(NVMET_TCP_MAXH2CDATA);
+       icresp->cpda = 0;
+       if (queue->hdr_digest)
+               icresp->digest |= NVME_TCP_HDR_DIGEST_ENABLE;
+@@ -930,6 +931,7 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
+ {
+       struct nvme_tcp_data_pdu *data = &queue->pdu.data;
+       struct nvmet_tcp_cmd *cmd;
++      unsigned int plen;
+       if (likely(queue->nr_cmds)) {
+               if (unlikely(data->ttag >= queue->nr_cmds)) {
+@@ -953,7 +955,16 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
+               return -EPROTO;
+       }
++      plen = le32_to_cpu(data->hdr.plen);
+       cmd->pdu_len = le32_to_cpu(data->data_length);
++      if (unlikely(cmd->pdu_len != (plen - sizeof(*data)) ||
++                   cmd->pdu_len == 0 ||
++                   cmd->pdu_len > NVMET_TCP_MAXH2CDATA)) {
++              pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len);
++              /* FIXME: use proper transport errors */
++              nvmet_tcp_fatal_error(queue);
++              return -EPROTO;
++      }
+       cmd->pdu_recv = 0;
+       nvmet_tcp_map_pdu_iovec(cmd);
+       queue->cmd = cmd;
+-- 
+2.43.0
+
diff --git a/queue-5.15/nvmet-tcp-fix-the-h2c-expected-pdu-len-calculation.patch b/queue-5.15/nvmet-tcp-fix-the-h2c-expected-pdu-len-calculation.patch
new file mode 100644 (file)
index 0000000..8b2805e
--- /dev/null
@@ -0,0 +1,55 @@
+From ca0d9a99bdb5391f883a25a1cd933079f6be62db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jan 2024 09:14:44 +0100
+Subject: nvmet-tcp: Fix the H2C expected PDU len calculation
+
+From: Maurizio Lombardi <mlombard@redhat.com>
+
+[ Upstream commit 9a1abc24850eb759e36a2f8869161c3b7254c904 ]
+
+The nvmet_tcp_handle_h2c_data_pdu() function should take into
+consideration the possibility that the header digest and/or the data
+digests are enabled when calculating the expected PDU length, before
+comparing it to the value stored in cmd->pdu_len.
+
+Fixes: efa56305908b ("nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU length")
+Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/tcp.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
+index d25ca0742f91..4f2164a3f466 100644
+--- a/drivers/nvme/target/tcp.c
++++ b/drivers/nvme/target/tcp.c
+@@ -931,7 +931,7 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
+ {
+       struct nvme_tcp_data_pdu *data = &queue->pdu.data;
+       struct nvmet_tcp_cmd *cmd;
+-      unsigned int plen;
++      unsigned int exp_data_len;
+       if (likely(queue->nr_cmds)) {
+               if (unlikely(data->ttag >= queue->nr_cmds)) {
+@@ -954,9 +954,13 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
+               return -EPROTO;
+       }
+-      plen = le32_to_cpu(data->hdr.plen);
++      exp_data_len = le32_to_cpu(data->hdr.plen) -
++                      nvmet_tcp_hdgst_len(queue) -
++                      nvmet_tcp_ddgst_len(queue) -
++                      sizeof(*data);
++
+       cmd->pdu_len = le32_to_cpu(data->data_length);
+-      if (unlikely(cmd->pdu_len != (plen - sizeof(*data)) ||
++      if (unlikely(cmd->pdu_len != exp_data_len ||
+                    cmd->pdu_len == 0 ||
+                    cmd->pdu_len > NVMET_TCP_MAXH2CDATA)) {
+               pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len);
+-- 
+2.43.0
+
diff --git a/queue-5.15/pci-keystone-fix-race-condition-when-initializing-ph.patch b/queue-5.15/pci-keystone-fix-race-condition-when-initializing-ph.patch
new file mode 100644 (file)
index 0000000..de77617
--- /dev/null
@@ -0,0 +1,64 @@
+From aac3e39054c3c92ea4325fb3216a7d1a92fd9dbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Sep 2023 09:48:45 +0530
+Subject: PCI: keystone: Fix race condition when initializing PHYs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Siddharth Vadapalli <s-vadapalli@ti.com>
+
+[ Upstream commit c12ca110c613a81cb0f0099019c839d078cd0f38 ]
+
+The PCI driver invokes the PHY APIs using the ks_pcie_enable_phy()
+function. The PHY in this case is the Serdes. It is possible that the
+PCI instance is configured for two lane operation across two different
+Serdes instances, using one lane of each Serdes.
+
+In such a configuration, if the reference clock for one Serdes is
+provided by the other Serdes, it results in a race condition. After the
+Serdes providing the reference clock is initialized by the PCI driver by
+invoking its PHY APIs, it is not guaranteed that this Serdes remains
+powered on long enough for the PHY APIs based initialization of the
+dependent Serdes. In such cases, the PLL of the dependent Serdes fails
+to lock due to the absence of the reference clock from the former Serdes
+which has been powered off by the PM Core.
+
+Fix this by obtaining reference to the PHYs before invoking the PHY
+initialization APIs and releasing reference after the initialization is
+complete.
+
+Link: https://lore.kernel.org/linux-pci/20230927041845.1222080-1-s-vadapalli@ti.com
+Fixes: 49229238ab47 ("PCI: keystone: Cleanup PHY handling")
+Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
+Signed-off-by: Krzysztof WilczyÅ„ski <kwilczynski@kernel.org>
+Acked-by: Ravi Gunasekaran <r-gunasekaran@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pci-keystone.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
+index eacdcb0a8771..09379e5f7724 100644
+--- a/drivers/pci/controller/dwc/pci-keystone.c
++++ b/drivers/pci/controller/dwc/pci-keystone.c
+@@ -1200,7 +1200,16 @@ static int ks_pcie_probe(struct platform_device *pdev)
+               goto err_link;
+       }
++      /* Obtain references to the PHYs */
++      for (i = 0; i < num_lanes; i++)
++              phy_pm_runtime_get_sync(ks_pcie->phy[i]);
++
+       ret = ks_pcie_enable_phy(ks_pcie);
++
++      /* Release references to the PHYs */
++      for (i = 0; i < num_lanes; i++)
++              phy_pm_runtime_put_sync(ks_pcie->phy[i]);
++
+       if (ret) {
+               dev_err(dev, "failed to enable phy\n");
+               goto err_link;
+-- 
+2.43.0
+
diff --git a/queue-5.15/perf-env-avoid-recursively-taking-env-bpf_progs.lock.patch b/queue-5.15/perf-env-avoid-recursively-taking-env-bpf_progs.lock.patch
new file mode 100644 (file)
index 0000000..b94923c
--- /dev/null
@@ -0,0 +1,276 @@
+From 9f1a7d0e444025d82dc155f5a26f53480cb47a81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Dec 2023 17:46:55 -0800
+Subject: perf env: Avoid recursively taking env->bpf_progs.lock
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 9c51f8788b5d4e9f46afbcf563255cfd355690b3 ]
+
+Add variants of perf_env__insert_bpf_prog_info(), perf_env__insert_btf()
+and perf_env__find_btf prefixed with __ to indicate the
+env->bpf_progs.lock is assumed held.
+
+Call these variants when the lock is held to avoid recursively taking it
+and potentially having a thread deadlock with itself.
+
+Fixes: f8dfeae009effc0b ("perf bpf: Show more BPF program info in print_bpf_prog_info()")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Jiri Olsa <jolsa@kernel.org>
+Acked-by: Song Liu <song@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Huacai Chen <chenhuacai@kernel.org>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: K Prateek Nayak <kprateek.nayak@amd.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Ming Wang <wangming01@loongson.cn>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Link: https://lore.kernel.org/r/20231207014655.1252484-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/bpf-event.c |  8 +++---
+ tools/perf/util/bpf-event.h | 12 ++++-----
+ tools/perf/util/env.c       | 50 ++++++++++++++++++++++++-------------
+ tools/perf/util/env.h       |  4 +++
+ tools/perf/util/header.c    |  8 +++---
+ 5 files changed, 50 insertions(+), 32 deletions(-)
+
+diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c
+index cf1b9f6ec0db..ce74bc367e9c 100644
+--- a/tools/perf/util/bpf-event.c
++++ b/tools/perf/util/bpf-event.c
+@@ -554,9 +554,9 @@ int evlist__add_bpf_sb_event(struct evlist *evlist, struct perf_env *env)
+       return evlist__add_sb_event(evlist, &attr, bpf_event__sb_cb, env);
+ }
+-void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
+-                                  struct perf_env *env,
+-                                  FILE *fp)
++void __bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
++                                    struct perf_env *env,
++                                    FILE *fp)
+ {
+       __u32 *prog_lens = (__u32 *)(uintptr_t)(info->jited_func_lens);
+       __u64 *prog_addrs = (__u64 *)(uintptr_t)(info->jited_ksyms);
+@@ -572,7 +572,7 @@ void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
+       if (info->btf_id) {
+               struct btf_node *node;
+-              node = perf_env__find_btf(env, info->btf_id);
++              node = __perf_env__find_btf(env, info->btf_id);
+               if (node)
+                       btf = btf__new((__u8 *)(node->data),
+                                      node->data_size);
+diff --git a/tools/perf/util/bpf-event.h b/tools/perf/util/bpf-event.h
+index 68f315c3df5b..50f7412464df 100644
+--- a/tools/perf/util/bpf-event.h
++++ b/tools/perf/util/bpf-event.h
+@@ -34,9 +34,9 @@ struct btf_node {
+ int machine__process_bpf(struct machine *machine, union perf_event *event,
+                        struct perf_sample *sample);
+ int evlist__add_bpf_sb_event(struct evlist *evlist, struct perf_env *env);
+-void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
+-                                  struct perf_env *env,
+-                                  FILE *fp);
++void __bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
++                                    struct perf_env *env,
++                                    FILE *fp);
+ #else
+ static inline int machine__process_bpf(struct machine *machine __maybe_unused,
+                                      union perf_event *event __maybe_unused,
+@@ -51,9 +51,9 @@ static inline int evlist__add_bpf_sb_event(struct evlist *evlist __maybe_unused,
+       return 0;
+ }
+-static inline void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info __maybe_unused,
+-                                                struct perf_env *env __maybe_unused,
+-                                                FILE *fp __maybe_unused)
++static inline void __bpf_event__print_bpf_prog_info(struct bpf_prog_info *info __maybe_unused,
++                                                  struct perf_env *env __maybe_unused,
++                                                  FILE *fp __maybe_unused)
+ {
+ }
+diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
+index 5b24eb010336..d3d67ce70f55 100644
+--- a/tools/perf/util/env.c
++++ b/tools/perf/util/env.c
+@@ -20,13 +20,19 @@ struct perf_env perf_env;
+ void perf_env__insert_bpf_prog_info(struct perf_env *env,
+                                   struct bpf_prog_info_node *info_node)
++{
++      down_write(&env->bpf_progs.lock);
++      __perf_env__insert_bpf_prog_info(env, info_node);
++      up_write(&env->bpf_progs.lock);
++}
++
++void __perf_env__insert_bpf_prog_info(struct perf_env *env, struct bpf_prog_info_node *info_node)
+ {
+       __u32 prog_id = info_node->info_linear->info.id;
+       struct bpf_prog_info_node *node;
+       struct rb_node *parent = NULL;
+       struct rb_node **p;
+-      down_write(&env->bpf_progs.lock);
+       p = &env->bpf_progs.infos.rb_node;
+       while (*p != NULL) {
+@@ -38,15 +44,13 @@ void perf_env__insert_bpf_prog_info(struct perf_env *env,
+                       p = &(*p)->rb_right;
+               } else {
+                       pr_debug("duplicated bpf prog info %u\n", prog_id);
+-                      goto out;
++                      return;
+               }
+       }
+       rb_link_node(&info_node->rb_node, parent, p);
+       rb_insert_color(&info_node->rb_node, &env->bpf_progs.infos);
+       env->bpf_progs.infos_cnt++;
+-out:
+-      up_write(&env->bpf_progs.lock);
+ }
+ struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env,
+@@ -75,14 +79,22 @@ struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env,
+ }
+ bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node)
++{
++      bool ret;
++
++      down_write(&env->bpf_progs.lock);
++      ret = __perf_env__insert_btf(env, btf_node);
++      up_write(&env->bpf_progs.lock);
++      return ret;
++}
++
++bool __perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node)
+ {
+       struct rb_node *parent = NULL;
+       __u32 btf_id = btf_node->id;
+       struct btf_node *node;
+       struct rb_node **p;
+-      bool ret = true;
+-      down_write(&env->bpf_progs.lock);
+       p = &env->bpf_progs.btfs.rb_node;
+       while (*p != NULL) {
+@@ -94,25 +106,31 @@ bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node)
+                       p = &(*p)->rb_right;
+               } else {
+                       pr_debug("duplicated btf %u\n", btf_id);
+-                      ret = false;
+-                      goto out;
++                      return false;
+               }
+       }
+       rb_link_node(&btf_node->rb_node, parent, p);
+       rb_insert_color(&btf_node->rb_node, &env->bpf_progs.btfs);
+       env->bpf_progs.btfs_cnt++;
+-out:
+-      up_write(&env->bpf_progs.lock);
+-      return ret;
++      return true;
+ }
+ struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id)
++{
++      struct btf_node *res;
++
++      down_read(&env->bpf_progs.lock);
++      res = __perf_env__find_btf(env, btf_id);
++      up_read(&env->bpf_progs.lock);
++      return res;
++}
++
++struct btf_node *__perf_env__find_btf(struct perf_env *env, __u32 btf_id)
+ {
+       struct btf_node *node = NULL;
+       struct rb_node *n;
+-      down_read(&env->bpf_progs.lock);
+       n = env->bpf_progs.btfs.rb_node;
+       while (n) {
+@@ -122,13 +140,9 @@ struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id)
+               else if (btf_id > node->id)
+                       n = n->rb_right;
+               else
+-                      goto out;
++                      return node;
+       }
+-      node = NULL;
+-
+-out:
+-      up_read(&env->bpf_progs.lock);
+-      return node;
++      return NULL;
+ }
+ /* purge data in bpf_progs.infos tree */
+diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
+index 163e5ec503a2..192318054e12 100644
+--- a/tools/perf/util/env.h
++++ b/tools/perf/util/env.h
+@@ -163,12 +163,16 @@ const char *perf_env__raw_arch(struct perf_env *env);
+ int perf_env__nr_cpus_avail(struct perf_env *env);
+ void perf_env__init(struct perf_env *env);
++void __perf_env__insert_bpf_prog_info(struct perf_env *env,
++                                    struct bpf_prog_info_node *info_node);
+ void perf_env__insert_bpf_prog_info(struct perf_env *env,
+                                   struct bpf_prog_info_node *info_node);
+ struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env,
+                                                       __u32 prog_id);
+ bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node);
++bool __perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node);
+ struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id);
++struct btf_node *__perf_env__find_btf(struct perf_env *env, __u32 btf_id);
+ int perf_env__numa_node(struct perf_env *env, int cpu);
+ #endif /* __PERF_ENV_H */
+diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
+index 25947d013603..8b0a8ac7afef 100644
+--- a/tools/perf/util/header.c
++++ b/tools/perf/util/header.c
+@@ -1735,8 +1735,8 @@ static void print_bpf_prog_info(struct feat_fd *ff, FILE *fp)
+               node = rb_entry(next, struct bpf_prog_info_node, rb_node);
+               next = rb_next(&node->rb_node);
+-              bpf_event__print_bpf_prog_info(&node->info_linear->info,
+-                                             env, fp);
++              __bpf_event__print_bpf_prog_info(&node->info_linear->info,
++                                               env, fp);
+       }
+       up_read(&env->bpf_progs.lock);
+@@ -3073,7 +3073,7 @@ static int process_bpf_prog_info(struct feat_fd *ff, void *data __maybe_unused)
+               /* after reading from file, translate offset to address */
+               bpf_program__bpil_offs_to_addr(info_linear);
+               info_node->info_linear = info_linear;
+-              perf_env__insert_bpf_prog_info(env, info_node);
++              __perf_env__insert_bpf_prog_info(env, info_node);
+       }
+       up_write(&env->bpf_progs.lock);
+@@ -3120,7 +3120,7 @@ static int process_bpf_btf(struct feat_fd *ff, void *data __maybe_unused)
+               if (__do_read(ff, node->data, data_size))
+                       goto out;
+-              perf_env__insert_btf(env, node);
++              __perf_env__insert_btf(env, node);
+               node = NULL;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.15/perf-genelf-set-elf-program-header-addresses-properl.patch b/queue-5.15/perf-genelf-set-elf-program-header-addresses-properl.patch
new file mode 100644 (file)
index 0000000..fa045ee
--- /dev/null
@@ -0,0 +1,50 @@
+From 146d8b4badd78a732fddb423f9534e1818168e1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Dec 2023 23:05:44 -0800
+Subject: perf genelf: Set ELF program header addresses properly
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit 1af478903fc48c1409a8dd6b698383b62387adf1 ]
+
+The text section starts after the ELF headers so PHDR.p_vaddr and
+others should have the correct addresses.
+
+Fixes: babd04386b1df8c3 ("perf jit: Include program header in ELF files")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Fangrui Song <maskray@google.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Lieven Hey <lieven.hey@kdab.com>
+Cc: Milian Wolff <milian.wolff@kdab.com>
+Cc: Pablo Galindo <pablogsal@gmail.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20231212070547.612536-2-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/genelf.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/util/genelf.c b/tools/perf/util/genelf.c
+index 02cd9f75e3d2..89a85601485d 100644
+--- a/tools/perf/util/genelf.c
++++ b/tools/perf/util/genelf.c
+@@ -291,9 +291,9 @@ jit_write_elf(int fd, uint64_t load_addr, const char *sym,
+        */
+       phdr = elf_newphdr(e, 1);
+       phdr[0].p_type = PT_LOAD;
+-      phdr[0].p_offset = 0;
+-      phdr[0].p_vaddr = 0;
+-      phdr[0].p_paddr = 0;
++      phdr[0].p_offset = GEN_ELF_TEXT_OFFSET;
++      phdr[0].p_vaddr = GEN_ELF_TEXT_OFFSET;
++      phdr[0].p_paddr = GEN_ELF_TEXT_OFFSET;
+       phdr[0].p_filesz = csize;
+       phdr[0].p_memsz = csize;
+       phdr[0].p_flags = PF_X | PF_R;
+-- 
+2.43.0
+
diff --git a/queue-5.15/power-supply-bq256xx-fix-some-problem-in-bq256xx_hw_.patch b/queue-5.15/power-supply-bq256xx-fix-some-problem-in-bq256xx_hw_.patch
new file mode 100644 (file)
index 0000000..7b7d866
--- /dev/null
@@ -0,0 +1,55 @@
+From ee8d4115148e28667af63590290040a08236e4c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Nov 2023 12:18:23 +0800
+Subject: power: supply: bq256xx: fix some problem in bq256xx_hw_init
+
+From: Su Hui <suhui@nfschina.com>
+
+[ Upstream commit b55d073e6501dc6077edaa945a6dad8ac5c8bbab ]
+
+smatch complains that there is a buffer overflow and clang complains
+'ret' is never read.
+
+Smatch error:
+drivers/power/supply/bq256xx_charger.c:1578 bq256xx_hw_init() error:
+buffer overflow 'bq256xx_watchdog_time' 4 <= 4
+
+Clang static checker:
+Value stored to 'ret' is never read.
+
+Add check for buffer overflow and error code from regmap_update_bits().
+
+Fixes: 32e4978bb920 ("power: supply: bq256xx: Introduce the BQ256XX charger driver")
+Signed-off-by: Su Hui <suhui@nfschina.com>
+Link: https://lore.kernel.org/r/20231116041822.1378758-1-suhui@nfschina.com
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq256xx_charger.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/bq256xx_charger.c b/drivers/power/supply/bq256xx_charger.c
+index f501ecd49202..9fb7b44e890a 100644
+--- a/drivers/power/supply/bq256xx_charger.c
++++ b/drivers/power/supply/bq256xx_charger.c
+@@ -1514,13 +1514,16 @@ static int bq256xx_hw_init(struct bq256xx_device *bq)
+                       wd_reg_val = i;
+                       break;
+               }
+-              if (bq->watchdog_timer > bq256xx_watchdog_time[i] &&
++              if (i + 1 < BQ256XX_NUM_WD_VAL &&
++                  bq->watchdog_timer > bq256xx_watchdog_time[i] &&
+                   bq->watchdog_timer < bq256xx_watchdog_time[i + 1])
+                       wd_reg_val = i;
+       }
+       ret = regmap_update_bits(bq->regmap, BQ256XX_CHARGER_CONTROL_1,
+                                BQ256XX_WATCHDOG_MASK, wd_reg_val <<
+                                               BQ256XX_WDT_BIT_SHIFT);
++      if (ret)
++              return ret;
+       ret = power_supply_get_battery_info(bq->charger, &bat_info);
+       if (ret) {
+-- 
+2.43.0
+
diff --git a/queue-5.15/power-supply-cw2015-correct-time_to_empty-units-in-s.patch b/queue-5.15/power-supply-cw2015-correct-time_to_empty-units-in-s.patch
new file mode 100644 (file)
index 0000000..e903593
--- /dev/null
@@ -0,0 +1,38 @@
+From f2d8d9bf40599f360c2151daae856c6165fc428e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Nov 2023 23:17:04 +0100
+Subject: power: supply: cw2015: correct time_to_empty units in sysfs
+
+From: Jan Palus <jpalus@fastmail.com>
+
+[ Upstream commit f37669119423ca852ca855b24732f25c0737aa57 ]
+
+RRT_ALRT register holds remaining battery time in minutes therefore it
+needs to be scaled accordingly when exposing TIME_TO_EMPTY via sysfs
+expressed in seconds
+
+Fixes: b4c7715c10c1 ("power: supply: add CellWise cw2015 fuel gauge driver")
+Signed-off-by: Jan Palus <jpalus@fastmail.com>
+Link: https://lore.kernel.org/r/20231111221704.5579-1-jpalus@fastmail.com
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/cw2015_battery.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c
+index 091868e9e9e8..587db9fd8624 100644
+--- a/drivers/power/supply/cw2015_battery.c
++++ b/drivers/power/supply/cw2015_battery.c
+@@ -490,7 +490,7 @@ static int cw_battery_get_property(struct power_supply *psy,
+       case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
+               if (cw_battery_valid_time_to_empty(cw_bat))
+-                      val->intval = cw_bat->time_to_empty;
++                      val->intval = cw_bat->time_to_empty * 60;
+               else
+                       val->intval = 0;
+               break;
+-- 
+2.43.0
+
diff --git a/queue-5.15/r8152-choose-our-usb-config-with-choose_configuratio.patch b/queue-5.15/r8152-choose-our-usb-config-with-choose_configuratio.patch
new file mode 100644 (file)
index 0000000..2f37aa2
--- /dev/null
@@ -0,0 +1,80 @@
+From 7cb0bcacfbbda3487ecaa7bdd6b625f08ee63528 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Dec 2023 10:29:52 -0800
+Subject: r8152: Choose our USB config with choose_configuration() rather than
+ probe()
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit aa4f2b3e418e8673e55145de8b8016a7a9920306 ]
+
+If you deauthorize the r8152 device (by writing 0 to the "authorized"
+field in sysfs) and then reauthorize it (by writing a 1) then it no
+longer works. This is because when you do the above we lose the
+special configuration that we set in rtl8152_cfgselector_probe().
+Deauthorizing causes the config to be set to -1 and then reauthorizing
+runs the default logic for choosing the best config.
+
+I made an attempt to fix it so that the config is kept across
+deauthorizing / reauthorizing [1] but it was a bit ugly.
+
+Let's instead use the new USB core feature to override
+choose_configuration().
+
+This patch relies upon the patches ("usb: core: Don't force USB
+generic_subclass drivers to define probe()") and ("usb: core: Allow
+subclassed USB drivers to override usb_choose_configuration()")
+
+[1] https://lore.kernel.org/r/20231130154337.1.Ie00e07f07f87149c9ce0b27ae4e26991d307e14b@changeid
+
+Fixes: ec51fbd1b8a2 ("r8152: add USB device driver for config selection")
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Grant Grundler <grundler@chromium.org>
+Link: https://lore.kernel.org/r/20231201102946.v2.3.Ie00e07f07f87149c9ce0b27ae4e26991d307e14b@changeid
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/r8152.c | 16 +++++-----------
+ 1 file changed, 5 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index e8fd743a1509..85b98fd06ba2 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -9872,7 +9872,7 @@ static struct usb_driver rtl8152_driver = {
+       .disable_hub_initiated_lpm = 1,
+ };
+-static int rtl8152_cfgselector_probe(struct usb_device *udev)
++static int rtl8152_cfgselector_choose_configuration(struct usb_device *udev)
+ {
+       struct usb_host_config *c;
+       int i, num_configs;
+@@ -9899,19 +9899,13 @@ static int rtl8152_cfgselector_probe(struct usb_device *udev)
+       if (i == num_configs)
+               return -ENODEV;
+-      if (usb_set_configuration(udev, c->desc.bConfigurationValue)) {
+-              dev_err(&udev->dev, "Failed to set configuration %d\n",
+-                      c->desc.bConfigurationValue);
+-              return -ENODEV;
+-      }
+-
+-      return 0;
++      return c->desc.bConfigurationValue;
+ }
+ static struct usb_device_driver rtl8152_cfgselector_driver = {
+-      .name =         MODULENAME "-cfgselector",
+-      .probe =        rtl8152_cfgselector_probe,
+-      .id_table =     rtl8152_table,
++      .name = MODULENAME "-cfgselector",
++      .choose_configuration = rtl8152_cfgselector_choose_configuration,
++      .id_table = rtl8152_table,
+       .generic_subclass = 1,
+       .supports_autosuspend = 1,
+ };
+-- 
+2.43.0
+
diff --git a/queue-5.15/riscv-check-if-the-code-to-patch-lies-in-the-exit-se.patch b/queue-5.15/riscv-check-if-the-code-to-patch-lies-in-the-exit-se.patch
new file mode 100644 (file)
index 0000000..34406a9
--- /dev/null
@@ -0,0 +1,110 @@
+From 3cc50c29f3eb0010ad092d4504c36d95b41b2082 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Dec 2023 10:19:26 +0100
+Subject: riscv: Check if the code to patch lies in the exit section
+
+From: Alexandre Ghiti <alexghiti@rivosinc.com>
+
+[ Upstream commit 420370f3ae3d3b883813fd3051a38805160b2b9f ]
+
+Otherwise we fall through to vmalloc_to_page() which panics since the
+address does not lie in the vmalloc region.
+
+Fixes: 043cb41a85de ("riscv: introduce interfaces to patch kernel code")
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
+Link: https://lore.kernel.org/r/20231214091926.203439-1-alexghiti@rivosinc.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/sections.h   |  1 +
+ arch/riscv/kernel/patch.c           | 11 ++++++++++-
+ arch/riscv/kernel/vmlinux-xip.lds.S |  2 ++
+ arch/riscv/kernel/vmlinux.lds.S     |  2 ++
+ 4 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h
+index 32336e8a17cb..a393d5035c54 100644
+--- a/arch/riscv/include/asm/sections.h
++++ b/arch/riscv/include/asm/sections.h
+@@ -13,6 +13,7 @@ extern char _start_kernel[];
+ extern char __init_data_begin[], __init_data_end[];
+ extern char __init_text_begin[], __init_text_end[];
+ extern char __alt_start[], __alt_end[];
++extern char __exittext_begin[], __exittext_end[];
+ static inline bool is_va_kernel_text(uintptr_t va)
+ {
+diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c
+index e099961453cc..160e5c1caa9c 100644
+--- a/arch/riscv/kernel/patch.c
++++ b/arch/riscv/kernel/patch.c
+@@ -13,6 +13,7 @@
+ #include <asm/fixmap.h>
+ #include <asm/ftrace.h>
+ #include <asm/patch.h>
++#include <asm/sections.h>
+ struct patch_insn {
+       void *addr;
+@@ -23,6 +24,14 @@ struct patch_insn {
+ int riscv_patch_in_stop_machine = false;
+ #ifdef CONFIG_MMU
++
++static inline bool is_kernel_exittext(uintptr_t addr)
++{
++      return system_state < SYSTEM_RUNNING &&
++              addr >= (uintptr_t)__exittext_begin &&
++              addr < (uintptr_t)__exittext_end;
++}
++
+ /*
+  * The fix_to_virt(, idx) needs a const value (not a dynamic variable of
+  * reg-a0) or BUILD_BUG_ON failed with "idx >= __end_of_fixed_addresses".
+@@ -33,7 +42,7 @@ static __always_inline void *patch_map(void *addr, const unsigned int fixmap)
+       uintptr_t uintaddr = (uintptr_t) addr;
+       struct page *page;
+-      if (core_kernel_text(uintaddr))
++      if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr))
+               page = phys_to_page(__pa_symbol(addr));
+       else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
+               page = vmalloc_to_page(addr);
+diff --git a/arch/riscv/kernel/vmlinux-xip.lds.S b/arch/riscv/kernel/vmlinux-xip.lds.S
+index 9c9f35091ef0..5407eafa166b 100644
+--- a/arch/riscv/kernel/vmlinux-xip.lds.S
++++ b/arch/riscv/kernel/vmlinux-xip.lds.S
+@@ -29,10 +29,12 @@ SECTIONS
+       HEAD_TEXT_SECTION
+       INIT_TEXT_SECTION(PAGE_SIZE)
+       /* we have to discard exit text and such at runtime, not link time */
++      __exittext_begin = .;
+       .exit.text :
+       {
+               EXIT_TEXT
+       }
++      __exittext_end = .;
+       .text : {
+               _text = .;
+diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
+index 5104f3a871e3..adcfe9c6a7bf 100644
+--- a/arch/riscv/kernel/vmlinux.lds.S
++++ b/arch/riscv/kernel/vmlinux.lds.S
+@@ -73,10 +73,12 @@ SECTIONS
+               __soc_builtin_dtb_table_end = .;
+       }
+       /* we have to discard exit text and such at runtime, not link time */
++      __exittext_begin = .;
+       .exit.text :
+       {
+               EXIT_TEXT
+       }
++      __exittext_end = .;
+       __init_text_end = .;
+       . = ALIGN(SECTION_ALIGN);
+-- 
+2.43.0
+
diff --git a/queue-5.15/riscv-fix-module_alloc-that-did-not-reset-the-linear.patch b/queue-5.15/riscv-fix-module_alloc-that-did-not-reset-the-linear.patch
new file mode 100644 (file)
index 0000000..ec5dbba
--- /dev/null
@@ -0,0 +1,56 @@
+From 502b7eaa2a23303d520b040017070db17d881371 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Dec 2023 14:40:26 +0100
+Subject: riscv: Fix module_alloc() that did not reset the linear mapping
+ permissions
+
+From: Alexandre Ghiti <alexghiti@rivosinc.com>
+
+[ Upstream commit 749b94b08005929bbc636df21a23322733166e35 ]
+
+After unloading a module, we must reset the linear mapping permissions,
+see the example below:
+
+Before unloading a module:
+
+0xffffaf809d65d000-0xffffaf809d6dc000    0x000000011d65d000       508K PTE .   ..     ..   D A G . . W R V
+0xffffaf809d6dc000-0xffffaf809d6dd000    0x000000011d6dc000         4K PTE .   ..     ..   D A G . . . R V
+0xffffaf809d6dd000-0xffffaf809d6e1000    0x000000011d6dd000        16K PTE .   ..     ..   D A G . . W R V
+0xffffaf809d6e1000-0xffffaf809d6e7000    0x000000011d6e1000        24K PTE .   ..     ..   D A G . X . R V
+
+After unloading a module:
+
+0xffffaf809d65d000-0xffffaf809d6e1000    0x000000011d65d000       528K PTE .   ..     ..   D A G . . W R V
+0xffffaf809d6e1000-0xffffaf809d6e7000    0x000000011d6e1000        24K PTE .   ..     ..   D A G . X W R V
+
+The last mapping is not reset and we end up with WX mappings in the linear
+mapping.
+
+So add VM_FLUSH_RESET_PERMS to our module_alloc() definition.
+
+Fixes: 0cff8bff7af8 ("riscv: avoid the PIC offset of static percpu data in module beyond 2G limits")
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Link: https://lore.kernel.org/r/20231213134027.155327-2-alexghiti@rivosinc.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/module.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
+index 4a48287513c3..24c3883c80d0 100644
+--- a/arch/riscv/kernel/module.c
++++ b/arch/riscv/kernel/module.c
+@@ -423,7 +423,8 @@ void *module_alloc(unsigned long size)
+ {
+       return __vmalloc_node_range(size, 1, MODULES_VADDR,
+                                   MODULES_END, GFP_KERNEL,
+-                                  PAGE_KERNEL, 0, NUMA_NO_NODE,
++                                  PAGE_KERNEL, VM_FLUSH_RESET_PERMS,
++                                  NUMA_NO_NODE,
+                                   __builtin_return_address(0));
+ }
+ #endif
+-- 
+2.43.0
+
diff --git a/queue-5.15/s390-pci-fix-max-size-calculation-in-zpci_memcpy_toi.patch b/queue-5.15/s390-pci-fix-max-size-calculation-in-zpci_memcpy_toi.patch
new file mode 100644 (file)
index 0000000..29de168
--- /dev/null
@@ -0,0 +1,145 @@
+From f1c49e6be846f5dd602e6388c688e6cf6119c589 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Nov 2023 16:22:49 +0100
+Subject: s390/pci: fix max size calculation in zpci_memcpy_toio()
+
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+
+[ Upstream commit 80df7d6af7f6d229b34cf237b2cc9024c07111cd ]
+
+The zpci_get_max_write_size() helper is used to determine the maximum
+size a PCI store or load can use at a given __iomem address.
+
+For the PCI block store the following restrictions apply:
+
+1. The dst + len must not cross a 4K boundary in the (pseudo-)MMIO space
+2. len must not exceed ZPCI_MAX_WRITE_SIZE
+3. len must be a multiple of 8 bytes
+4. The src address must be double word (8 byte) aligned
+5. The dst address must be double word (8 byte) aligned
+
+Otherwise only a normal PCI store which takes its src value from
+a register can be used. For these PCI store restriction 1 still applies.
+Similarly 1 also applies to PCI loads.
+
+It turns out zpci_max_write_size() instead implements stricter
+conditions which prevents PCI block stores from being used where they
+can and should be used. In particular instead of conditions 4 and 5 it
+wrongly enforces both dst and src to be size aligned. This indirectly
+covers condition 1 but also prevents many legal PCI block stores.
+
+On top of the functional shortcomings the zpci_get_max_write_size() is
+misnamed as it is used for both read and write size calculations. Rename
+it to zpci_get_max_io_size() and implement the listed conditions
+explicitly.
+
+Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
+Fixes: cd24834130ac ("s390/pci: base support")
+Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
+[agordeev@linux.ibm.com replaced spaces with tabs]
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/include/asm/pci_io.h | 32 ++++++++++++++++++--------------
+ arch/s390/pci/pci_mmio.c       | 12 ++++++------
+ 2 files changed, 24 insertions(+), 20 deletions(-)
+
+diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h
+index 287bb88f7698..2686bee800e3 100644
+--- a/arch/s390/include/asm/pci_io.h
++++ b/arch/s390/include/asm/pci_io.h
+@@ -11,6 +11,8 @@
+ /* I/O size constraints */
+ #define ZPCI_MAX_READ_SIZE    8
+ #define ZPCI_MAX_WRITE_SIZE   128
++#define ZPCI_BOUNDARY_SIZE    (1 << 12)
++#define ZPCI_BOUNDARY_MASK    (ZPCI_BOUNDARY_SIZE - 1)
+ /* I/O Map */
+ #define ZPCI_IOMAP_SHIFT              48
+@@ -125,16 +127,18 @@ static inline int zpci_read_single(void *dst, const volatile void __iomem *src,
+ int zpci_write_block(volatile void __iomem *dst, const void *src,
+                    unsigned long len);
+-static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max)
++static inline int zpci_get_max_io_size(u64 src, u64 dst, int len, int max)
+ {
+-      int count = len > max ? max : len, size = 1;
++      int offset = dst & ZPCI_BOUNDARY_MASK;
++      int size;
+-      while (!(src & 0x1) && !(dst & 0x1) && ((size << 1) <= count)) {
+-              dst = dst >> 1;
+-              src = src >> 1;
+-              size = size << 1;
+-      }
+-      return size;
++      size = min3(len, ZPCI_BOUNDARY_SIZE - offset, max);
++      if (IS_ALIGNED(src, 8) && IS_ALIGNED(dst, 8) && IS_ALIGNED(size, 8))
++              return size;
++
++      if (size >= 8)
++              return 8;
++      return rounddown_pow_of_two(size);
+ }
+ static inline int zpci_memcpy_fromio(void *dst,
+@@ -144,9 +148,9 @@ static inline int zpci_memcpy_fromio(void *dst,
+       int size, rc = 0;
+       while (n > 0) {
+-              size = zpci_get_max_write_size((u64 __force) src,
+-                                             (u64) dst, n,
+-                                             ZPCI_MAX_READ_SIZE);
++              size = zpci_get_max_io_size((u64 __force) src,
++                                          (u64) dst, n,
++                                          ZPCI_MAX_READ_SIZE);
+               rc = zpci_read_single(dst, src, size);
+               if (rc)
+                       break;
+@@ -166,9 +170,9 @@ static inline int zpci_memcpy_toio(volatile void __iomem *dst,
+               return -EINVAL;
+       while (n > 0) {
+-              size = zpci_get_max_write_size((u64 __force) dst,
+-                                             (u64) src, n,
+-                                             ZPCI_MAX_WRITE_SIZE);
++              size = zpci_get_max_io_size((u64 __force) dst,
++                                          (u64) src, n,
++                                          ZPCI_MAX_WRITE_SIZE);
+               if (size > 8) /* main path */
+                       rc = zpci_write_block(dst, src, size);
+               else
+diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c
+index b94163ee5632..7e4cb95a431c 100644
+--- a/arch/s390/pci/pci_mmio.c
++++ b/arch/s390/pci/pci_mmio.c
+@@ -96,9 +96,9 @@ static inline int __memcpy_toio_inuser(void __iomem *dst,
+               return -EINVAL;
+       while (n > 0) {
+-              size = zpci_get_max_write_size((u64 __force) dst,
+-                                             (u64 __force) src, n,
+-                                             ZPCI_MAX_WRITE_SIZE);
++              size = zpci_get_max_io_size((u64 __force) dst,
++                                          (u64 __force) src, n,
++                                          ZPCI_MAX_WRITE_SIZE);
+               if (size > 8) /* main path */
+                       rc = __pcistb_mio_inuser(dst, src, size, &status);
+               else
+@@ -241,9 +241,9 @@ static inline int __memcpy_fromio_inuser(void __user *dst,
+       u8 status;
+       while (n > 0) {
+-              size = zpci_get_max_write_size((u64 __force) src,
+-                                             (u64 __force) dst, n,
+-                                             ZPCI_MAX_READ_SIZE);
++              size = zpci_get_max_io_size((u64 __force) src,
++                                          (u64 __force) dst, n,
++                                          ZPCI_MAX_READ_SIZE);
+               rc = __pcilg_mio_inuser(dst, src, size, &status);
+               if (rc)
+                       break;
+-- 
+2.43.0
+
diff --git a/queue-5.15/selftests-mlxsw-qos_pfc-adjust-the-test-to-support-8.patch b/queue-5.15/selftests-mlxsw-qos_pfc-adjust-the-test-to-support-8.patch
new file mode 100644 (file)
index 0000000..b73f9a8
--- /dev/null
@@ -0,0 +1,88 @@
+From 50213ee73e87d3043297119fdc4a827b13856ffd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 16:04:21 +0100
+Subject: selftests: mlxsw: qos_pfc: Adjust the test to support 8 lanes
+
+From: Amit Cohen <amcohen@nvidia.com>
+
+[ Upstream commit b34f4de6d30cbaa8fed905a5080b6eace8c84dc7 ]
+
+'qos_pfc' test checks PFC behavior. The idea is to limit the traffic
+using a shaper somewhere in the flow of the packets. In this area, the
+buffer is smaller than the buffer at the beginning of the flow, so it fills
+up until there is no more space left. The test configures there PFC
+which is supposed to notice that the headroom is filling up and send PFC
+Xoff to indicate the transmitter to stop sending traffic for the priorities
+sharing this PG.
+
+The Xon/Xoff threshold is auto-configured and always equal to
+2*(MTU rounded up to cell size). Even after sending the PFC Xoff packet,
+traffic will keep arriving until the transmitter receives and processes
+the PFC packet. This amount of traffic is known as the PFC delay allowance.
+
+Currently the buffer for the delay traffic is configured as 100KB. The
+MTU in the test is 10KB, therefore the threshold for Xoff is about 20KB.
+This allows 80KB extra to be stored in this buffer.
+
+8-lane ports use two buffers among which the configured buffer is split,
+the Xoff threshold then applies to each buffer in parallel.
+
+The test does not take into account the behavior of 8-lane ports, when the
+ports are configured to 400Gbps with 8 lanes or 800Gbps with 8 lanes,
+packets are dropped and the test fails.
+
+Check if the relevant ports use 8 lanes, in such case double the size of
+the buffer, as the headroom is split half-half.
+
+Cc: Shuah Khan <shuah@kernel.org>
+Fixes: bfa804784e32 ("selftests: mlxsw: Add a PFC test")
+Signed-off-by: Amit Cohen <amcohen@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Link: https://lore.kernel.org/r/23ff11b7dff031eb04a41c0f5254a2b636cd8ebb.1705502064.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/drivers/net/mlxsw/qos_pfc.sh     | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh
+index 5d5622fc2758..56761de1ca3b 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh
+@@ -121,6 +121,9 @@ h2_destroy()
+ switch_create()
+ {
++      local lanes_swp4
++      local pg1_size
++
+       # pools
+       # -----
+@@ -230,7 +233,20 @@ switch_create()
+       dcb pfc set dev $swp4 prio-pfc all:off 1:on
+       # PG0 will get autoconfigured to Xoff, give PG1 arbitrarily 100K, which
+       # is (-2*MTU) about 80K of delay provision.
+-      dcb buffer set dev $swp4 buffer-size all:0 1:$_100KB
++      pg1_size=$_100KB
++
++      setup_wait_dev_with_timeout $swp4
++
++      lanes_swp4=$(ethtool $swp4 | grep 'Lanes:')
++      lanes_swp4=${lanes_swp4#*"Lanes: "}
++
++      # 8-lane ports use two buffers among which the configured buffer
++      # is split, so double the size to get twice (20K + 80K).
++      if [[ $lanes_swp4 -eq 8 ]]; then
++              pg1_size=$((pg1_size * 2))
++      fi
++
++      dcb buffer set dev $swp4 buffer-size all:0 1:$pg1_size
+       # bridges
+       # -------
+-- 
+2.43.0
+
diff --git a/queue-5.15/selftests-sgx-fix-uninitialized-pointer-dereference-.patch b/queue-5.15/selftests-sgx-fix-uninitialized-pointer-dereference-.patch
new file mode 100644 (file)
index 0000000..d288723
--- /dev/null
@@ -0,0 +1,52 @@
+From 89896615835ea302ba98adc4cb43dd584db4dee7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Oct 2023 17:38:42 +0200
+Subject: selftests/sgx: Fix uninitialized pointer dereference in error path
+
+From: Jo Van Bulck <jo.vanbulck@cs.kuleuven.be>
+
+[ Upstream commit 79eba8c924f7decfa71ddf187d38cb9f5f2cd7b3 ]
+
+Ensure ctx is zero-initialized, such that the encl_measure function will
+not call EVP_MD_CTX_destroy with an uninitialized ctx pointer in case of an
+early error during key generation.
+
+Fixes: 2adcba79e69d ("selftests/x86: Add a selftest for SGX")
+Signed-off-by: Jo Van Bulck <jo.vanbulck@cs.kuleuven.be>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Acked-by: Kai Huang <kai.huang@intel.com>
+Link: https://lore.kernel.org/all/20231005153854.25566-2-jo.vanbulck%40cs.kuleuven.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/sgx/sigstruct.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/sgx/sigstruct.c b/tools/testing/selftests/sgx/sigstruct.c
+index 92bbc5a15c39..a201d64f9b49 100644
+--- a/tools/testing/selftests/sgx/sigstruct.c
++++ b/tools/testing/selftests/sgx/sigstruct.c
+@@ -310,9 +310,9 @@ bool encl_measure(struct encl *encl)
+       struct sgx_sigstruct *sigstruct = &encl->sigstruct;
+       struct sgx_sigstruct_payload payload;
+       uint8_t digest[SHA256_DIGEST_LENGTH];
++      EVP_MD_CTX *ctx = NULL;
+       unsigned int siglen;
+       RSA *key = NULL;
+-      EVP_MD_CTX *ctx;
+       int i;
+       memset(sigstruct, 0, sizeof(*sigstruct));
+@@ -376,7 +376,8 @@ bool encl_measure(struct encl *encl)
+       return true;
+ err:
+-      EVP_MD_CTX_destroy(ctx);
++      if (ctx)
++              EVP_MD_CTX_destroy(ctx);
+       RSA_free(key);
+       return false;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.15/selftests-sgx-skip-non-x86_64-platform.patch b/queue-5.15/selftests-sgx-skip-non-x86_64-platform.patch
new file mode 100644 (file)
index 0000000..8337a3a
--- /dev/null
@@ -0,0 +1,48 @@
+From e8ed14e2be555884c60ee50dd87f0cf27f3bcc71 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 21:56:05 -0500
+Subject: selftests/sgx: Skip non X86_64 platform
+
+From: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
+
+[ Upstream commit 981cf568a8644161c2f15c02278ebc2834b51ba6 ]
+
+When building whole selftests on arm64, rsync gives an erorr about sgx:
+
+rsync: [sender] link_stat "/root/linux-next/tools/testing/selftests/sgx/test_encl.elf" failed: No such file or directory (2)
+rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1327) [sender=3.2.5]
+
+The root casue is sgx only used on X86_64, and shall be skipped on other
+platforms.
+
+Fix this by moving TEST_CUSTOM_PROGS and TEST_FILES inside the if check,
+then the build result will be "Skipping non-existent dir: sgx".
+
+Fixes: 2adcba79e69d ("selftests/x86: Add a selftest for SGX")
+Signed-off-by: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Link: https://lore.kernel.org/all/20231206025605.3965302-1-zhaomzhao%40126.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/sgx/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/sgx/Makefile b/tools/testing/selftests/sgx/Makefile
+index 472b27ccd7dc..394d0dde479b 100644
+--- a/tools/testing/selftests/sgx/Makefile
++++ b/tools/testing/selftests/sgx/Makefile
+@@ -16,9 +16,9 @@ HOST_CFLAGS := -Wall -Werror -g $(INCLUDES) -fPIC -z noexecstack
+ ENCL_CFLAGS := -Wall -Werror -static -nostdlib -nostartfiles -fPIC \
+              -fno-stack-protector -mrdrnd $(INCLUDES)
++ifeq ($(CAN_BUILD_X86_64), 1)
+ TEST_CUSTOM_PROGS := $(OUTPUT)/test_sgx
+-ifeq ($(CAN_BUILD_X86_64), 1)
+ all: $(TEST_CUSTOM_PROGS) $(OUTPUT)/test_encl.elf
+ endif
+-- 
+2.43.0
+
diff --git a/queue-5.15/serial-8250-omap-don-t-skip-resource-freeing-if-pm_r.patch b/queue-5.15/serial-8250-omap-don-t-skip-resource-freeing-if-pm_r.patch
new file mode 100644 (file)
index 0000000..c10defd
--- /dev/null
@@ -0,0 +1,51 @@
+From c747102c07fe0916d0d054609b801f263a06f9a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Nov 2023 16:29:29 +0100
+Subject: serial: 8250: omap: Don't skip resource freeing if
+ pm_runtime_resume_and_get() failed
+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>
+
+[ Upstream commit ad90d0358bd3b4554f243a425168fc7cebe7d04e ]
+
+Returning an error code from .remove() makes the driver core emit the
+little helpful error message:
+
+       remove callback returned a non-zero value. This will be ignored.
+
+and then remove the device anyhow. So all resources that were not freed
+are leaked in this case. Skipping serial8250_unregister_port() has the
+potential to keep enough of the UART around to trigger a use-after-free.
+
+So replace the error return (and with it the little helpful error
+message) by a more useful error message and continue to cleanup.
+
+Fixes: e3f0c638f428 ("serial: 8250: omap: Fix unpaired pm_runtime_put_sync() in omap8250_remove()")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Tony Lindgren <tony@atomide.com>
+Link: https://lore.kernel.org/r/20231110152927.70601-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_omap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
+index 20e0703f1def..770c4cabdf9b 100644
+--- a/drivers/tty/serial/8250/8250_omap.c
++++ b/drivers/tty/serial/8250/8250_omap.c
+@@ -1492,7 +1492,7 @@ static int omap8250_remove(struct platform_device *pdev)
+       err = pm_runtime_resume_and_get(&pdev->dev);
+       if (err)
+-              return err;
++              dev_err(&pdev->dev, "Failed to resume hardware\n");
+       serial8250_unregister_port(priv->line);
+       priv->line = -ENODEV;
+-- 
+2.43.0
+
diff --git a/queue-5.15/serial-imx-correct-clock-error-message-in-function-p.patch b/queue-5.15/serial-imx-correct-clock-error-message-in-function-p.patch
new file mode 100644 (file)
index 0000000..75e3c6d
--- /dev/null
@@ -0,0 +1,40 @@
+From bdae98762f9b1f7bdb819b31a54c8b931b5e5dff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Dec 2023 10:32:09 +0100
+Subject: serial: imx: Correct clock error message in function probe()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+
+[ Upstream commit 3e189470cad27d41a3a9dc02649f965b7ed1c90f ]
+
+Correct the clock error message by changing the clock name.
+
+Fixes: 1e512d45332b ("serial: imx: add error messages when .probe fails")
+Signed-off-by: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20231224093209.2612-1-cniedermaier@dh-electronics.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/imx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
+index 52f183889c95..4504b5fcc171 100644
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -2318,7 +2318,7 @@ static int imx_uart_probe(struct platform_device *pdev)
+       /* For register access, we only need to enable the ipg clock. */
+       ret = clk_prepare_enable(sport->clk_ipg);
+       if (ret) {
+-              dev_err(&pdev->dev, "failed to enable per clk: %d\n", ret);
++              dev_err(&pdev->dev, "failed to enable ipg clk: %d\n", ret);
+               return ret;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.15/serial-imx-fix-tx-statemachine-deadlock.patch b/queue-5.15/serial-imx-fix-tx-statemachine-deadlock.patch
new file mode 100644 (file)
index 0000000..65c4990
--- /dev/null
@@ -0,0 +1,58 @@
+From f44ebc5699dbf5998717aa08229e9464365fcb2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Nov 2023 14:11:10 +0100
+Subject: serial: imx: fix tx statemachine deadlock
+
+From: Paul Geurts <paul_geurts@live.nl>
+
+[ Upstream commit 78d60dae9a0c9f09aa3d6477c94047df2fe6f7b0 ]
+
+When using the serial port as RS485 port, the tx statemachine is used to
+control the RTS pin to drive the RS485 transceiver TX_EN pin. When the
+TTY port is closed in the middle of a transmission (for instance during
+userland application crash), imx_uart_shutdown disables the interface
+and disables the Transmission Complete interrupt. afer that,
+imx_uart_stop_tx bails on an incomplete transmission, to be retriggered
+by the TC interrupt. This interrupt is disabled and therefore the tx
+statemachine never transitions out of SEND. The statemachine is in
+deadlock now, and the TX_EN remains low, making the interface useless.
+
+imx_uart_stop_tx now checks for incomplete transmission AND whether TC
+interrupts are enabled before bailing to be retriggered. This makes sure
+the state machine handling is reached, and is properly set to
+WAIT_AFTER_SEND.
+
+Fixes: cb1a60923609 ("serial: imx: implement rts delaying for rs485")
+Signed-off-by: Paul Geurts <paul_geurts@live.nl>
+Tested-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
+Tested-by: Eberhard Stoll <eberhard.stoll@gmx.de>
+Link: https://lore.kernel.org/r/AM0PR09MB26758F651BC1B742EB45775995B8A@AM0PR09MB2675.eurprd09.prod.outlook.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/imx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
+index 4b9e82737e0b..52f183889c95 100644
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -450,13 +450,13 @@ static void imx_uart_stop_tx(struct uart_port *port)
+       ucr1 = imx_uart_readl(sport, UCR1);
+       imx_uart_writel(sport, ucr1 & ~UCR1_TRDYEN, UCR1);
++      ucr4 = imx_uart_readl(sport, UCR4);
+       usr2 = imx_uart_readl(sport, USR2);
+-      if (!(usr2 & USR2_TXDC)) {
++      if ((!(usr2 & USR2_TXDC)) && (ucr4 & UCR4_TCEN)) {
+               /* The shifter is still busy, so retry once TC triggers */
+               return;
+       }
+-      ucr4 = imx_uart_readl(sport, UCR4);
+       ucr4 &= ~UCR4_TCEN;
+       imx_uart_writel(sport, ucr4, UCR4);
+-- 
+2.43.0
+
index 757a642398f090d19630d81df5a507a2f18c95af..dabe54cafe6d4fbc0f34c1b9589241b76c01ed7e 100644 (file)
@@ -288,3 +288,80 @@ hid-wacom-correct-behavior-when-processing-some-confidence-false-touches.patch
 serial-sc16is7xx-add-check-for-unsupported-spi-modes-during-probe.patch
 serial-sc16is7xx-set-safe-default-spi-clock-frequency.patch
 iommu-dma-trace-bounce-buffer-usage-when-mapping-buffers.patch
+arm-9330-1-davinci-also-select-pinctrl.patch
+mfd-syscon-fix-null-pointer-dereference-in-of_syscon.patch
+leds-aw2013-select-missing-dependency-regmap_i2c.patch
+mfd-intel-lpss-fix-the-fractional-clock-divider-flag.patch
+mips-dmi-fix-early-remap-on-mips32.patch
+mips-fix-incorrect-max_low_pfn-adjustment.patch
+riscv-check-if-the-code-to-patch-lies-in-the-exit-se.patch
+riscv-fix-module_alloc-that-did-not-reset-the-linear.patch
+mips-alchemy-fix-an-out-of-bound-access-in-db1200_de.patch
+mips-alchemy-fix-an-out-of-bound-access-in-db1550_de.patch
+power-supply-cw2015-correct-time_to_empty-units-in-s.patch
+power-supply-bq256xx-fix-some-problem-in-bq256xx_hw_.patch
+serial-8250-omap-don-t-skip-resource-freeing-if-pm_r.patch
+libapi-add-missing-linux-types.h-header-to-get-the-_.patch
+usb-core-allow-subclassed-usb-drivers-to-override-us.patch
+r8152-choose-our-usb-config-with-choose_configuratio.patch
+software-node-let-args-be-null-in-software_node_get_.patch
+serial-imx-fix-tx-statemachine-deadlock.patch
+selftests-sgx-fix-uninitialized-pointer-dereference-.patch
+selftests-sgx-skip-non-x86_64-platform.patch
+iio-adc-ad9467-benefit-from-devm_clk_get_enabled-to-.patch
+iio-adc-ad9467-fix-reset-gpio-handling.patch
+iio-adc-ad9467-don-t-ignore-error-codes.patch
+iio-adc-ad9467-fix-scale-setting.patch
+perf-genelf-set-elf-program-header-addresses-properl.patch
+tty-change-tty_write_lock-s-ndelay-parameter-to-bool.patch
+tty-early-return-from-send_break-on-tty_driver_hardw.patch
+tty-don-t-check-for-signal_pending-in-send_break.patch
+tty-use-if-in-send_break-instead-of-goto.patch
+usb-cdc-acm-return-correct-error-code-on-unsupported.patch
+usb-core-fix-crash-w-usb_choose_configuration-if-no-.patch
+nvmet-tcp-fix-a-kernel-panic-when-host-sends-an-inva.patch
+nvmet-tcp-fix-a-crash-in-nvmet_req_complete.patch
+perf-env-avoid-recursively-taking-env-bpf_progs.lock.patch
+apparmor-avoid-crash-when-parsed-profile-name-is-emp.patch
+usb-xhci-mtk-fix-a-short-packet-issue-of-gen1-isoc-i.patch
+serial-imx-correct-clock-error-message-in-function-p.patch
+nvmet-re-fix-tracing-strncpy-warning.patch
+nvmet-tcp-fix-the-h2c-expected-pdu-len-calculation.patch
+pci-keystone-fix-race-condition-when-initializing-ph.patch
+s390-pci-fix-max-size-calculation-in-zpci_memcpy_toi.patch
+net-qualcomm-rmnet-fix-global-oob-in-rmnet_policy.patch
+net-ethernet-ti-am65-cpsw-fix-max-mtu-to-fit-etherne.patch
+net-phy-micrel-populate-.soft_reset-for-ksz9131.patch
+mptcp-mptcp_parse_option-fix-for-mptcpopt_mp_join.patch
+mptcp-drop-unused-sk-in-mptcp_get_options.patch
+mptcp-strict-validation-before-using-mp_opt-hmac.patch
+mptcp-use-option_mptcp_mpj_synack-in-subflow_finish_.patch
+mptcp-use-option_mptcp_mpj_syn-in-subflow_check_req.patch
+net-ravb-fix-dma_addr_t-truncation-in-error-case.patch
+net-stmmac-ethtool-fixed-calltrace-caused-by-unbalan.patch
+bpf-reject-variable-offset-alu-on-ptr_to_flow_keys.patch
+net-dsa-vsc73xx-add-null-pointer-check-to-vsc73xx_gp.patch
+netfilter-nf_tables-reject-invalid-set-policy.patch
+netfilter-nft_connlimit-move-stateful-fields-out-of-.patch
+netfilter-nft_last-move-stateful-fields-out-of-expre.patch
+netfilter-nft_quota-move-stateful-fields-out-of-expr.patch
+netfilter-nft_limit-rename-stateful-structure.patch
+netfilter-nft_limit-move-stateful-fields-out-of-expr.patch
+netfilter-nf_tables-memcg-accounting-for-dynamically.patch
+netfilter-nft_limit-do-not-ignore-unsupported-flags.patch
+netfilter-nf_tables-do-not-allow-mismatch-field-size.patch
+netfilter-nf_tables-skip-dead-set-elements-in-netlin.patch
+netfilter-nf_tables-reject-nft_set_concat-with-not-f.patch
+ipvs-avoid-stat-macros-calls-from-preemptible-contex.patch
+kdb-fix-a-potential-buffer-overflow-in-kdb_local.patch
+ethtool-netlink-add-missing-ethnl_ops_begin-complete.patch
+mlxsw-spectrum_acl_erp-fix-error-flow-of-pool-alloca.patch
+mlxsw-spectrum-use-bitmap_zalloc-when-applicable.patch
+mlxsw-spectrum_acl_tcam-add-missing-mutex_destroy.patch
+mlxsw-spectrum_acl_tcam-make-fini-symmetric-to-init.patch
+mlxsw-spectrum_acl_tcam-reorder-functions-to-avoid-f.patch
+mlxsw-spectrum_acl_tcam-fix-stack-corruption.patch
+selftests-mlxsw-qos_pfc-adjust-the-test-to-support-8.patch
+ipv6-mcast-fix-data-race-in-ipv6_mc_down-mld_ifc_wor.patch
+i2c-s3c24xx-fix-read-transfers-in-polling-mode.patch
+i2c-s3c24xx-fix-transferring-more-than-one-message-i.patch
diff --git a/queue-5.15/software-node-let-args-be-null-in-software_node_get_.patch b/queue-5.15/software-node-let-args-be-null-in-software_node_get_.patch
new file mode 100644 (file)
index 0000000..bd32fda
--- /dev/null
@@ -0,0 +1,42 @@
+From c3ab1657a7fc44ab4e06804bb672b5e33df0e239 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Nov 2023 12:10:09 +0200
+Subject: software node: Let args be NULL in software_node_get_reference_args
+
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+
+[ Upstream commit 1eaea4b3604eb9ca7d9a1e73d88fc121bb4061f5 ]
+
+fwnode_get_property_reference_args() may not be called with args argument
+NULL and while OF already supports this. Add the missing NULL check.
+
+The purpose is to be able to count the references.
+
+Fixes: b06184acf751 ("software node: Add software_node_get_reference_args()")
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20231109101010.1329587-3-sakari.ailus@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/swnode.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
+index 3ba1232ce845..15f149fc1940 100644
+--- a/drivers/base/swnode.c
++++ b/drivers/base/swnode.c
+@@ -547,6 +547,9 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
+       if (nargs > NR_FWNODE_REFERENCE_ARGS)
+               return -EINVAL;
++      if (!args)
++              return 0;
++
+       args->fwnode = software_node_get(refnode);
+       args->nargs = nargs;
+-- 
+2.43.0
+
diff --git a/queue-5.15/tty-change-tty_write_lock-s-ndelay-parameter-to-bool.patch b/queue-5.15/tty-change-tty_write_lock-s-ndelay-parameter-to-bool.patch
new file mode 100644 (file)
index 0000000..1341c40
--- /dev/null
@@ -0,0 +1,82 @@
+From b2148c7b2b283e45aa62c7654cd20dba2555944c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Aug 2023 11:14:39 +0200
+Subject: tty: change tty_write_lock()'s ndelay parameter to bool
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit af815336556df28f800669c58ab3bdad7d786b98 ]
+
+It's a yes-no parameter, so convert it to bool to be obvious.
+
+Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
+Link: https://lore.kernel.org/r/20230810091510.13006-6-jirislaby@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 66aad7d8d3ec ("usb: cdc-acm: return correct error code on unsupported break")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/tty.h       | 2 +-
+ drivers/tty/tty_io.c    | 6 +++---
+ drivers/tty/tty_ioctl.c | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h
+index 72b88aafd536..989986f67263 100644
+--- a/drivers/tty/tty.h
++++ b/drivers/tty/tty.h
+@@ -63,7 +63,7 @@ int tty_check_change(struct tty_struct *tty);
+ void __stop_tty(struct tty_struct *tty);
+ void __start_tty(struct tty_struct *tty);
+ void tty_write_unlock(struct tty_struct *tty);
+-int tty_write_lock(struct tty_struct *tty, int ndelay);
++int tty_write_lock(struct tty_struct *tty, bool ndelay);
+ void tty_vhangup_session(struct tty_struct *tty);
+ void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty);
+ int tty_signal_session_leader(struct tty_struct *tty, int exit_session);
+diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
+index 3d540dff42ef..12f6ef8d0f45 100644
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -956,7 +956,7 @@ void tty_write_unlock(struct tty_struct *tty)
+       wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT);
+ }
+-int tty_write_lock(struct tty_struct *tty, int ndelay)
++int tty_write_lock(struct tty_struct *tty, bool ndelay)
+ {
+       if (!mutex_trylock(&tty->atomic_write_lock)) {
+               if (ndelay)
+@@ -1173,7 +1173,7 @@ int tty_send_xchar(struct tty_struct *tty, char ch)
+               return 0;
+       }
+-      if (tty_write_lock(tty, 0) < 0)
++      if (tty_write_lock(tty, false) < 0)
+               return -ERESTARTSYS;
+       down_read(&tty->termios_rwsem);
+@@ -2507,7 +2507,7 @@ static int send_break(struct tty_struct *tty, unsigned int duration)
+               retval = tty->ops->break_ctl(tty, duration);
+       else {
+               /* Do the work ourselves */
+-              if (tty_write_lock(tty, 0) < 0)
++              if (tty_write_lock(tty, false) < 0)
+                       return -EINTR;
+               retval = tty->ops->break_ctl(tty, -1);
+               if (retval)
+diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c
+index 1736130f9c39..dac1e2568803 100644
+--- a/drivers/tty/tty_ioctl.c
++++ b/drivers/tty/tty_ioctl.c
+@@ -427,7 +427,7 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
+               if (retval < 0)
+                       return retval;
+-              if (tty_write_lock(tty, 0) < 0)
++              if (tty_write_lock(tty, false) < 0)
+                       goto retry_write_wait;
+               /* Racing writer? */
+-- 
+2.43.0
+
diff --git a/queue-5.15/tty-don-t-check-for-signal_pending-in-send_break.patch b/queue-5.15/tty-don-t-check-for-signal_pending-in-send_break.patch
new file mode 100644 (file)
index 0000000..7e737de
--- /dev/null
@@ -0,0 +1,38 @@
+From 5b486e365c7c442a042fdf6575972bb7258b7aaa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Sep 2023 10:51:55 +0200
+Subject: tty: don't check for signal_pending() in send_break()
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit fd99392b643b824813df2edbaebe26a2136d31e6 ]
+
+msleep_interruptible() will check on its own. So no need to do the check
+in send_break() before calling the above.
+
+Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
+Link: https://lore.kernel.org/r/20230919085156.1578-15-jirislaby@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 66aad7d8d3ec ("usb: cdc-acm: return correct error code on unsupported break")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/tty_io.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
+index a18138ce67b2..cdbf05e76bc7 100644
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -2513,8 +2513,7 @@ static int send_break(struct tty_struct *tty, unsigned int duration)
+       retval = tty->ops->break_ctl(tty, -1);
+       if (retval)
+               goto out;
+-      if (!signal_pending(current))
+-              msleep_interruptible(duration);
++      msleep_interruptible(duration);
+       retval = tty->ops->break_ctl(tty, 0);
+ out:
+       tty_write_unlock(tty);
+-- 
+2.43.0
+
diff --git a/queue-5.15/tty-early-return-from-send_break-on-tty_driver_hardw.patch b/queue-5.15/tty-early-return-from-send_break-on-tty_driver_hardw.patch
new file mode 100644 (file)
index 0000000..2711f37
--- /dev/null
@@ -0,0 +1,74 @@
+From 31c357c68b71dd039bbcfd4b427e5d85eb8b3684 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Sep 2023 10:51:54 +0200
+Subject: tty: early return from send_break() on TTY_DRIVER_HARDWARE_BREAK
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit 66619686d187b4a6395316b7f39881e945dce4bc ]
+
+If the driver sets TTY_DRIVER_HARDWARE_BREAK, we leave ops->break_ctl()
+to the driver and return from send_break(). But we do it using a local
+variable and keep the code flowing through the end of the function.
+Instead, do 'return' immediately with the ops->break_ctl()'s return
+value.
+
+This way, we don't have to stuff the 'else' branch of the 'if' with the
+software break handling. And we can re-indent the function too.
+
+Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
+Link: https://lore.kernel.org/r/20230919085156.1578-14-jirislaby@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 66aad7d8d3ec ("usb: cdc-acm: return correct error code on unsupported break")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/tty_io.c | 32 +++++++++++++++++---------------
+ 1 file changed, 17 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
+index 12f6ef8d0f45..a18138ce67b2 100644
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -2504,22 +2504,24 @@ static int send_break(struct tty_struct *tty, unsigned int duration)
+               return 0;
+       if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK)
+-              retval = tty->ops->break_ctl(tty, duration);
+-      else {
+-              /* Do the work ourselves */
+-              if (tty_write_lock(tty, false) < 0)
+-                      return -EINTR;
+-              retval = tty->ops->break_ctl(tty, -1);
+-              if (retval)
+-                      goto out;
+-              if (!signal_pending(current))
+-                      msleep_interruptible(duration);
+-              retval = tty->ops->break_ctl(tty, 0);
++              return tty->ops->break_ctl(tty, duration);
++
++      /* Do the work ourselves */
++      if (tty_write_lock(tty, false) < 0)
++              return -EINTR;
++
++      retval = tty->ops->break_ctl(tty, -1);
++      if (retval)
++              goto out;
++      if (!signal_pending(current))
++              msleep_interruptible(duration);
++      retval = tty->ops->break_ctl(tty, 0);
+ out:
+-              tty_write_unlock(tty);
+-              if (signal_pending(current))
+-                      retval = -EINTR;
+-      }
++      tty_write_unlock(tty);
++
++      if (signal_pending(current))
++              retval = -EINTR;
++
+       return retval;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.15/tty-use-if-in-send_break-instead-of-goto.patch b/queue-5.15/tty-use-if-in-send_break-instead-of-goto.patch
new file mode 100644 (file)
index 0000000..61b3cdd
--- /dev/null
@@ -0,0 +1,44 @@
+From 9712565f47570a25292acde78a78a5c9d92939f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Sep 2023 10:51:56 +0200
+Subject: tty: use 'if' in send_break() instead of 'goto'
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit 24f2cd019946fc2e88e632d2e24a34c2cc3f2be4 ]
+
+Now, the "jumped-over" code is simple enough to be put inside an 'if'.
+Do so to make it 'goto'-less.
+
+Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
+Link: https://lore.kernel.org/r/20230919085156.1578-16-jirislaby@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 66aad7d8d3ec ("usb: cdc-acm: return correct error code on unsupported break")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/tty_io.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
+index cdbf05e76bc7..82b49aa0f9de 100644
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -2511,11 +2511,10 @@ static int send_break(struct tty_struct *tty, unsigned int duration)
+               return -EINTR;
+       retval = tty->ops->break_ctl(tty, -1);
+-      if (retval)
+-              goto out;
+-      msleep_interruptible(duration);
+-      retval = tty->ops->break_ctl(tty, 0);
+-out:
++      if (!retval) {
++              msleep_interruptible(duration);
++              retval = tty->ops->break_ctl(tty, 0);
++      }
+       tty_write_unlock(tty);
+       if (signal_pending(current))
+-- 
+2.43.0
+
diff --git a/queue-5.15/usb-cdc-acm-return-correct-error-code-on-unsupported.patch b/queue-5.15/usb-cdc-acm-return-correct-error-code-on-unsupported.patch
new file mode 100644 (file)
index 0000000..25142a9
--- /dev/null
@@ -0,0 +1,62 @@
+From 8be40c1c0c6e2f5c24b4de1c1cb8b27b8d7ea3df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Dec 2023 14:26:30 +0100
+Subject: usb: cdc-acm: return correct error code on unsupported break
+
+From: Oliver Neukum <oneukum@suse.com>
+
+[ Upstream commit 66aad7d8d3ec5a3a8ec2023841bcec2ded5f65c9 ]
+
+In ACM support for sending breaks to devices is optional.
+If a device says that it doenot support sending breaks,
+the host must respect that.
+Given the number of optional features providing tty operations
+for each combination is not practical and errors need to be
+returned dynamically if unsupported features are requested.
+
+In case a device does not support break, we want the tty layer
+to treat that like it treats drivers that statically cannot
+support sending a break. It ignores the inability and does nothing.
+This patch uses EOPNOTSUPP to indicate that.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Fixes: 9e98966c7bb94 ("tty: rework break handling")
+Link: https://lore.kernel.org/r/20231207132639.18250-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/tty_io.c        | 3 +++
+ drivers/usb/class/cdc-acm.c | 3 +++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
+index 82b49aa0f9de..d5191065b6e9 100644
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -2514,6 +2514,9 @@ static int send_break(struct tty_struct *tty, unsigned int duration)
+       if (!retval) {
+               msleep_interruptible(duration);
+               retval = tty->ops->break_ctl(tty, 0);
++      } else if (retval == -EOPNOTSUPP) {
++              /* some drivers can tell only dynamically */
++              retval = 0;
+       }
+       tty_write_unlock(tty);
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index adc154b691d0..f21fd809e44f 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -896,6 +896,9 @@ static int acm_tty_break_ctl(struct tty_struct *tty, int state)
+       struct acm *acm = tty->driver_data;
+       int retval;
++      if (!(acm->ctrl_caps & USB_CDC_CAP_BRK))
++              return -EOPNOTSUPP;
++
+       retval = acm_send_break(acm, state ? 0xffff : 0);
+       if (retval < 0)
+               dev_dbg(&acm->control->dev,
+-- 
+2.43.0
+
diff --git a/queue-5.15/usb-core-allow-subclassed-usb-drivers-to-override-us.patch b/queue-5.15/usb-core-allow-subclassed-usb-drivers-to-override-us.patch
new file mode 100644 (file)
index 0000000..4268b5f
--- /dev/null
@@ -0,0 +1,89 @@
+From 692bc9dc9b8cd469bb61a68003639f223d6bc15c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Dec 2023 10:29:51 -0800
+Subject: usb: core: Allow subclassed USB drivers to override
+ usb_choose_configuration()
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit a87b8e3be926af0fc3b9b1af42b1127bd1ff077c ]
+
+For some USB devices we might want to do something different for
+usb_choose_configuration(). One example here is the r8152 driver where
+we want to end up using the vendor driver with the preferred
+interface.
+
+The r8152 driver tried to make things work by implementing a USB
+generic_subclass driver and then overriding the normal config
+selection after it happened. This is less than ideal and also caused
+breakage if someone deauthorized and re-authorized the USB device
+because the USB core ended up going back to it's default logic for
+choosing the best config. I made an attempt to fix this [1] but it was
+a bit ugly.
+
+Let's do this better and allow USB generic_subclass drivers to
+override usb_choose_configuration().
+
+[1] https://lore.kernel.org/r/20231130154337.1.Ie00e07f07f87149c9ce0b27ae4e26991d307e14b@changeid
+
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20231201102946.v2.2.Iade5fa31997f1a0ca3e1dec0591633b02471df12@changeid
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: aa4f2b3e418e ("r8152: Choose our USB config with choose_configuration() rather than probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/core/generic.c | 7 +++++++
+ include/linux/usb.h        | 6 ++++++
+ 2 files changed, 13 insertions(+)
+
+diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
+index 26f9fb9f67ca..57f6cab36ef6 100644
+--- a/drivers/usb/core/generic.c
++++ b/drivers/usb/core/generic.c
+@@ -59,10 +59,17 @@ int usb_choose_configuration(struct usb_device *udev)
+       int num_configs;
+       int insufficient_power = 0;
+       struct usb_host_config *c, *best;
++      struct usb_device_driver *udriver = to_usb_device_driver(udev->dev.driver);
+       if (usb_device_is_owned(udev))
+               return 0;
++      if (udriver->choose_configuration) {
++              i = udriver->choose_configuration(udev);
++              if (i >= 0)
++                      return i;
++      }
++
+       best = NULL;
+       c = udev->config;
+       num_configs = udev->descriptor.bNumConfigurations;
+diff --git a/include/linux/usb.h b/include/linux/usb.h
+index 987550fd46fa..d879fc573f43 100644
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -1241,6 +1241,9 @@ struct usb_driver {
+  *    module is being unloaded.
+  * @suspend: Called when the device is going to be suspended by the system.
+  * @resume: Called when the device is being resumed by the system.
++ * @choose_configuration: If non-NULL, called instead of the default
++ *    usb_choose_configuration(). If this returns an error then we'll go
++ *    on to call the normal usb_choose_configuration().
+  * @dev_groups: Attributes attached to the device that will be created once it
+  *    is bound to the driver.
+  * @drvwrap: Driver-model core structure wrapper.
+@@ -1264,6 +1267,9 @@ struct usb_device_driver {
+       int (*suspend) (struct usb_device *udev, pm_message_t message);
+       int (*resume) (struct usb_device *udev, pm_message_t message);
++
++      int (*choose_configuration) (struct usb_device *udev);
++
+       const struct attribute_group **dev_groups;
+       struct usbdrv_wrap drvwrap;
+       const struct usb_device_id *id_table;
+-- 
+2.43.0
+
diff --git a/queue-5.15/usb-core-fix-crash-w-usb_choose_configuration-if-no-.patch b/queue-5.15/usb-core-fix-crash-w-usb_choose_configuration-if-no-.patch
new file mode 100644 (file)
index 0000000..f005bc1
--- /dev/null
@@ -0,0 +1,64 @@
+From 75ea98ad215b45d2ceb7a803dc6b6463c19b9564 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Dec 2023 07:32:41 -0800
+Subject: usb: core: Fix crash w/ usb_choose_configuration() if no driver
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit 44995e6f07028f798efd0c3c11a1efc78330f600 ]
+
+It's possible that usb_choose_configuration() can get called when a
+USB device has no driver. In this case the recent commit a87b8e3be926
+("usb: core: Allow subclassed USB drivers to override
+usb_choose_configuration()") can cause a crash since it dereferenced
+the driver structure without checking for NULL. Let's add a check.
+
+A USB device with no driver is an anomaly, so make
+usb_choose_configuration() return immediately if there is no driver.
+
+This was seen in the real world when usbguard got ahold of a r8152
+device at the wrong time. It can also be simulated via this on a
+computer with one r8152-based USB Ethernet adapter:
+  cd /sys/bus/usb/drivers/r8152-cfgselector
+  to_unbind="$(ls -d *-*)"
+  real_dir="$(readlink -f "${to_unbind}")"
+  echo "${to_unbind}" > unbind
+  cd "${real_dir}"
+  echo 0 > authorized
+  echo 1 > authorized
+
+Fixes: a87b8e3be926 ("usb: core: Allow subclassed USB drivers to override usb_choose_configuration()")
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://lore.kernel.org/r/20231211073237.v3.1.If27eb3bf7812f91ab83810f232292f032f4203e0@changeid
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/core/generic.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
+index 57f6cab36ef6..77aefe0f4fc5 100644
+--- a/drivers/usb/core/generic.c
++++ b/drivers/usb/core/generic.c
+@@ -59,7 +59,16 @@ int usb_choose_configuration(struct usb_device *udev)
+       int num_configs;
+       int insufficient_power = 0;
+       struct usb_host_config *c, *best;
+-      struct usb_device_driver *udriver = to_usb_device_driver(udev->dev.driver);
++      struct usb_device_driver *udriver;
++
++      /*
++       * If a USB device (not an interface) doesn't have a driver then the
++       * kernel has no business trying to select or install a configuration
++       * for it.
++       */
++      if (!udev->dev.driver)
++              return -1;
++      udriver = to_usb_device_driver(udev->dev.driver);
+       if (usb_device_is_owned(udev))
+               return 0;
+-- 
+2.43.0
+
diff --git a/queue-5.15/usb-xhci-mtk-fix-a-short-packet-issue-of-gen1-isoc-i.patch b/queue-5.15/usb-xhci-mtk-fix-a-short-packet-issue-of-gen1-isoc-i.patch
new file mode 100644 (file)
index 0000000..264e3b1
--- /dev/null
@@ -0,0 +1,129 @@
+From b807342984b95ffb355061adb416c24c7b065fd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jan 2024 14:16:39 +0800
+Subject: usb: xhci-mtk: fix a short packet issue of gen1 isoc-in transfer
+
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+
+[ Upstream commit 017dbfc05c31284150819890b4cc86a699cbdb71 ]
+
+For Gen1 isoc-in transfer, host still send out unexpected ACK after device
+finish the burst with a short packet, this will cause an exception on the
+connected device, such as, a usb 4k camera.
+It can be fixed by setting rxfifo depth less than 4k bytes, prefer to use
+3k here, the side-effect is that may cause performance drop about 10%,
+including bulk transfer.
+
+Fixes: 926d60ae64a6 ("usb: xhci-mtk: modify the SOF/ITP interval for mt8195")
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Link: https://lore.kernel.org/r/20240104061640.7335-2-chunfeng.yun@mediatek.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-mtk.c | 40 +++++++++++++++++++++++++++++++++++--
+ drivers/usb/host/xhci-mtk.h |  2 ++
+ 2 files changed, 40 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+index b55ddc1156cc..4e5c7d3fb4bc 100644
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -7,6 +7,7 @@
+  *  Chunfeng Yun <chunfeng.yun@mediatek.com>
+  */
++#include <linux/bitfield.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/iopoll.h>
+ #include <linux/kernel.h>
+@@ -72,6 +73,9 @@
+ #define FRMCNT_LEV1_RANG      (0x12b << 8)
+ #define FRMCNT_LEV1_RANG_MASK GENMASK(19, 8)
++#define HSCH_CFG1             0x960
++#define SCH3_RXFIFO_DEPTH_MASK        GENMASK(21, 20)
++
+ #define SS_GEN2_EOF_CFG               0x990
+ #define SSG2EOF_OFFSET                0x3c
+@@ -100,6 +104,8 @@
+ #define SSC_IP_SLEEP_EN       BIT(4)
+ #define SSC_SPM_INT_EN                BIT(1)
++#define SCH_FIFO_TO_KB(x)     ((x) >> 10)
++
+ enum ssusb_uwk_vers {
+       SSUSB_UWK_V1 = 1,
+       SSUSB_UWK_V2,
+@@ -147,6 +153,35 @@ static void xhci_mtk_set_frame_interval(struct xhci_hcd_mtk *mtk)
+       writel(value, hcd->regs + SS_GEN2_EOF_CFG);
+ }
++/*
++ * workaround: usb3.2 gen1 isoc rx hw issue
++ * host send out unexpected ACK afer device fininsh a burst transfer with
++ * a short packet.
++ */
++static void xhci_mtk_rxfifo_depth_set(struct xhci_hcd_mtk *mtk)
++{
++      struct usb_hcd *hcd = mtk->hcd;
++      u32 value;
++
++      if (!mtk->rxfifo_depth)
++              return;
++
++      value = readl(hcd->regs + HSCH_CFG1);
++      value &= ~SCH3_RXFIFO_DEPTH_MASK;
++      value |= FIELD_PREP(SCH3_RXFIFO_DEPTH_MASK,
++                          SCH_FIFO_TO_KB(mtk->rxfifo_depth) - 1);
++      writel(value, hcd->regs + HSCH_CFG1);
++}
++
++static void xhci_mtk_init_quirk(struct xhci_hcd_mtk *mtk)
++{
++      /* workaround only for mt8195 */
++      xhci_mtk_set_frame_interval(mtk);
++
++      /* workaround for SoCs using SSUSB about before IPM v1.6.0 */
++      xhci_mtk_rxfifo_depth_set(mtk);
++}
++
+ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
+ {
+       struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs;
+@@ -429,8 +464,7 @@ static int xhci_mtk_setup(struct usb_hcd *hcd)
+               if (ret)
+                       return ret;
+-              /* workaround only for mt8195 */
+-              xhci_mtk_set_frame_interval(mtk);
++              xhci_mtk_init_quirk(mtk);
+       }
+       ret = xhci_gen_setup(hcd, xhci_mtk_quirks);
+@@ -517,6 +551,8 @@ static int xhci_mtk_probe(struct platform_device *pdev)
+       of_property_read_u32(node, "mediatek,u2p-dis-msk",
+                            &mtk->u2p_dis_msk);
++      of_property_read_u32(node, "rx-fifo-depth", &mtk->rxfifo_depth);
++
+       ret = usb_wakeup_of_property_parse(mtk, node);
+       if (ret) {
+               dev_err(dev, "failed to parse uwk property\n");
+diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
+index 4b1ea89f959a..153fc7ba1609 100644
+--- a/drivers/usb/host/xhci-mtk.h
++++ b/drivers/usb/host/xhci-mtk.h
+@@ -161,6 +161,8 @@ struct xhci_hcd_mtk {
+       struct regmap *uwk;
+       u32 uwk_reg_base;
+       u32 uwk_vers;
++      /* quirk */
++      u32 rxfifo_depth;
+ };
+ static inline struct xhci_hcd_mtk *hcd_to_mtk(struct usb_hcd *hcd)
+-- 
+2.43.0
+