]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.1
authorSasha Levin <sashal@kernel.org>
Sat, 7 Oct 2023 12:15:42 +0000 (08:15 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 7 Oct 2023 12:15:42 +0000 (08:15 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
66 files changed:
queue-6.1/bluetooth-delete-unused-hci_req_prepare_suspend-decl.patch [new file with mode: 0644]
queue-6.1/bluetooth-iso-fix-handling-of-listen-for-unicast.patch [new file with mode: 0644]
queue-6.1/bpf-add-bpf_fib_lookup_skip_neigh-for-bpf_fib_lookup.patch [new file with mode: 0644]
queue-6.1/bpf-fix-tr-dereferencing.patch [new file with mode: 0644]
queue-6.1/bpf-sockmap-do-not-inc-copied_seq-when-peek-flag-set.patch [new file with mode: 0644]
queue-6.1/bpf-sockmap-reject-sk_msg-egress-redirects-to-non-tc.patch [new file with mode: 0644]
queue-6.1/bpf-tcp_read_skb-needs-to-pop-skb-regardless-of-seq.patch [new file with mode: 0644]
queue-6.1/drivers-net-process-the-result-of-hdlc_open-and-add-.patch [new file with mode: 0644]
queue-6.1/erofs-fix-memory-leak-of-lzma-global-compressed-dedu.patch [new file with mode: 0644]
queue-6.1/hid-intel-ish-hid-ipc-disable-and-reenable-acpi-gpe-.patch [new file with mode: 0644]
queue-6.1/hid-sony-fix-a-potential-memory-leak-in-sony_probe.patch [new file with mode: 0644]
queue-6.1/hid-sony-remove-duplicate-null-check-before-calling-.patch [new file with mode: 0644]
queue-6.1/ibmveth-remove-condition-to-recompute-tcp-header-che.patch [new file with mode: 0644]
queue-6.1/ima-finish-deprecation-of-ima_trusted_keyring-kconfi.patch [new file with mode: 0644]
queue-6.1/ima-rework-config_ima-dependency-block.patch [new file with mode: 0644]
queue-6.1/intel_idle-add-emerald-rapids-xeon-support.patch [new file with mode: 0644]
queue-6.1/iommu-mediatek-fix-share-pgtable-for-iova-over-4gb.patch [new file with mode: 0644]
queue-6.1/ipv4-ipv6-fix-handling-of-transhdrlen-in-__ip-6-_app.patch [new file with mode: 0644]
queue-6.1/ipv4-set-offload_failed-flag-in-fibmatch-results.patch [new file with mode: 0644]
queue-6.1/ipv6-tcp-add-a-missing-nf_reset_ct-in-3whs-handling.patch [new file with mode: 0644]
queue-6.1/leds-drop-bug_on-check-for-led_color_id_multi.patch [new file with mode: 0644]
queue-6.1/modpost-add-missing-else-to-the-of-check.patch [new file with mode: 0644]
queue-6.1/neighbour-annotate-lockless-accesses-to-n-nud_state.patch [new file with mode: 0644]
queue-6.1/neighbour-fix-data-races-around-n-output.patch [new file with mode: 0644]
queue-6.1/neighbour-switch-to-standard-rcu-instead-of-rcu_bh.patch [new file with mode: 0644]
queue-6.1/net-dsa-mv88e6xxx-avoid-eeprom-timeout-when-eeprom-i.patch [new file with mode: 0644]
queue-6.1/net-ethernet-ti-am65-cpsw-fix-error-code-in-am65_cps.patch [new file with mode: 0644]
queue-6.1/net-fix-possible-store-tearing-in-neigh_periodic_wor.patch [new file with mode: 0644]
queue-6.1/net-nfc-llcp-add-lock-when-modifying-device-list.patch [new file with mode: 0644]
queue-6.1/net-stmmac-dwmac-stm32-fix-resume-on-stm32-mcu.patch [new file with mode: 0644]
queue-6.1/net-usb-smsc75xx-fix-uninit-value-access-in-__smsc75.patch [new file with mode: 0644]
queue-6.1/netfilter-handle-the-connecting-collision-properly-i.patch [new file with mode: 0644]
queue-6.1/netfilter-nf_tables-deduplicate-nft_register_obj-aud.patch [new file with mode: 0644]
queue-6.1/netfilter-nf_tables-nft_set_rbtree-fix-spurious-inse.patch [new file with mode: 0644]
queue-6.1/netlink-annotate-data-races-around-sk-sk_err.patch [new file with mode: 0644]
queue-6.1/netlink-fix-potential-skb-memleak-in-netlink_ack.patch [new file with mode: 0644]
queue-6.1/netlink-split-up-copies-in-the-ack-construction.patch [new file with mode: 0644]
queue-6.1/nfsv4-fix-a-nfs4_state_manager-race.patch [new file with mode: 0644]
queue-6.1/perf-x86-amd-core-fix-overflow-reset-on-hotplug.patch [new file with mode: 0644]
queue-6.1/perf-x86-amd-do-not-warn-on-every-irq.patch [new file with mode: 0644]
queue-6.1/ptp-ocp-fix-error-handling-in-ptp_ocp_device_init.patch [new file with mode: 0644]
queue-6.1/regmap-rbtree-fix-wrong-register-marked-as-in-cache-.patch [new file with mode: 0644]
queue-6.1/regulator-core-regulator_register-set-device-class-e.patch [new file with mode: 0644]
queue-6.1/regulator-mt6358-drop-_sshub-regulators.patch [new file with mode: 0644]
queue-6.1/regulator-mt6358-split-ops-for-buck-and-linear-range.patch [new file with mode: 0644]
queue-6.1/regulator-mt6358-use-linear-voltage-helpers-for-sing.patch [new file with mode: 0644]
queue-6.1/scsi-target-core-fix-deadlock-due-to-recursive-locki.patch [new file with mode: 0644]
queue-6.1/sctp-update-hb-timer-immediately-after-users-change-.patch [new file with mode: 0644]
queue-6.1/sctp-update-transport-state-when-processing-a-dupcoo.patch [new file with mode: 0644]
queue-6.1/selftests-netfilter-extend-nft_audit.sh.patch [new file with mode: 0644]
queue-6.1/selftests-netfilter-test-nf_tables-audit-logging.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/tcp-fix-delayed-acks-for-mss-boundary-condition.patch [new file with mode: 0644]
queue-6.1/tcp-fix-quick-ack-counting-to-count-actual-acks-of-n.patch [new file with mode: 0644]
queue-6.1/tipc-fix-a-potential-deadlock-on-tx-lock.patch [new file with mode: 0644]
queue-6.1/ubi-refuse-attaching-if-mtd-s-erasesize-is-0.patch [new file with mode: 0644]
queue-6.1/wifi-cfg80211-add-a-work-abstraction-with-special-se.patch [new file with mode: 0644]
queue-6.1/wifi-cfg80211-add-missing-kernel-doc-for-cqm_rssi_wo.patch [new file with mode: 0644]
queue-6.1/wifi-cfg80211-fix-cqm_config-access-race.patch [new file with mode: 0644]
queue-6.1/wifi-cfg80211-hold-wiphy-lock-in-auto-disconnect.patch [new file with mode: 0644]
queue-6.1/wifi-cfg80211-move-wowlan-disable-under-locks.patch [new file with mode: 0644]
queue-6.1/wifi-iwlwifi-dbg_ini-fix-structure-packing.patch [new file with mode: 0644]
queue-6.1/wifi-iwlwifi-mvm-fix-a-memory-corruption-issue.patch [new file with mode: 0644]
queue-6.1/wifi-mac80211-fix-potential-key-use-after-free.patch [new file with mode: 0644]
queue-6.1/wifi-mt76-mt76x02-fix-mt76x0-external-lna-gain-handl.patch [new file with mode: 0644]
queue-6.1/wifi-mwifiex-fix-oob-check-condition-in-mwifiex_proc.patch [new file with mode: 0644]

diff --git a/queue-6.1/bluetooth-delete-unused-hci_req_prepare_suspend-decl.patch b/queue-6.1/bluetooth-delete-unused-hci_req_prepare_suspend-decl.patch
new file mode 100644 (file)
index 0000000..bb600a4
--- /dev/null
@@ -0,0 +1,35 @@
+From 4f53ce07db6914c71f70c921fe7ad6192988e5bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Aug 2023 16:13:13 +0800
+Subject: Bluetooth: Delete unused hci_req_prepare_suspend() declaration
+
+From: Yao Xiao <xiaoyao@rock-chips.com>
+
+[ Upstream commit cbaabbcdcbd355f0a1ccc09a925575c51c270750 ]
+
+hci_req_prepare_suspend() has been deprecated in favor of
+hci_suspend_sync().
+
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Yao Xiao <xiaoyao@rock-chips.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_request.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/net/bluetooth/hci_request.h b/net/bluetooth/hci_request.h
+index b9c5a98238374..0be75cf0efed8 100644
+--- a/net/bluetooth/hci_request.h
++++ b/net/bluetooth/hci_request.h
+@@ -71,7 +71,5 @@ struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen,
+ void hci_req_add_le_scan_disable(struct hci_request *req, bool rpa_le_conn);
+ void hci_req_add_le_passive_scan(struct hci_request *req);
+-void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next);
+-
+ void hci_request_setup(struct hci_dev *hdev);
+ void hci_request_cancel_all(struct hci_dev *hdev);
+-- 
+2.40.1
+
diff --git a/queue-6.1/bluetooth-iso-fix-handling-of-listen-for-unicast.patch b/queue-6.1/bluetooth-iso-fix-handling-of-listen-for-unicast.patch
new file mode 100644 (file)
index 0000000..98e7cf4
--- /dev/null
@@ -0,0 +1,57 @@
+From 88965576c56c6c7b8efa06ebaff331a29c4fc6be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Aug 2023 13:05:45 -0700
+Subject: Bluetooth: ISO: Fix handling of listen for unicast
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit e0275ea52169412b8faccb4e2f4fed8a057844c6 ]
+
+iso_listen_cis shall only return -EADDRINUSE if the listening socket has
+the destination set to BDADDR_ANY otherwise if the destination is set to
+a specific address it is for broadcast which shall be ignored.
+
+Fixes: f764a6c2c1e4 ("Bluetooth: ISO: Add broadcast support")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/iso.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index 5cd2e775915be..91e990accbf20 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -458,7 +458,7 @@ static void iso_recv_frame(struct iso_conn *conn, struct sk_buff *skb)
+ }
+ /* -------- Socket interface ---------- */
+-static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *ba)
++static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *src, bdaddr_t *dst)
+ {
+       struct sock *sk;
+@@ -466,7 +466,10 @@ static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *ba)
+               if (sk->sk_state != BT_LISTEN)
+                       continue;
+-              if (!bacmp(&iso_pi(sk)->src, ba))
++              if (bacmp(&iso_pi(sk)->dst, dst))
++                      continue;
++
++              if (!bacmp(&iso_pi(sk)->src, src))
+                       return sk;
+       }
+@@ -910,7 +913,7 @@ static int iso_listen_cis(struct sock *sk)
+       write_lock(&iso_sk_list.lock);
+-      if (__iso_get_sock_listen_by_addr(&iso_pi(sk)->src))
++      if (__iso_get_sock_listen_by_addr(&iso_pi(sk)->src, &iso_pi(sk)->dst))
+               err = -EADDRINUSE;
+       write_unlock(&iso_sk_list.lock);
+-- 
+2.40.1
+
diff --git a/queue-6.1/bpf-add-bpf_fib_lookup_skip_neigh-for-bpf_fib_lookup.patch b/queue-6.1/bpf-add-bpf_fib_lookup_skip_neigh-for-bpf_fib_lookup.patch
new file mode 100644 (file)
index 0000000..ef36719
--- /dev/null
@@ -0,0 +1,184 @@
+From ac8edd5765ff616b44db2115b52b8084da24dc22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Feb 2023 12:55:14 -0800
+Subject: bpf: Add BPF_FIB_LOOKUP_SKIP_NEIGH for bpf_fib_lookup
+
+From: Martin KaFai Lau <martin.lau@kernel.org>
+
+[ Upstream commit 31de4105f00d64570139bc5494a201b0bd57349f ]
+
+The bpf_fib_lookup() also looks up the neigh table.
+This was done before bpf_redirect_neigh() was added.
+
+In the use case that does not manage the neigh table
+and requires bpf_fib_lookup() to lookup a fib to
+decide if it needs to redirect or not, the bpf prog can
+depend only on using bpf_redirect_neigh() to lookup the
+neigh. It also keeps the neigh entries fresh and connected.
+
+This patch adds a bpf_fib_lookup flag, SKIP_NEIGH, to avoid
+the double neigh lookup when the bpf prog always call
+bpf_redirect_neigh() to do the neigh lookup. The params->smac
+output is skipped together when SKIP_NEIGH is set because
+bpf_redirect_neigh() will figure out the smac also.
+
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20230217205515.3583372-1-martin.lau@linux.dev
+Stable-dep-of: 5baa0433a15e ("neighbour: fix data-races around n->output")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/bpf.h       |  6 ++++++
+ net/core/filter.c              | 39 ++++++++++++++++++++++------------
+ tools/include/uapi/linux/bpf.h |  6 ++++++
+ 3 files changed, 38 insertions(+), 13 deletions(-)
+
+diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
+index 53bc487947197..92dbe89dafbf5 100644
+--- a/include/uapi/linux/bpf.h
++++ b/include/uapi/linux/bpf.h
+@@ -3112,6 +3112,11 @@ union bpf_attr {
+  *            **BPF_FIB_LOOKUP_OUTPUT**
+  *                    Perform lookup from an egress perspective (default is
+  *                    ingress).
++ *            **BPF_FIB_LOOKUP_SKIP_NEIGH**
++ *                    Skip the neighbour table lookup. *params*->dmac
++ *                    and *params*->smac will not be set as output. A common
++ *                    use case is to call **bpf_redirect_neigh**\ () after
++ *                    doing **bpf_fib_lookup**\ ().
+  *
+  *            *ctx* is either **struct xdp_md** for XDP programs or
+  *            **struct sk_buff** tc cls_act programs.
+@@ -6678,6 +6683,7 @@ struct bpf_raw_tracepoint_args {
+ enum {
+       BPF_FIB_LOOKUP_DIRECT  = (1U << 0),
+       BPF_FIB_LOOKUP_OUTPUT  = (1U << 1),
++      BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
+ };
+ enum {
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 9fd7c88b5db4e..6ef62d84dcac5 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -5674,12 +5674,8 @@ static const struct bpf_func_proto bpf_skb_get_xfrm_state_proto = {
+ #endif
+ #if IS_ENABLED(CONFIG_INET) || IS_ENABLED(CONFIG_IPV6)
+-static int bpf_fib_set_fwd_params(struct bpf_fib_lookup *params,
+-                                const struct neighbour *neigh,
+-                                const struct net_device *dev, u32 mtu)
++static int bpf_fib_set_fwd_params(struct bpf_fib_lookup *params, u32 mtu)
+ {
+-      memcpy(params->dmac, neigh->ha, ETH_ALEN);
+-      memcpy(params->smac, dev->dev_addr, ETH_ALEN);
+       params->h_vlan_TCI = 0;
+       params->h_vlan_proto = 0;
+       if (mtu)
+@@ -5790,21 +5786,29 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
+       if (likely(nhc->nhc_gw_family != AF_INET6)) {
+               if (nhc->nhc_gw_family)
+                       params->ipv4_dst = nhc->nhc_gw.ipv4;
+-
+-              neigh = __ipv4_neigh_lookup_noref(dev,
+-                                               (__force u32)params->ipv4_dst);
+       } else {
+               struct in6_addr *dst = (struct in6_addr *)params->ipv6_dst;
+               params->family = AF_INET6;
+               *dst = nhc->nhc_gw.ipv6;
+-              neigh = __ipv6_neigh_lookup_noref_stub(dev, dst);
+       }
++      if (flags & BPF_FIB_LOOKUP_SKIP_NEIGH)
++              goto set_fwd_params;
++
++      if (likely(nhc->nhc_gw_family != AF_INET6))
++              neigh = __ipv4_neigh_lookup_noref(dev,
++                                                (__force u32)params->ipv4_dst);
++      else
++              neigh = __ipv6_neigh_lookup_noref_stub(dev, params->ipv6_dst);
++
+       if (!neigh || !(neigh->nud_state & NUD_VALID))
+               return BPF_FIB_LKUP_RET_NO_NEIGH;
++      memcpy(params->dmac, neigh->ha, ETH_ALEN);
++      memcpy(params->smac, dev->dev_addr, ETH_ALEN);
+-      return bpf_fib_set_fwd_params(params, neigh, dev, mtu);
++set_fwd_params:
++      return bpf_fib_set_fwd_params(params, mtu);
+ }
+ #endif
+@@ -5912,24 +5916,33 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
+       params->rt_metric = res.f6i->fib6_metric;
+       params->ifindex = dev->ifindex;
++      if (flags & BPF_FIB_LOOKUP_SKIP_NEIGH)
++              goto set_fwd_params;
++
+       /* xdp and cls_bpf programs are run in RCU-bh so rcu_read_lock_bh is
+        * not needed here.
+        */
+       neigh = __ipv6_neigh_lookup_noref_stub(dev, dst);
+       if (!neigh || !(neigh->nud_state & NUD_VALID))
+               return BPF_FIB_LKUP_RET_NO_NEIGH;
++      memcpy(params->dmac, neigh->ha, ETH_ALEN);
++      memcpy(params->smac, dev->dev_addr, ETH_ALEN);
+-      return bpf_fib_set_fwd_params(params, neigh, dev, mtu);
++set_fwd_params:
++      return bpf_fib_set_fwd_params(params, mtu);
+ }
+ #endif
++#define BPF_FIB_LOOKUP_MASK (BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_OUTPUT | \
++                           BPF_FIB_LOOKUP_SKIP_NEIGH)
++
+ BPF_CALL_4(bpf_xdp_fib_lookup, struct xdp_buff *, ctx,
+          struct bpf_fib_lookup *, params, int, plen, u32, flags)
+ {
+       if (plen < sizeof(*params))
+               return -EINVAL;
+-      if (flags & ~(BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_OUTPUT))
++      if (flags & ~BPF_FIB_LOOKUP_MASK)
+               return -EINVAL;
+       switch (params->family) {
+@@ -5967,7 +5980,7 @@ BPF_CALL_4(bpf_skb_fib_lookup, struct sk_buff *, skb,
+       if (plen < sizeof(*params))
+               return -EINVAL;
+-      if (flags & ~(BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_OUTPUT))
++      if (flags & ~BPF_FIB_LOOKUP_MASK)
+               return -EINVAL;
+       if (params->tot_len)
+diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
+index 53bc487947197..92dbe89dafbf5 100644
+--- a/tools/include/uapi/linux/bpf.h
++++ b/tools/include/uapi/linux/bpf.h
+@@ -3112,6 +3112,11 @@ union bpf_attr {
+  *            **BPF_FIB_LOOKUP_OUTPUT**
+  *                    Perform lookup from an egress perspective (default is
+  *                    ingress).
++ *            **BPF_FIB_LOOKUP_SKIP_NEIGH**
++ *                    Skip the neighbour table lookup. *params*->dmac
++ *                    and *params*->smac will not be set as output. A common
++ *                    use case is to call **bpf_redirect_neigh**\ () after
++ *                    doing **bpf_fib_lookup**\ ().
+  *
+  *            *ctx* is either **struct xdp_md** for XDP programs or
+  *            **struct sk_buff** tc cls_act programs.
+@@ -6678,6 +6683,7 @@ struct bpf_raw_tracepoint_args {
+ enum {
+       BPF_FIB_LOOKUP_DIRECT  = (1U << 0),
+       BPF_FIB_LOOKUP_OUTPUT  = (1U << 1),
++      BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
+ };
+ enum {
+-- 
+2.40.1
+
diff --git a/queue-6.1/bpf-fix-tr-dereferencing.patch b/queue-6.1/bpf-fix-tr-dereferencing.patch
new file mode 100644 (file)
index 0000000..cfb5de6
--- /dev/null
@@ -0,0 +1,42 @@
+From cced480fe9d91660cb2f0159309d1f12d76e77a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Sep 2023 23:38:46 +0800
+Subject: bpf: Fix tr dereferencing
+
+From: Leon Hwang <hffilwlqm@gmail.com>
+
+[ Upstream commit b724a6418f1f853bcb39c8923bf14a50c7bdbd07 ]
+
+Fix 'tr' dereferencing bug when CONFIG_BPF_JIT is turned off.
+
+When CONFIG_BPF_JIT is turned off, 'bpf_trampoline_get()' returns NULL,
+which is same as the cases when CONFIG_BPF_JIT is turned on.
+
+Closes: https://lore.kernel.org/r/202309131936.5Nc8eUD0-lkp@intel.com/
+Fixes: f7b12b6fea00 ("bpf: verifier: refactor check_attach_btf_id()")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Leon Hwang <hffilwlqm@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20230917153846.88732-1-hffilwlqm@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/bpf.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 1ed2ec035e779..1fba826f0acef 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -1065,7 +1065,7 @@ static inline int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
+ static inline struct bpf_trampoline *bpf_trampoline_get(u64 key,
+                                                       struct bpf_attach_target_info *tgt_info)
+ {
+-      return ERR_PTR(-EOPNOTSUPP);
++      return NULL;
+ }
+ static inline void bpf_trampoline_put(struct bpf_trampoline *tr) {}
+ #define DEFINE_BPF_DISPATCHER(name)
+-- 
+2.40.1
+
diff --git a/queue-6.1/bpf-sockmap-do-not-inc-copied_seq-when-peek-flag-set.patch b/queue-6.1/bpf-sockmap-do-not-inc-copied_seq-when-peek-flag-set.patch
new file mode 100644 (file)
index 0000000..12187f9
--- /dev/null
@@ -0,0 +1,59 @@
+From 4d3a6bf061c2fc98147d0b3f38173fdac2238a81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Sep 2023 20:52:59 -0700
+Subject: bpf, sockmap: Do not inc copied_seq when PEEK flag set
+
+From: John Fastabend <john.fastabend@gmail.com>
+
+[ Upstream commit da9e915eaf5dadb1963b7738cdfa42ed55212445 ]
+
+When data is peek'd off the receive queue we shouldn't considered it
+copied from tcp_sock side. When we increment copied_seq this will confuse
+tcp_data_ready() because copied_seq can be arbitrarily increased. From
+application side it results in poll() operations not waking up when
+expected.
+
+Notice tcp stack without BPF recvmsg programs also does not increment
+copied_seq.
+
+We broke this when we moved copied_seq into recvmsg to only update when
+actual copy was happening. But, it wasn't working correctly either before
+because the tcp_data_ready() tried to use the copied_seq value to see
+if data was read by user yet. See fixes tags.
+
+Fixes: e5c6de5fa0258 ("bpf, sockmap: Incorrectly handling copied_seq")
+Fixes: 04919bed948dc ("tcp: Introduce tcp_read_skb()")
+Signed-off-by: John Fastabend <john.fastabend@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
+Link: https://lore.kernel.org/bpf/20230926035300.135096-3-john.fastabend@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_bpf.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index 5f93918c063c7..f53380fd89bcf 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -217,6 +217,7 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
+                                 int *addr_len)
+ {
+       struct tcp_sock *tcp = tcp_sk(sk);
++      int peek = flags & MSG_PEEK;
+       u32 seq = tcp->copied_seq;
+       struct sk_psock *psock;
+       int copied = 0;
+@@ -306,7 +307,8 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
+               copied = -EAGAIN;
+       }
+ out:
+-      WRITE_ONCE(tcp->copied_seq, seq);
++      if (!peek)
++              WRITE_ONCE(tcp->copied_seq, seq);
+       tcp_rcv_space_adjust(sk);
+       if (copied > 0)
+               __tcp_cleanup_rbuf(sk, copied);
+-- 
+2.40.1
+
diff --git a/queue-6.1/bpf-sockmap-reject-sk_msg-egress-redirects-to-non-tc.patch b/queue-6.1/bpf-sockmap-reject-sk_msg-egress-redirects-to-non-tc.patch
new file mode 100644 (file)
index 0000000..c0aa325
--- /dev/null
@@ -0,0 +1,102 @@
+From c9dfc35768f2edbd512083b1cb72d74fc19fdef2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Sep 2023 12:20:55 +0200
+Subject: bpf, sockmap: Reject sk_msg egress redirects to non-TCP sockets
+
+From: Jakub Sitnicki <jakub@cloudflare.com>
+
+[ Upstream commit b80e31baa43614e086a9d29dc1151932b1bd7fc5 ]
+
+With a SOCKMAP/SOCKHASH map and an sk_msg program user can steer messages
+sent from one TCP socket (s1) to actually egress from another TCP
+socket (s2):
+
+tcp_bpf_sendmsg(s1)            // = sk_prot->sendmsg
+  tcp_bpf_send_verdict(s1)     // __SK_REDIRECT case
+    tcp_bpf_sendmsg_redir(s2)
+      tcp_bpf_push_locked(s2)
+       tcp_bpf_push(s2)
+         tcp_rate_check_app_limited(s2) // expects tcp_sock
+         tcp_sendmsg_locked(s2)         // ditto
+
+There is a hard-coded assumption in the call-chain, that the egress
+socket (s2) is a TCP socket.
+
+However in commit 122e6c79efe1 ("sock_map: Update sock type checks for
+UDP") we have enabled redirects to non-TCP sockets. This was done for the
+sake of BPF sk_skb programs. There was no indention to support sk_msg
+send-to-egress use case.
+
+As a result, attempts to send-to-egress through a non-TCP socket lead to a
+crash due to invalid downcast from sock to tcp_sock:
+
+ BUG: kernel NULL pointer dereference, address: 000000000000002f
+ ...
+ Call Trace:
+  <TASK>
+  ? show_regs+0x60/0x70
+  ? __die+0x1f/0x70
+  ? page_fault_oops+0x80/0x160
+  ? do_user_addr_fault+0x2d7/0x800
+  ? rcu_is_watching+0x11/0x50
+  ? exc_page_fault+0x70/0x1c0
+  ? asm_exc_page_fault+0x27/0x30
+  ? tcp_tso_segs+0x14/0xa0
+  tcp_write_xmit+0x67/0xce0
+  __tcp_push_pending_frames+0x32/0xf0
+  tcp_push+0x107/0x140
+  tcp_sendmsg_locked+0x99f/0xbb0
+  tcp_bpf_push+0x19d/0x3a0
+  tcp_bpf_sendmsg_redir+0x55/0xd0
+  tcp_bpf_send_verdict+0x407/0x550
+  tcp_bpf_sendmsg+0x1a1/0x390
+  inet_sendmsg+0x6a/0x70
+  sock_sendmsg+0x9d/0xc0
+  ? sockfd_lookup_light+0x12/0x80
+  __sys_sendto+0x10e/0x160
+  ? syscall_enter_from_user_mode+0x20/0x60
+  ? __this_cpu_preempt_check+0x13/0x20
+  ? lockdep_hardirqs_on+0x82/0x110
+  __x64_sys_sendto+0x1f/0x30
+  do_syscall_64+0x38/0x90
+  entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Reject selecting a non-TCP sockets as redirect target from a BPF sk_msg
+program to prevent the crash. When attempted, user will receive an EACCES
+error from send/sendto/sendmsg() syscall.
+
+Fixes: 122e6c79efe1 ("sock_map: Update sock type checks for UDP")
+Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20230920102055.42662-1-jakub@cloudflare.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock_map.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index 96db7409baa12..38e01f82f2ef3 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -670,6 +670,8 @@ BPF_CALL_4(bpf_msg_redirect_map, struct sk_msg *, msg,
+       sk = __sock_map_lookup_elem(map, key);
+       if (unlikely(!sk || !sock_map_redirect_allowed(sk)))
+               return SK_DROP;
++      if (!(flags & BPF_F_INGRESS) && !sk_is_tcp(sk))
++              return SK_DROP;
+       msg->flags = flags;
+       msg->sk_redir = sk;
+@@ -1262,6 +1264,8 @@ BPF_CALL_4(bpf_msg_redirect_hash, struct sk_msg *, msg,
+       sk = __sock_hash_lookup_elem(map, key);
+       if (unlikely(!sk || !sock_map_redirect_allowed(sk)))
+               return SK_DROP;
++      if (!(flags & BPF_F_INGRESS) && !sk_is_tcp(sk))
++              return SK_DROP;
+       msg->flags = flags;
+       msg->sk_redir = sk;
+-- 
+2.40.1
+
diff --git a/queue-6.1/bpf-tcp_read_skb-needs-to-pop-skb-regardless-of-seq.patch b/queue-6.1/bpf-tcp_read_skb-needs-to-pop-skb-regardless-of-seq.patch
new file mode 100644 (file)
index 0000000..79756ec
--- /dev/null
@@ -0,0 +1,99 @@
+From 4aaf9d7f800dc13345bcf22bf5d848662be1a42c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Sep 2023 20:52:58 -0700
+Subject: bpf: tcp_read_skb needs to pop skb regardless of seq
+
+From: John Fastabend <john.fastabend@gmail.com>
+
+[ Upstream commit 9b7177b1df64b8d7f85700027c324aadd6aded00 ]
+
+Before fix e5c6de5fa0258 tcp_read_skb() would increment the tp->copied-seq
+value. This (as described in the commit) would cause an error for apps
+because once that is incremented the application might believe there is no
+data to be read. Then some apps would stall or abort believing no data is
+available.
+
+However, the fix is incomplete because it introduces another issue in
+the skb dequeue. The loop does tcp_recv_skb() in a while loop to consume
+as many skbs as possible. The problem is the call is ...
+
+  tcp_recv_skb(sk, seq, &offset)
+
+... where 'seq' is:
+
+  u32 seq = tp->copied_seq;
+
+Now we can hit a case where we've yet incremented copied_seq from BPF side,
+but then tcp_recv_skb() fails this test ...
+
+ if (offset < skb->len || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN))
+
+... so that instead of returning the skb we call tcp_eat_recv_skb() which
+frees the skb. This is because the routine believes the SKB has been collapsed
+per comment:
+
+ /* This looks weird, but this can happen if TCP collapsing
+  * splitted a fat GRO packet, while we released socket lock
+  * in skb_splice_bits()
+  */
+
+This can't happen here we've unlinked the full SKB and orphaned it. Anyways
+it would confuse any BPF programs if the data were suddenly moved underneath
+it.
+
+To fix this situation do simpler operation and just skb_peek() the data
+of the queue followed by the unlink. It shouldn't need to check this
+condition and tcp_read_skb() reads entire skbs so there is no need to
+handle the 'offset!=0' case as we would see in tcp_read_sock().
+
+Fixes: e5c6de5fa0258 ("bpf, sockmap: Incorrectly handling copied_seq")
+Fixes: 04919bed948dc ("tcp: Introduce tcp_read_skb()")
+Signed-off-by: John Fastabend <john.fastabend@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
+Link: https://lore.kernel.org/bpf/20230926035300.135096-2-john.fastabend@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index fab25d4f3a6f1..96fdde6e42b1b 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -1755,16 +1755,13 @@ EXPORT_SYMBOL(tcp_read_sock);
+ int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
+ {
+-      struct tcp_sock *tp = tcp_sk(sk);
+-      u32 seq = tp->copied_seq;
+       struct sk_buff *skb;
+       int copied = 0;
+-      u32 offset;
+       if (sk->sk_state == TCP_LISTEN)
+               return -ENOTCONN;
+-      while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
++      while ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) {
+               u8 tcp_flags;
+               int used;
+@@ -1777,13 +1774,10 @@ int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
+                               copied = used;
+                       break;
+               }
+-              seq += used;
+               copied += used;
+-              if (tcp_flags & TCPHDR_FIN) {
+-                      ++seq;
++              if (tcp_flags & TCPHDR_FIN)
+                       break;
+-              }
+       }
+       return copied;
+ }
+-- 
+2.40.1
+
diff --git a/queue-6.1/drivers-net-process-the-result-of-hdlc_open-and-add-.patch b/queue-6.1/drivers-net-process-the-result-of-hdlc_open-and-add-.patch
new file mode 100644 (file)
index 0000000..9c35c84
--- /dev/null
@@ -0,0 +1,78 @@
+From db6eec7850b1d562c10d86a30b549b8c80062f77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Sep 2023 17:25:02 +0300
+Subject: drivers/net: process the result of hdlc_open() and add call of
+ hdlc_close() in uhdlc_close()
+
+From: Alexandra Diupina <adiupina@astralinux.ru>
+
+[ Upstream commit a59addacf899b1b21a7b7449a1c52c98704c2472 ]
+
+Process the result of hdlc_open() and call uhdlc_close()
+in case of an error. It is necessary to pass the error
+code up the control flow, similar to a possible
+error in request_irq().
+Also add a hdlc_close() call to the uhdlc_close()
+because the comment to hdlc_close() says it must be called
+by the hardware driver when the HDLC device is being closed
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
+Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
+Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wan/fsl_ucc_hdlc.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
+index 1c53b55469270..5fec8abe8e1d3 100644
+--- a/drivers/net/wan/fsl_ucc_hdlc.c
++++ b/drivers/net/wan/fsl_ucc_hdlc.c
+@@ -34,6 +34,8 @@
+ #define TDM_PPPOHT_SLIC_MAXIN
+ #define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | R_LG_S)
++static int uhdlc_close(struct net_device *dev);
++
+ static struct ucc_tdm_info utdm_primary_info = {
+       .uf_info = {
+               .tsa = 0,
+@@ -708,6 +710,7 @@ static int uhdlc_open(struct net_device *dev)
+       hdlc_device *hdlc = dev_to_hdlc(dev);
+       struct ucc_hdlc_private *priv = hdlc->priv;
+       struct ucc_tdm *utdm = priv->utdm;
++      int rc = 0;
+       if (priv->hdlc_busy != 1) {
+               if (request_irq(priv->ut_info->uf_info.irq,
+@@ -731,10 +734,13 @@ static int uhdlc_open(struct net_device *dev)
+               napi_enable(&priv->napi);
+               netdev_reset_queue(dev);
+               netif_start_queue(dev);
+-              hdlc_open(dev);
++
++              rc = hdlc_open(dev);
++              if (rc)
++                      uhdlc_close(dev);
+       }
+-      return 0;
++      return rc;
+ }
+ static void uhdlc_memclean(struct ucc_hdlc_private *priv)
+@@ -824,6 +830,8 @@ static int uhdlc_close(struct net_device *dev)
+       netdev_reset_queue(dev);
+       priv->hdlc_busy = 0;
++      hdlc_close(dev);
++
+       return 0;
+ }
+-- 
+2.40.1
+
diff --git a/queue-6.1/erofs-fix-memory-leak-of-lzma-global-compressed-dedu.patch b/queue-6.1/erofs-fix-memory-leak-of-lzma-global-compressed-dedu.patch
new file mode 100644 (file)
index 0000000..6588449
--- /dev/null
@@ -0,0 +1,45 @@
+From f3db9a070ca35d59630002ea2b49bd7db5b86fe7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Sep 2023 13:05:42 +0800
+Subject: erofs: fix memory leak of LZMA global compressed deduplication
+
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+
+[ Upstream commit 75a5221630fe5aa3fedba7a06be618db0f79ba1e ]
+
+When stressing microLZMA EROFS images with the new global compressed
+deduplication feature enabled (`-Ededupe`), I found some short-lived
+temporary pages weren't properly released, which could slowly cause
+unexpected OOMs hours later.
+
+Let's fix it now (LZ4 and DEFLATE don't have this issue.)
+
+Fixes: 5c2a64252c5d ("erofs: introduce partial-referenced pclusters")
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Link: https://lore.kernel.org/r/20230907050542.97152-1-hsiangkao@linux.alibaba.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/erofs/decompressor_lzma.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/fs/erofs/decompressor_lzma.c b/fs/erofs/decompressor_lzma.c
+index 5cd612a8f8584..49addc345aebe 100644
+--- a/fs/erofs/decompressor_lzma.c
++++ b/fs/erofs/decompressor_lzma.c
+@@ -217,9 +217,12 @@ int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
+                       strm->buf.out_size = min_t(u32, outlen,
+                                                  PAGE_SIZE - pageofs);
+                       outlen -= strm->buf.out_size;
+-                      if (!rq->out[no] && rq->fillgaps)       /* deduped */
++                      if (!rq->out[no] && rq->fillgaps) {     /* deduped */
+                               rq->out[no] = erofs_allocpage(pagepool,
+                                               GFP_KERNEL | __GFP_NOFAIL);
++                              set_page_private(rq->out[no],
++                                               Z_EROFS_SHORTLIVED_PAGE);
++                      }
+                       if (rq->out[no])
+                               strm->buf.out = kmap(rq->out[no]) + pageofs;
+                       pageofs = 0;
+-- 
+2.40.1
+
diff --git a/queue-6.1/hid-intel-ish-hid-ipc-disable-and-reenable-acpi-gpe-.patch b/queue-6.1/hid-intel-ish-hid-ipc-disable-and-reenable-acpi-gpe-.patch
new file mode 100644 (file)
index 0000000..3abb397
--- /dev/null
@@ -0,0 +1,55 @@
+From d416776961722288846eabda3a0f7dccacd41ee7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Oct 2023 08:53:32 -0700
+Subject: HID: intel-ish-hid: ipc: Disable and reenable ACPI GPE bit
+
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+[ Upstream commit 8f02139ad9a7e6e5c05712f8c1501eebed8eacfd ]
+
+The EHL (Elkhart Lake) based platforms provide a OOB (Out of band)
+service, which allows to wakup device when the system is in S5 (Soft-Off
+state). This OOB service can be enabled/disabled from BIOS settings. When
+enabled, the ISH device gets PME wake capability. To enable PME wakeup,
+driver also needs to enable ACPI GPE bit.
+
+On resume, BIOS will clear the wakeup bit. So driver need to re-enable it
+in resume function to keep the next wakeup capability. But this BIOS
+clearing of wakeup bit doesn't decrement internal OS GPE reference count,
+so this reenabling on every resume will cause reference count to overflow.
+
+So first disable and reenable ACPI GPE bit using acpi_disable_gpe().
+
+Fixes: 2e23a70edabe ("HID: intel-ish-hid: ipc: finish power flow for EHL OOB")
+Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Closes: https://lore.kernel.org/lkml/CAAd53p4=oLYiH2YbVSmrPNj1zpMcfp=Wxbasb5vhMXOWCArLCg@mail.gmail.com/T/
+Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/intel-ish-hid/ipc/pci-ish.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
+index 55cb25038e632..710fda5f19e1c 100644
+--- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c
++++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
+@@ -133,6 +133,14 @@ static int enable_gpe(struct device *dev)
+       }
+       wakeup = &adev->wakeup;
++      /*
++       * Call acpi_disable_gpe(), so that reference count
++       * gpe_event_info->runtime_count doesn't overflow.
++       * When gpe_event_info->runtime_count = 0, the call
++       * to acpi_disable_gpe() simply return.
++       */
++      acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number);
++
+       acpi_sts = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number);
+       if (ACPI_FAILURE(acpi_sts)) {
+               dev_err(dev, "enable ose_gpe failed\n");
+-- 
+2.40.1
+
diff --git a/queue-6.1/hid-sony-fix-a-potential-memory-leak-in-sony_probe.patch b/queue-6.1/hid-sony-fix-a-potential-memory-leak-in-sony_probe.patch
new file mode 100644 (file)
index 0000000..b4df0e1
--- /dev/null
@@ -0,0 +1,37 @@
+From 697c2e49a066dbd6bdbe33a98c1bba4ef9c8342c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Sep 2023 18:04:00 +0200
+Subject: HID: sony: Fix a potential memory leak in sony_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit e1cd4004cde7c9b694bbdd8def0e02288ee58c74 ]
+
+If an error occurs after a successful usb_alloc_urb() call, usb_free_urb()
+should be called.
+
+Fixes: fb1a79a6b6e1 ("HID: sony: fix freeze when inserting ghlive ps3/wii dongles")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-sony.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
+index 03691cdcfb8e1..5b3f58e068807 100644
+--- a/drivers/hid/hid-sony.c
++++ b/drivers/hid/hid-sony.c
+@@ -3074,6 +3074,9 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
+       return ret;
+ err:
++      if (sc->ghl_urb)
++              usb_free_urb(sc->ghl_urb);
++
+       hid_hw_stop(hdev);
+       return ret;
+ }
+-- 
+2.40.1
+
diff --git a/queue-6.1/hid-sony-remove-duplicate-null-check-before-calling-.patch b/queue-6.1/hid-sony-remove-duplicate-null-check-before-calling-.patch
new file mode 100644 (file)
index 0000000..c18b200
--- /dev/null
@@ -0,0 +1,37 @@
+From 08ed744451cd06f1bf4aa44d4b8afef442c7fdf8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Oct 2023 21:10:41 +0200
+Subject: HID: sony: remove duplicate NULL check before calling usb_free_urb()
+
+From: Jiri Kosina <jkosina@suse.cz>
+
+[ Upstream commit b328dd02e19cb9d3b35de4322f5363516a20ac8c ]
+
+usb_free_urb() does the NULL check itself, so there is no need to duplicate
+it prior to calling.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: e1cd4004cde7c9 ("HID: sony: Fix a potential memory leak in sony_probe()")
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-sony.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
+index 5b3f58e068807..f7f7252d839ee 100644
+--- a/drivers/hid/hid-sony.c
++++ b/drivers/hid/hid-sony.c
+@@ -3074,8 +3074,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
+       return ret;
+ err:
+-      if (sc->ghl_urb)
+-              usb_free_urb(sc->ghl_urb);
++      usb_free_urb(sc->ghl_urb);
+       hid_hw_stop(hdev);
+       return ret;
+-- 
+2.40.1
+
diff --git a/queue-6.1/ibmveth-remove-condition-to-recompute-tcp-header-che.patch b/queue-6.1/ibmveth-remove-condition-to-recompute-tcp-header-che.patch
new file mode 100644 (file)
index 0000000..691de5b
--- /dev/null
@@ -0,0 +1,72 @@
+From c4d95420b88c01f53401bf0aff886d5202006949 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Sep 2023 16:42:51 -0500
+Subject: ibmveth: Remove condition to recompute TCP header checksum.
+
+From: David Wilder <dwilder@us.ibm.com>
+
+[ Upstream commit 51e7a66666e0ca9642c59464ef8359f0ac604d41 ]
+
+In some OVS environments the TCP pseudo header checksum may need to be
+recomputed. Currently this is only done when the interface instance is
+configured for "Trunk Mode". We found the issue also occurs in some
+Kubernetes environments, these environments do not use "Trunk Mode",
+therefor the condition is removed.
+
+Performance tests with this change show only a fractional decrease in
+throughput (< 0.2%).
+
+Fixes: 7525de2516fb ("ibmveth: Set CHECKSUM_PARTIAL if NULL TCP CSUM.")
+Signed-off-by: David Wilder <dwilder@us.ibm.com>
+Reviewed-by: Nick Child <nnac123@linux.ibm.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmveth.c | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
+index 0b4ec6e41eb41..1d21a281222d9 100644
+--- a/drivers/net/ethernet/ibm/ibmveth.c
++++ b/drivers/net/ethernet/ibm/ibmveth.c
+@@ -1308,24 +1308,23 @@ static void ibmveth_rx_csum_helper(struct sk_buff *skb,
+        * the user space for finding a flow. During this process, OVS computes
+        * checksum on the first packet when CHECKSUM_PARTIAL flag is set.
+        *
+-       * So, re-compute TCP pseudo header checksum when configured for
+-       * trunk mode.
++       * So, re-compute TCP pseudo header checksum.
+        */
++
+       if (iph_proto == IPPROTO_TCP) {
+               struct tcphdr *tcph = (struct tcphdr *)(skb->data + iphlen);
++
+               if (tcph->check == 0x0000) {
+                       /* Recompute TCP pseudo header checksum  */
+-                      if (adapter->is_active_trunk) {
+-                              tcphdrlen = skb->len - iphlen;
+-                              if (skb_proto == ETH_P_IP)
+-                                      tcph->check =
+-                                       ~csum_tcpudp_magic(iph->saddr,
+-                                      iph->daddr, tcphdrlen, iph_proto, 0);
+-                              else if (skb_proto == ETH_P_IPV6)
+-                                      tcph->check =
+-                                       ~csum_ipv6_magic(&iph6->saddr,
+-                                      &iph6->daddr, tcphdrlen, iph_proto, 0);
+-                      }
++                      tcphdrlen = skb->len - iphlen;
++                      if (skb_proto == ETH_P_IP)
++                              tcph->check =
++                               ~csum_tcpudp_magic(iph->saddr,
++                              iph->daddr, tcphdrlen, iph_proto, 0);
++                      else if (skb_proto == ETH_P_IPV6)
++                              tcph->check =
++                               ~csum_ipv6_magic(&iph6->saddr,
++                              &iph6->daddr, tcphdrlen, iph_proto, 0);
+                       /* Setup SKB fields for checksum offload */
+                       skb_partial_csum_set(skb, iphlen,
+                                            offsetof(struct tcphdr, check));
+-- 
+2.40.1
+
diff --git a/queue-6.1/ima-finish-deprecation-of-ima_trusted_keyring-kconfi.patch b/queue-6.1/ima-finish-deprecation-of-ima_trusted_keyring-kconfi.patch
new file mode 100644 (file)
index 0000000..d9e3f4b
--- /dev/null
@@ -0,0 +1,50 @@
+From 722f609c6bb2979d2d72ff5989b292ea732b53db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Sep 2023 06:45:05 +0000
+Subject: ima: Finish deprecation of IMA_TRUSTED_KEYRING Kconfig
+
+From: Oleksandr Tymoshenko <ovt@google.com>
+
+[ Upstream commit be210c6d3597faf330cb9af33b9f1591d7b2a983 ]
+
+The removal of IMA_TRUSTED_KEYRING made IMA_LOAD_X509
+and IMA_BLACKLIST_KEYRING unavailable because the latter
+two depend on the former. Since IMA_TRUSTED_KEYRING was
+deprecated in favor of INTEGRITY_TRUSTED_KEYRING use it
+as a dependency for the two Kconfigs affected by the
+deprecation.
+
+Fixes: 5087fd9e80e5 ("ima: Remove deprecated IMA_TRUSTED_KEYRING Kconfig")
+Signed-off-by: Oleksandr Tymoshenko <ovt@google.com>
+Reviewed-by: Nayna Jain <nayna@linux.ibm.com>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/ima/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
+index c17660bf5f347..e6df7c930397c 100644
+--- a/security/integrity/ima/Kconfig
++++ b/security/integrity/ima/Kconfig
+@@ -268,7 +268,7 @@ config IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
+ config IMA_BLACKLIST_KEYRING
+       bool "Create IMA machine owner blacklist keyrings (EXPERIMENTAL)"
+       depends on SYSTEM_TRUSTED_KEYRING
+-      depends on IMA_TRUSTED_KEYRING
++      depends on INTEGRITY_TRUSTED_KEYRING
+       default n
+       help
+          This option creates an IMA blacklist keyring, which contains all
+@@ -278,7 +278,7 @@ config IMA_BLACKLIST_KEYRING
+ config IMA_LOAD_X509
+       bool "Load X509 certificate onto the '.ima' trusted keyring"
+-      depends on IMA_TRUSTED_KEYRING
++      depends on INTEGRITY_TRUSTED_KEYRING
+       default n
+       help
+          File signature verification is based on the public keys
+-- 
+2.40.1
+
diff --git a/queue-6.1/ima-rework-config_ima-dependency-block.patch b/queue-6.1/ima-rework-config_ima-dependency-block.patch
new file mode 100644 (file)
index 0000000..5c6eca3
--- /dev/null
@@ -0,0 +1,141 @@
+From 5067c4014110158d000fca1136d787d4b315daf7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Sep 2023 09:22:14 +0200
+Subject: ima: rework CONFIG_IMA dependency block
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 91e326563ee34509c35267808a4b1b3ea3db62a8 ]
+
+Changing the direct dependencies of IMA_BLACKLIST_KEYRING and
+IMA_LOAD_X509 caused them to no longer depend on IMA, but a
+a configuration without IMA results in link failures:
+
+arm-linux-gnueabi-ld: security/integrity/iint.o: in function `integrity_load_keys':
+iint.c:(.init.text+0xd8): undefined reference to `ima_load_x509'
+
+aarch64-linux-ld: security/integrity/digsig_asymmetric.o: in function `asymmetric_verify':
+digsig_asymmetric.c:(.text+0x104): undefined reference to `ima_blacklist_keyring'
+
+Adding explicit dependencies on IMA would fix this, but a more reliable
+way to do this is to enclose the entire Kconfig file in an 'if IMA' block.
+This also allows removing the existing direct dependencies.
+
+Fixes: be210c6d3597f ("ima: Finish deprecation of IMA_TRUSTED_KEYRING Kconfig")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/ima/Kconfig | 18 ++++++------------
+ 1 file changed, 6 insertions(+), 12 deletions(-)
+
+diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
+index e6df7c930397c..6ef7bde551263 100644
+--- a/security/integrity/ima/Kconfig
++++ b/security/integrity/ima/Kconfig
+@@ -29,9 +29,11 @@ config IMA
+         to learn more about IMA.
+         If unsure, say N.
++if IMA
++
+ config IMA_KEXEC
+       bool "Enable carrying the IMA measurement list across a soft boot"
+-      depends on IMA && TCG_TPM && HAVE_IMA_KEXEC
++      depends on TCG_TPM && HAVE_IMA_KEXEC
+       default n
+       help
+          TPM PCRs are only reset on a hard reboot.  In order to validate
+@@ -43,7 +45,6 @@ config IMA_KEXEC
+ config IMA_MEASURE_PCR_IDX
+       int
+-      depends on IMA
+       range 8 14
+       default 10
+       help
+@@ -53,7 +54,7 @@ config IMA_MEASURE_PCR_IDX
+ config IMA_LSM_RULES
+       bool
+-      depends on IMA && AUDIT && (SECURITY_SELINUX || SECURITY_SMACK || SECURITY_APPARMOR)
++      depends on AUDIT && (SECURITY_SELINUX || SECURITY_SMACK || SECURITY_APPARMOR)
+       default y
+       help
+         Disabling this option will disregard LSM based policy rules.
+@@ -61,7 +62,6 @@ config IMA_LSM_RULES
+ choice
+       prompt "Default template"
+       default IMA_NG_TEMPLATE
+-      depends on IMA
+       help
+         Select the default IMA measurement template.
+@@ -80,14 +80,12 @@ endchoice
+ config IMA_DEFAULT_TEMPLATE
+       string
+-      depends on IMA
+       default "ima-ng" if IMA_NG_TEMPLATE
+       default "ima-sig" if IMA_SIG_TEMPLATE
+ choice
+       prompt "Default integrity hash algorithm"
+       default IMA_DEFAULT_HASH_SHA1
+-      depends on IMA
+       help
+          Select the default hash algorithm used for the measurement
+          list, integrity appraisal and audit log.  The compiled default
+@@ -117,7 +115,6 @@ endchoice
+ config IMA_DEFAULT_HASH
+       string
+-      depends on IMA
+       default "sha1" if IMA_DEFAULT_HASH_SHA1
+       default "sha256" if IMA_DEFAULT_HASH_SHA256
+       default "sha512" if IMA_DEFAULT_HASH_SHA512
+@@ -126,7 +123,6 @@ config IMA_DEFAULT_HASH
+ config IMA_WRITE_POLICY
+       bool "Enable multiple writes to the IMA policy"
+-      depends on IMA
+       default n
+       help
+         IMA policy can now be updated multiple times.  The new rules get
+@@ -137,7 +133,6 @@ config IMA_WRITE_POLICY
+ config IMA_READ_POLICY
+       bool "Enable reading back the current IMA policy"
+-      depends on IMA
+       default y if IMA_WRITE_POLICY
+       default n if !IMA_WRITE_POLICY
+       help
+@@ -147,7 +142,6 @@ config IMA_READ_POLICY
+ config IMA_APPRAISE
+       bool "Appraise integrity measurements"
+-      depends on IMA
+       default n
+       help
+         This option enables local measurement integrity appraisal.
+@@ -303,7 +297,6 @@ config IMA_APPRAISE_SIGNED_INIT
+ config IMA_MEASURE_ASYMMETRIC_KEYS
+       bool
+-      depends on IMA
+       depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
+       default y
+@@ -322,7 +315,8 @@ config IMA_SECURE_AND_OR_TRUSTED_BOOT
+ config IMA_DISABLE_HTABLE
+       bool "Disable htable to allow measurement of duplicate records"
+-      depends on IMA
+       default n
+       help
+          This option disables htable to allow measurement of duplicate records.
++
++endif
+-- 
+2.40.1
+
diff --git a/queue-6.1/intel_idle-add-emerald-rapids-xeon-support.patch b/queue-6.1/intel_idle-add-emerald-rapids-xeon-support.patch
new file mode 100644 (file)
index 0000000..e6d02cb
--- /dev/null
@@ -0,0 +1,46 @@
+From 9988912f1984ebdcd99fd84d5698646676997cd8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Jan 2023 11:15:28 +0200
+Subject: intel_idle: add Emerald Rapids Xeon support
+
+From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
+
+[ Upstream commit 74528edfbc664f9d2c927c4e5a44f1285598ed0f ]
+
+Emerald Rapids (EMR) is the next Intel Xeon processor after Sapphire
+Rapids (SPR).
+
+EMR C-states are the same as SPR C-states, and we expect that EMR
+C-state characteristics (latency and target residency) will be the
+same as in SPR. Therefore, add EMR support by using SPR C-states table.
+
+Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/idle/intel_idle.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
+index cfeb24d40d378..bb3d10099ba44 100644
+--- a/drivers/idle/intel_idle.c
++++ b/drivers/idle/intel_idle.c
+@@ -1430,6 +1430,7 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = {
+       X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L,         &idle_cpu_adl_l),
+       X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N,         &idle_cpu_adl_n),
+       X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X,    &idle_cpu_spr),
++      X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X,     &idle_cpu_spr),
+       X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL,        &idle_cpu_knl),
+       X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM,        &idle_cpu_knl),
+       X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT,       &idle_cpu_bxt),
+@@ -1862,6 +1863,7 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
+               skx_idle_state_table_update();
+               break;
+       case INTEL_FAM6_SAPPHIRERAPIDS_X:
++      case INTEL_FAM6_EMERALDRAPIDS_X:
+               spr_idle_state_table_update();
+               break;
+       case INTEL_FAM6_ALDERLAKE:
+-- 
+2.40.1
+
diff --git a/queue-6.1/iommu-mediatek-fix-share-pgtable-for-iova-over-4gb.patch b/queue-6.1/iommu-mediatek-fix-share-pgtable-for-iova-over-4gb.patch
new file mode 100644 (file)
index 0000000..65066fd
--- /dev/null
@@ -0,0 +1,68 @@
+From bc1c0e89f08390f49c92cb6f0ed9c6e9efb22bc1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Aug 2023 16:14:43 +0800
+Subject: iommu/mediatek: Fix share pgtable for iova over 4GB
+
+From: Yong Wu <yong.wu@mediatek.com>
+
+[ Upstream commit b07eba71a512eb196cbcc29765c29c8c29b11b59 ]
+
+In mt8192/mt8186, there is only one MM IOMMU that supports 16GB iova
+space, which is shared by display, vcodec and camera. These two SoC use
+one pgtable and have not the flag SHARE_PGTABLE, we should also keep
+share pgtable for this case.
+
+In mtk_iommu_domain_finalise, MM IOMMU always share pgtable, thus remove
+the flag SHARE_PGTABLE checking. Infra IOMMU always uses independent
+pgtable.
+
+Fixes: cf69ef46dbd9 ("iommu/mediatek: Fix two IOMMU share pagetable issue")
+Reported-by: Laura Nao <laura.nao@collabora.com>
+Closes: https://lore.kernel.org/linux-iommu/20230818154156.314742-1-laura.nao@collabora.com/
+Signed-off-by: Yong Wu <yong.wu@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: Laura Nao <laura.nao@collabora.com>
+Link: https://lore.kernel.org/r/20230819081443.8333-1-yong.wu@mediatek.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/mtk_iommu.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
+index 9673cd60c84fc..0ba2a63a9538a 100644
+--- a/drivers/iommu/mtk_iommu.c
++++ b/drivers/iommu/mtk_iommu.c
+@@ -223,7 +223,7 @@ struct mtk_iommu_data {
+       struct device                   *smicomm_dev;
+       struct mtk_iommu_bank_data      *bank;
+-      struct mtk_iommu_domain         *share_dom; /* For 2 HWs share pgtable */
++      struct mtk_iommu_domain         *share_dom;
+       struct regmap                   *pericfg;
+       struct mutex                    mutex; /* Protect m4u_group/m4u_dom above */
+@@ -579,8 +579,8 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
+       struct mtk_iommu_domain *share_dom = data->share_dom;
+       const struct mtk_iommu_iova_region *region;
+-      /* Always use share domain in sharing pgtable case */
+-      if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE) && share_dom) {
++      /* Share pgtable when 2 MM IOMMU share the pgtable or one IOMMU use multiple iova ranges */
++      if (share_dom) {
+               dom->iop = share_dom->iop;
+               dom->cfg = share_dom->cfg;
+               dom->domain.pgsize_bitmap = share_dom->cfg.pgsize_bitmap;
+@@ -613,8 +613,7 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
+       /* Update our support page sizes bitmap */
+       dom->domain.pgsize_bitmap = dom->cfg.pgsize_bitmap;
+-      if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE))
+-              data->share_dom = dom;
++      data->share_dom = dom;
+ update_iova_region:
+       /* Update the iova region for this domain */
+-- 
+2.40.1
+
diff --git a/queue-6.1/ipv4-ipv6-fix-handling-of-transhdrlen-in-__ip-6-_app.patch b/queue-6.1/ipv4-ipv6-fix-handling-of-transhdrlen-in-__ip-6-_app.patch
new file mode 100644 (file)
index 0000000..211d32e
--- /dev/null
@@ -0,0 +1,81 @@
+From 566c500f4fdfcee7d255a1aa828a1b259b4ccb35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Sep 2023 11:41:19 +0100
+Subject: ipv4, ipv6: Fix handling of transhdrlen in __ip{,6}_append_data()
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 9d4c75800f61e5d75c1659ba201b6c0c7ead3070 ]
+
+Including the transhdrlen in length is a problem when the packet is
+partially filled (e.g. something like send(MSG_MORE) happened previously)
+when appending to an IPv4 or IPv6 packet as we don't want to repeat the
+transport header or account for it twice.  This can happen under some
+circumstances, such as splicing into an L2TP socket.
+
+The symptom observed is a warning in __ip6_append_data():
+
+    WARNING: CPU: 1 PID: 5042 at net/ipv6/ip6_output.c:1800 __ip6_append_data.isra.0+0x1be8/0x47f0 net/ipv6/ip6_output.c:1800
+
+that occurs when MSG_SPLICE_PAGES is used to append more data to an already
+partially occupied skbuff.  The warning occurs when 'copy' is larger than
+the amount of data in the message iterator.  This is because the requested
+length includes the transport header length when it shouldn't.  This can be
+triggered by, for example:
+
+        sfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_L2TP);
+        bind(sfd, ...); // ::1
+        connect(sfd, ...); // ::1 port 7
+        send(sfd, buffer, 4100, MSG_MORE);
+        sendfile(sfd, dfd, NULL, 1024);
+
+Fix this by only adding transhdrlen into the length if the write queue is
+empty in l2tp_ip6_sendmsg(), analogously to how UDP does things.
+
+l2tp_ip_sendmsg() looks like it won't suffer from this problem as it builds
+the UDP packet itself.
+
+Fixes: a32e0eec7042 ("l2tp: introduce L2TPv3 IP encapsulation support for IPv6")
+Reported-by: syzbot+62cbf263225ae13ff153@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/r/0000000000001c12b30605378ce8@google.com/
+Suggested-by: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Eric Dumazet <edumazet@google.com>
+cc: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+cc: "David S. Miller" <davem@davemloft.net>
+cc: David Ahern <dsahern@kernel.org>
+cc: Paolo Abeni <pabeni@redhat.com>
+cc: Jakub Kicinski <kuba@kernel.org>
+cc: netdev@vger.kernel.org
+cc: bpf@vger.kernel.org
+cc: syzkaller-bugs@googlegroups.com
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/l2tp/l2tp_ip6.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
+index bce4132b0a5c8..314ec3a51e8de 100644
+--- a/net/l2tp/l2tp_ip6.c
++++ b/net/l2tp/l2tp_ip6.c
+@@ -510,7 +510,6 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+        */
+       if (len > INT_MAX - transhdrlen)
+               return -EMSGSIZE;
+-      ulen = len + transhdrlen;
+       /* Mirror BSD error message compatibility */
+       if (msg->msg_flags & MSG_OOB)
+@@ -631,6 +630,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+ back_from_confirm:
+       lock_sock(sk);
++      ulen = len + skb_queue_empty(&sk->sk_write_queue) ? transhdrlen : 0;
+       err = ip6_append_data(sk, ip_generic_getfrag, msg,
+                             ulen, transhdrlen, &ipc6,
+                             &fl6, (struct rt6_info *)dst,
+-- 
+2.40.1
+
diff --git a/queue-6.1/ipv4-set-offload_failed-flag-in-fibmatch-results.patch b/queue-6.1/ipv4-set-offload_failed-flag-in-fibmatch-results.patch
new file mode 100644 (file)
index 0000000..f3e0b60
--- /dev/null
@@ -0,0 +1,57 @@
+From acbbbc65745fb8b07cf5941dd1dddaacfb89fae2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Sep 2023 14:27:30 -0400
+Subject: ipv4: Set offload_failed flag in fibmatch results
+
+From: Benjamin Poirier <bpoirier@nvidia.com>
+
+[ Upstream commit 0add5c597f3253a9c6108a0a81d57f44ab0d9d30 ]
+
+Due to a small omission, the offload_failed flag is missing from ipv4
+fibmatch results. Make sure it is set correctly.
+
+The issue can be witnessed using the following commands:
+echo "1 1" > /sys/bus/netdevsim/new_device
+ip link add dummy1 up type dummy
+ip route add 192.0.2.0/24 dev dummy1
+echo 1 > /sys/kernel/debug/netdevsim/netdevsim1/fib/fail_route_offload
+ip route add 198.51.100.0/24 dev dummy1
+ip route
+       # 192.168.15.0/24 has rt_trap
+       # 198.51.100.0/24 has rt_offload_failed
+ip route get 192.168.15.1 fibmatch
+       # Result has rt_trap
+ip route get 198.51.100.1 fibmatch
+       # Result differs from the route shown by `ip route`, it is missing
+       # rt_offload_failed
+ip link del dev dummy1
+echo 1 > /sys/bus/netdevsim/del_device
+
+Fixes: 36c5100e859d ("IPv4: Add "offload failed" indication to routes")
+Signed-off-by: Benjamin Poirier <bpoirier@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://lore.kernel.org/r/20230926182730.231208-1-bpoirier@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 608bd9f8dbc86..9cbaae4f5ee71 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -3421,6 +3421,8 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
+                                   fa->fa_type == fri.type) {
+                                       fri.offload = READ_ONCE(fa->offload);
+                                       fri.trap = READ_ONCE(fa->trap);
++                                      fri.offload_failed =
++                                              READ_ONCE(fa->offload_failed);
+                                       break;
+                               }
+                       }
+-- 
+2.40.1
+
diff --git a/queue-6.1/ipv6-tcp-add-a-missing-nf_reset_ct-in-3whs-handling.patch b/queue-6.1/ipv6-tcp-add-a-missing-nf_reset_ct-in-3whs-handling.patch
new file mode 100644 (file)
index 0000000..c926899
--- /dev/null
@@ -0,0 +1,72 @@
+From dad19c72b1950c4722746ef9caa4f1839d60a46a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Sep 2023 23:04:58 +0200
+Subject: ipv6: tcp: add a missing nf_reset_ct() in 3WHS handling
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 9593c7cb6cf670ef724d17f7f9affd7a8d2ad0c5 ]
+
+Commit b0e214d21203 ("netfilter: keep conntrack reference until
+IPsecv6 policy checks are done") is a direct copy of the old
+commit b59c270104f0 ("[NETFILTER]: Keep conntrack reference until
+IPsec policy checks are done") but for IPv6.  However, it also
+copies a bug that this old commit had.  That is: when the third
+packet of 3WHS connection establishment contains payload, it is
+added into socket receive queue without the XFRM check and the
+drop of connection tracking context.
+
+That leads to nf_conntrack module being impossible to unload as
+it waits for all the conntrack references to be dropped while
+the packet release is deferred in per-cpu cache indefinitely, if
+not consumed by the application.
+
+The issue for IPv4 was fixed in commit 6f0012e35160 ("tcp: add a
+missing nf_reset_ct() in 3WHS handling") by adding a missing XFRM
+check and correctly dropping the conntrack context.  However, the
+issue was introduced to IPv6 code afterwards.  Fixing it the
+same way for IPv6 now.
+
+Fixes: b0e214d21203 ("netfilter: keep conntrack reference until IPsecv6 policy checks are done")
+Link: https://lore.kernel.org/netdev/d589a999-d4dd-2768-b2d5-89dec64a4a42@ovn.org/
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Florian Westphal <fw@strlen.de>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://lore.kernel.org/r/20230922210530.2045146-1-i.maximets@ovn.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/tcp_ipv6.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index 4bdd356bb5c46..7be89dcfd5fc5 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1644,9 +1644,12 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
+               struct sock *nsk;
+               sk = req->rsk_listener;
+-              drop_reason = tcp_inbound_md5_hash(sk, skb,
+-                                                 &hdr->saddr, &hdr->daddr,
+-                                                 AF_INET6, dif, sdif);
++              if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
++                      drop_reason = SKB_DROP_REASON_XFRM_POLICY;
++              else
++                      drop_reason = tcp_inbound_md5_hash(sk, skb,
++                                                         &hdr->saddr, &hdr->daddr,
++                                                         AF_INET6, dif, sdif);
+               if (drop_reason) {
+                       sk_drops_add(sk, skb);
+                       reqsk_put(req);
+@@ -1693,6 +1696,7 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
+                       }
+                       goto discard_and_relse;
+               }
++              nf_reset_ct(skb);
+               if (nsk == sk) {
+                       reqsk_put(req);
+                       tcp_v6_restore_cb(skb);
+-- 
+2.40.1
+
diff --git a/queue-6.1/leds-drop-bug_on-check-for-led_color_id_multi.patch b/queue-6.1/leds-drop-bug_on-check-for-led_color_id_multi.patch
new file mode 100644 (file)
index 0000000..87ac213
--- /dev/null
@@ -0,0 +1,48 @@
+From 5658e27c09c00fd48d029915eb2634f87270656c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Sep 2023 16:07:24 +0200
+Subject: leds: Drop BUG_ON check for LED_COLOR_ID_MULTI
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <kabel@kernel.org>
+
+[ Upstream commit 9dc1664fab2246bc2c3e9bf2cf21518a857f9b5b ]
+
+Commit c3f853184bed ("leds: Fix BUG_ON check for LED_COLOR_ID_MULTI that
+is always false") fixed a no-op BUG_ON. This turned out to cause a
+regression, since some in-tree device-tree files already use
+LED_COLOR_ID_MULTI.
+
+Drop the BUG_ON altogether.
+
+Fixes: c3f853184bed ("leds: Fix BUG_ON check for LED_COLOR_ID_MULTI that is always false")
+Reported-by: Da Xue <da@libre.computer>
+Closes: https://lore.kernel.org/linux-leds/ZQLelWcNjjp2xndY@duo.ucw.cz/T/
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Link: https://lore.kernel.org/r/20230918140724.18634-1-kabel@kernel.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/led-core.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
+index aad8bc44459fe..d94d60b526461 100644
+--- a/drivers/leds/led-core.c
++++ b/drivers/leds/led-core.c
+@@ -424,10 +424,6 @@ int led_compose_name(struct device *dev, struct led_init_data *init_data,
+       led_parse_fwnode_props(dev, fwnode, &props);
+-      /* We want to label LEDs that can produce full range of colors
+-       * as RGB, not multicolor */
+-      BUG_ON(props.color == LED_COLOR_ID_MULTI);
+-
+       if (props.label) {
+               /*
+                * If init_data.devicename is NULL, then it indicates that
+-- 
+2.40.1
+
diff --git a/queue-6.1/modpost-add-missing-else-to-the-of-check.patch b/queue-6.1/modpost-add-missing-else-to-the-of-check.patch
new file mode 100644 (file)
index 0000000..ab38933
--- /dev/null
@@ -0,0 +1,54 @@
+From b8bc83d86fa3d8c377b8a8d4e7634b3a00ab1597 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Sep 2023 17:28:07 -0300
+Subject: modpost: add missing else to the "of" check
+
+From: Mauricio Faria de Oliveira <mfo@canonical.com>
+
+[ Upstream commit cbc3d00cf88fda95dbcafee3b38655b7a8f2650a ]
+
+Without this 'else' statement, an "usb" name goes into two handlers:
+the first/previous 'if' statement _AND_ the for-loop over 'devtable',
+but the latter is useless as it has no 'usb' device_id entry anyway.
+
+Tested with allmodconfig before/after patch; no changes to *.mod.c:
+
+    git checkout v6.6-rc3
+    make -j$(nproc) allmodconfig
+    make -j$(nproc) olddefconfig
+
+    make -j$(nproc)
+    find . -name '*.mod.c' | cpio -pd /tmp/before
+
+    # apply patch
+
+    make -j$(nproc)
+    find . -name '*.mod.c' | cpio -pd /tmp/after
+
+    diff -r /tmp/before/ /tmp/after/
+    # no difference
+
+Fixes: acbef7b76629 ("modpost: fix module autoloading for OF devices with generic compatible property")
+Signed-off-by: Mauricio Faria de Oliveira <mfo@canonical.com>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/mod/file2alias.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
+index 80d973144fded..111d5464c12df 100644
+--- a/scripts/mod/file2alias.c
++++ b/scripts/mod/file2alias.c
+@@ -1577,7 +1577,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
+       /* First handle the "special" cases */
+       if (sym_is(name, namelen, "usb"))
+               do_usb_table(symval, sym->st_size, mod);
+-      if (sym_is(name, namelen, "of"))
++      else if (sym_is(name, namelen, "of"))
+               do_of_table(symval, sym->st_size, mod);
+       else if (sym_is(name, namelen, "pnp"))
+               do_pnp_device_entry(symval, sym->st_size, mod);
+-- 
+2.40.1
+
diff --git a/queue-6.1/neighbour-annotate-lockless-accesses-to-n-nud_state.patch b/queue-6.1/neighbour-annotate-lockless-accesses-to-n-nud_state.patch
new file mode 100644 (file)
index 0000000..ccb110c
--- /dev/null
@@ -0,0 +1,401 @@
+From 9b8875d07b819aa8de6894937031ef5d369ab45c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Mar 2023 20:17:31 +0000
+Subject: neighbour: annotate lockless accesses to n->nud_state
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b071af523579df7341cabf0f16fc661125e9a13f ]
+
+We have many lockless accesses to n->nud_state.
+
+Before adding another one in the following patch,
+add annotations to readers and writers.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Reviewed-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 5baa0433a15e ("neighbour: fix data-races around n->output")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vxlan/vxlan_core.c  |  4 ++--
+ include/net/neighbour.h         |  2 +-
+ net/bridge/br_arp_nd_proxy.c    |  4 ++--
+ net/bridge/br_netfilter_hooks.c |  3 ++-
+ net/core/filter.c               |  4 ++--
+ net/core/neighbour.c            | 28 ++++++++++++++--------------
+ net/ipv4/arp.c                  |  8 ++++----
+ net/ipv4/fib_semantics.c        |  4 ++--
+ net/ipv4/nexthop.c              |  4 ++--
+ net/ipv4/route.c                |  2 +-
+ net/ipv6/ip6_output.c           |  2 +-
+ net/ipv6/ndisc.c                |  4 ++--
+ net/ipv6/route.c                |  2 +-
+ 13 files changed, 36 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
+index 0c3eb850fcb79..619dd71c9d75e 100644
+--- a/drivers/net/vxlan/vxlan_core.c
++++ b/drivers/net/vxlan/vxlan_core.c
+@@ -1910,7 +1910,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
+               struct vxlan_fdb *f;
+               struct sk_buff  *reply;
+-              if (!(n->nud_state & NUD_CONNECTED)) {
++              if (!(READ_ONCE(n->nud_state) & NUD_CONNECTED)) {
+                       neigh_release(n);
+                       goto out;
+               }
+@@ -2074,7 +2074,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
+               struct vxlan_fdb *f;
+               struct sk_buff *reply;
+-              if (!(n->nud_state & NUD_CONNECTED)) {
++              if (!(READ_ONCE(n->nud_state) & NUD_CONNECTED)) {
+                       neigh_release(n);
+                       goto out;
+               }
+diff --git a/include/net/neighbour.h b/include/net/neighbour.h
+index 794e45981891a..cd30aac9ec835 100644
+--- a/include/net/neighbour.h
++++ b/include/net/neighbour.h
+@@ -464,7 +464,7 @@ static __always_inline int neigh_event_send_probe(struct neighbour *neigh,
+       if (READ_ONCE(neigh->used) != now)
+               WRITE_ONCE(neigh->used, now);
+-      if (!(neigh->nud_state & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE)))
++      if (!(READ_ONCE(neigh->nud_state) & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE)))
+               return __neigh_event_send(neigh, skb, immediate_ok);
+       return 0;
+ }
+diff --git a/net/bridge/br_arp_nd_proxy.c b/net/bridge/br_arp_nd_proxy.c
+index e5e48c6e35d78..b45c00c01dea1 100644
+--- a/net/bridge/br_arp_nd_proxy.c
++++ b/net/bridge/br_arp_nd_proxy.c
+@@ -192,7 +192,7 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
+       if (n) {
+               struct net_bridge_fdb_entry *f;
+-              if (!(n->nud_state & NUD_VALID)) {
++              if (!(READ_ONCE(n->nud_state) & NUD_VALID)) {
+                       neigh_release(n);
+                       return;
+               }
+@@ -452,7 +452,7 @@ void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br,
+       if (n) {
+               struct net_bridge_fdb_entry *f;
+-              if (!(n->nud_state & NUD_VALID)) {
++              if (!(READ_ONCE(n->nud_state) & NUD_VALID)) {
+                       neigh_release(n);
+                       return;
+               }
+diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
+index 812bd7e1750b6..442198cb83909 100644
+--- a/net/bridge/br_netfilter_hooks.c
++++ b/net/bridge/br_netfilter_hooks.c
+@@ -277,7 +277,8 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_
+               struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
+               int ret;
+-              if ((neigh->nud_state & NUD_CONNECTED) && neigh->hh.hh_len) {
++              if ((READ_ONCE(neigh->nud_state) & NUD_CONNECTED) &&
++                  READ_ONCE(neigh->hh.hh_len)) {
+                       neigh_hh_bridge(&neigh->hh, skb);
+                       skb->dev = nf_bridge->physindev;
+                       ret = br_handle_frame_finish(net, sk, skb);
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 6ef62d84dcac5..d32c6bd4d579a 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -5802,7 +5802,7 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
+       else
+               neigh = __ipv6_neigh_lookup_noref_stub(dev, params->ipv6_dst);
+-      if (!neigh || !(neigh->nud_state & NUD_VALID))
++      if (!neigh || !(READ_ONCE(neigh->nud_state) & NUD_VALID))
+               return BPF_FIB_LKUP_RET_NO_NEIGH;
+       memcpy(params->dmac, neigh->ha, ETH_ALEN);
+       memcpy(params->smac, dev->dev_addr, ETH_ALEN);
+@@ -5923,7 +5923,7 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
+        * not needed here.
+        */
+       neigh = __ipv6_neigh_lookup_noref_stub(dev, dst);
+-      if (!neigh || !(neigh->nud_state & NUD_VALID))
++      if (!neigh || !(READ_ONCE(neigh->nud_state) & NUD_VALID))
+               return BPF_FIB_LKUP_RET_NO_NEIGH;
+       memcpy(params->dmac, neigh->ha, ETH_ALEN);
+       memcpy(params->smac, dev->dev_addr, ETH_ALEN);
+diff --git a/net/core/neighbour.c b/net/core/neighbour.c
+index 8e726eb0548f6..51393079487ae 100644
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -1095,13 +1095,13 @@ static void neigh_timer_handler(struct timer_list *t)
+                                         neigh->used +
+                                         NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME))) {
+                       neigh_dbg(2, "neigh %p is delayed\n", neigh);
+-                      neigh->nud_state = NUD_DELAY;
++                      WRITE_ONCE(neigh->nud_state, NUD_DELAY);
+                       neigh->updated = jiffies;
+                       neigh_suspect(neigh);
+                       next = now + NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME);
+               } else {
+                       neigh_dbg(2, "neigh %p is suspected\n", neigh);
+-                      neigh->nud_state = NUD_STALE;
++                      WRITE_ONCE(neigh->nud_state, NUD_STALE);
+                       neigh->updated = jiffies;
+                       neigh_suspect(neigh);
+                       notify = 1;
+@@ -1111,14 +1111,14 @@ static void neigh_timer_handler(struct timer_list *t)
+                                  neigh->confirmed +
+                                  NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME))) {
+                       neigh_dbg(2, "neigh %p is now reachable\n", neigh);
+-                      neigh->nud_state = NUD_REACHABLE;
++                      WRITE_ONCE(neigh->nud_state, NUD_REACHABLE);
+                       neigh->updated = jiffies;
+                       neigh_connect(neigh);
+                       notify = 1;
+                       next = neigh->confirmed + neigh->parms->reachable_time;
+               } else {
+                       neigh_dbg(2, "neigh %p is probed\n", neigh);
+-                      neigh->nud_state = NUD_PROBE;
++                      WRITE_ONCE(neigh->nud_state, NUD_PROBE);
+                       neigh->updated = jiffies;
+                       atomic_set(&neigh->probes, 0);
+                       notify = 1;
+@@ -1132,7 +1132,7 @@ static void neigh_timer_handler(struct timer_list *t)
+       if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) &&
+           atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) {
+-              neigh->nud_state = NUD_FAILED;
++              WRITE_ONCE(neigh->nud_state, NUD_FAILED);
+               notify = 1;
+               neigh_invalidate(neigh);
+               goto out;
+@@ -1181,7 +1181,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb,
+                       atomic_set(&neigh->probes,
+                                  NEIGH_VAR(neigh->parms, UCAST_PROBES));
+                       neigh_del_timer(neigh);
+-                      neigh->nud_state = NUD_INCOMPLETE;
++                      WRITE_ONCE(neigh->nud_state, NUD_INCOMPLETE);
+                       neigh->updated = now;
+                       if (!immediate_ok) {
+                               next = now + 1;
+@@ -1193,7 +1193,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb,
+                       }
+                       neigh_add_timer(neigh, next);
+               } else {
+-                      neigh->nud_state = NUD_FAILED;
++                      WRITE_ONCE(neigh->nud_state, NUD_FAILED);
+                       neigh->updated = jiffies;
+                       write_unlock_bh(&neigh->lock);
+@@ -1203,7 +1203,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb,
+       } else if (neigh->nud_state & NUD_STALE) {
+               neigh_dbg(2, "neigh %p is delayed\n", neigh);
+               neigh_del_timer(neigh);
+-              neigh->nud_state = NUD_DELAY;
++              WRITE_ONCE(neigh->nud_state, NUD_DELAY);
+               neigh->updated = jiffies;
+               neigh_add_timer(neigh, jiffies +
+                               NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME));
+@@ -1315,7 +1315,7 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr,
+       neigh_update_flags(neigh, flags, &notify, &gc_update, &managed_update);
+       if (flags & (NEIGH_UPDATE_F_USE | NEIGH_UPDATE_F_MANAGED)) {
+               new = old & ~NUD_PERMANENT;
+-              neigh->nud_state = new;
++              WRITE_ONCE(neigh->nud_state, new);
+               err = 0;
+               goto out;
+       }
+@@ -1324,7 +1324,7 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr,
+               neigh_del_timer(neigh);
+               if (old & NUD_CONNECTED)
+                       neigh_suspect(neigh);
+-              neigh->nud_state = new;
++              WRITE_ONCE(neigh->nud_state, new);
+               err = 0;
+               notify = old & NUD_VALID;
+               if ((old & (NUD_INCOMPLETE | NUD_PROBE)) &&
+@@ -1403,7 +1403,7 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr,
+                                               ((new & NUD_REACHABLE) ?
+                                                neigh->parms->reachable_time :
+                                                0)));
+-              neigh->nud_state = new;
++              WRITE_ONCE(neigh->nud_state, new);
+               notify = 1;
+       }
+@@ -1490,7 +1490,7 @@ void __neigh_set_probe_once(struct neighbour *neigh)
+       neigh->updated = jiffies;
+       if (!(neigh->nud_state & NUD_FAILED))
+               return;
+-      neigh->nud_state = NUD_INCOMPLETE;
++      WRITE_ONCE(neigh->nud_state, NUD_INCOMPLETE);
+       atomic_set(&neigh->probes, neigh_max_probes(neigh));
+       neigh_add_timer(neigh,
+                       jiffies + max(NEIGH_VAR(neigh->parms, RETRANS_TIME),
+@@ -3190,7 +3190,7 @@ static struct neighbour *neigh_get_first(struct seq_file *seq)
+                       }
+                       if (!(state->flags & NEIGH_SEQ_SKIP_NOARP))
+                               break;
+-                      if (n->nud_state & ~NUD_NOARP)
++                      if (READ_ONCE(n->nud_state) & ~NUD_NOARP)
+                               break;
+ next:
+                       n = rcu_dereference_bh(n->next);
+@@ -3232,7 +3232,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
+                       if (!(state->flags & NEIGH_SEQ_SKIP_NOARP))
+                               break;
+-                      if (n->nud_state & ~NUD_NOARP)
++                      if (READ_ONCE(n->nud_state) & ~NUD_NOARP)
+                               break;
+ next:
+                       n = rcu_dereference_bh(n->next);
+diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
+index 4f7237661afb9..9456f5bb35e5d 100644
+--- a/net/ipv4/arp.c
++++ b/net/ipv4/arp.c
+@@ -375,7 +375,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
+       probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES);
+       if (probes < 0) {
+-              if (!(neigh->nud_state & NUD_VALID))
++              if (!(READ_ONCE(neigh->nud_state) & NUD_VALID))
+                       pr_debug("trying to ucast probe in NUD_INVALID\n");
+               neigh_ha_snapshot(dst_ha, neigh, dev);
+               dst_hw = dst_ha;
+@@ -1123,7 +1123,7 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
+       neigh = neigh_lookup(&arp_tbl, &ip, dev);
+       if (neigh) {
+-              if (!(neigh->nud_state & NUD_NOARP)) {
++              if (!(READ_ONCE(neigh->nud_state) & NUD_NOARP)) {
+                       read_lock_bh(&neigh->lock);
+                       memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len);
+                       r->arp_flags = arp_state_to_flags(neigh);
+@@ -1144,12 +1144,12 @@ int arp_invalidate(struct net_device *dev, __be32 ip, bool force)
+       struct neigh_table *tbl = &arp_tbl;
+       if (neigh) {
+-              if ((neigh->nud_state & NUD_VALID) && !force) {
++              if ((READ_ONCE(neigh->nud_state) & NUD_VALID) && !force) {
+                       neigh_release(neigh);
+                       return 0;
+               }
+-              if (neigh->nud_state & ~NUD_NOARP)
++              if (READ_ONCE(neigh->nud_state) & ~NUD_NOARP)
+                       err = neigh_update(neigh, NULL, NUD_FAILED,
+                                          NEIGH_UPDATE_F_OVERRIDE|
+                                          NEIGH_UPDATE_F_ADMIN, 0);
+diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
+index 3b6e6bc80dc1c..158ad3c2662f5 100644
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -564,7 +564,7 @@ static int fib_detect_death(struct fib_info *fi, int order,
+               n = NULL;
+       if (n) {
+-              state = n->nud_state;
++              state = READ_ONCE(n->nud_state);
+               neigh_release(n);
+       } else {
+               return 0;
+@@ -2205,7 +2205,7 @@ static bool fib_good_nh(const struct fib_nh *nh)
+               else
+                       n = NULL;
+               if (n)
+-                      state = n->nud_state;
++                      state = READ_ONCE(n->nud_state);
+               rcu_read_unlock_bh();
+       }
+diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
+index 9cc2879024541..d699a41c9d955 100644
+--- a/net/ipv4/nexthop.c
++++ b/net/ipv4/nexthop.c
+@@ -1128,7 +1128,7 @@ static bool ipv6_good_nh(const struct fib6_nh *nh)
+       n = __ipv6_neigh_lookup_noref_stub(nh->fib_nh_dev, &nh->fib_nh_gw6);
+       if (n)
+-              state = n->nud_state;
++              state = READ_ONCE(n->nud_state);
+       rcu_read_unlock_bh();
+@@ -1145,7 +1145,7 @@ static bool ipv4_good_nh(const struct fib_nh *nh)
+       n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev,
+                                     (__force u32)nh->fib_nh_gw4);
+       if (n)
+-              state = n->nud_state;
++              state = READ_ONCE(n->nud_state);
+       rcu_read_unlock_bh();
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 84a0a71a6f4e7..8d838b0046900 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -784,7 +784,7 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow
+       if (!n)
+               n = neigh_create(&arp_tbl, &new_gw, rt->dst.dev);
+       if (!IS_ERR(n)) {
+-              if (!(n->nud_state & NUD_VALID)) {
++              if (!(READ_ONCE(n->nud_state) & NUD_VALID)) {
+                       neigh_event_send(n, NULL);
+               } else {
+                       if (fib_lookup(net, fl4, &res, 0) == 0) {
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index 34192f7a166fb..5bf15a530fe73 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1153,7 +1153,7 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk,
+       rcu_read_lock_bh();
+       n = __ipv6_neigh_lookup_noref(rt->dst.dev,
+                                     rt6_nexthop(rt, &fl6->daddr));
+-      err = n && !(n->nud_state & NUD_VALID) ? -EINVAL : 0;
++      err = n && !(READ_ONCE(n->nud_state) & NUD_VALID) ? -EINVAL : 0;
+       rcu_read_unlock_bh();
+       if (err) {
+diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
+index 6cb2d6a536a84..8c5a99fe68030 100644
+--- a/net/ipv6/ndisc.c
++++ b/net/ipv6/ndisc.c
+@@ -746,7 +746,7 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
+               saddr = &ipv6_hdr(skb)->saddr;
+       probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES);
+       if (probes < 0) {
+-              if (!(neigh->nud_state & NUD_VALID)) {
++              if (!(READ_ONCE(neigh->nud_state) & NUD_VALID)) {
+                       ND_PRINTK(1, dbg,
+                                 "%s: trying to ucast probe in NUD_INVALID: %pI6\n",
+                                 __func__, target);
+@@ -1092,7 +1092,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
+               u8 old_flags = neigh->flags;
+               struct net *net = dev_net(dev);
+-              if (neigh->nud_state & NUD_FAILED)
++              if (READ_ONCE(neigh->nud_state) & NUD_FAILED)
+                       goto out;
+               /*
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 93957b20fccce..4f103e7c4ea25 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -641,7 +641,7 @@ static void rt6_probe(struct fib6_nh *fib6_nh)
+       idev = __in6_dev_get(dev);
+       neigh = __ipv6_neigh_lookup_noref(dev, nh_gw);
+       if (neigh) {
+-              if (neigh->nud_state & NUD_VALID)
++              if (READ_ONCE(neigh->nud_state) & NUD_VALID)
+                       goto out;
+               write_lock(&neigh->lock);
+-- 
+2.40.1
+
diff --git a/queue-6.1/neighbour-fix-data-races-around-n-output.patch b/queue-6.1/neighbour-fix-data-races-around-n-output.patch
new file mode 100644 (file)
index 0000000..7663504
--- /dev/null
@@ -0,0 +1,103 @@
+From 0f65c7bd482f8d2f4e15fd008e92efa287fda59c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Sep 2023 09:27:13 +0000
+Subject: neighbour: fix data-races around n->output
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 5baa0433a15eadd729625004c37463acb982eca7 ]
+
+n->output field can be read locklessly, while a writer
+might change the pointer concurrently.
+
+Add missing annotations to prevent load-store tearing.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/neighbour.h         |  2 +-
+ net/bridge/br_netfilter_hooks.c |  2 +-
+ net/core/neighbour.c            | 10 +++++-----
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/include/net/neighbour.h b/include/net/neighbour.h
+index f6a8ecc6b1fa7..ccc4a0f8b4ad8 100644
+--- a/include/net/neighbour.h
++++ b/include/net/neighbour.h
+@@ -541,7 +541,7 @@ static inline int neigh_output(struct neighbour *n, struct sk_buff *skb,
+           READ_ONCE(hh->hh_len))
+               return neigh_hh_output(hh, skb);
+-      return n->output(n, skb);
++      return READ_ONCE(n->output)(n, skb);
+ }
+ static inline struct neighbour *
+diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
+index 442198cb83909..01d690d9fe5f8 100644
+--- a/net/bridge/br_netfilter_hooks.c
++++ b/net/bridge/br_netfilter_hooks.c
+@@ -294,7 +294,7 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_
+                       /* tell br_dev_xmit to continue with forwarding */
+                       nf_bridge->bridged_dnat = 1;
+                       /* FIXME Need to refragment */
+-                      ret = neigh->output(neigh, skb);
++                      ret = READ_ONCE(neigh->output)(neigh, skb);
+               }
+               neigh_release(neigh);
+               return ret;
+diff --git a/net/core/neighbour.c b/net/core/neighbour.c
+index bafd72e5f5886..b20c9768d9f3f 100644
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -410,7 +410,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev,
+                                */
+                               __skb_queue_purge(&n->arp_queue);
+                               n->arp_queue_len_bytes = 0;
+-                              n->output = neigh_blackhole;
++                              WRITE_ONCE(n->output, neigh_blackhole);
+                               if (n->nud_state & NUD_VALID)
+                                       n->nud_state = NUD_NOARP;
+                               else
+@@ -920,7 +920,7 @@ static void neigh_suspect(struct neighbour *neigh)
+ {
+       neigh_dbg(2, "neigh %p is suspected\n", neigh);
+-      neigh->output = neigh->ops->output;
++      WRITE_ONCE(neigh->output, neigh->ops->output);
+ }
+ /* Neighbour state is OK;
+@@ -932,7 +932,7 @@ static void neigh_connect(struct neighbour *neigh)
+ {
+       neigh_dbg(2, "neigh %p is connected\n", neigh);
+-      neigh->output = neigh->ops->connected_output;
++      WRITE_ONCE(neigh->output, neigh->ops->connected_output);
+ }
+ static void neigh_periodic_work(struct work_struct *work)
+@@ -1449,7 +1449,7 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr,
+                               if (n2)
+                                       n1 = n2;
+                       }
+-                      n1->output(n1, skb);
++                      READ_ONCE(n1->output)(n1, skb);
+                       if (n2)
+                               neigh_release(n2);
+                       rcu_read_unlock();
+@@ -3145,7 +3145,7 @@ int neigh_xmit(int index, struct net_device *dev,
+                       rcu_read_unlock();
+                       goto out_kfree_skb;
+               }
+-              err = neigh->output(neigh, skb);
++              err = READ_ONCE(neigh->output)(neigh, skb);
+               rcu_read_unlock();
+       }
+       else if (index == NEIGH_LINK_TABLE) {
+-- 
+2.40.1
+
diff --git a/queue-6.1/neighbour-switch-to-standard-rcu-instead-of-rcu_bh.patch b/queue-6.1/neighbour-switch-to-standard-rcu-instead-of-rcu_bh.patch
new file mode 100644 (file)
index 0000000..a91d4e8
--- /dev/null
@@ -0,0 +1,690 @@
+From e92681d10e258bce6fb4e49861bbe01973b4791f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Mar 2023 04:01:14 +0000
+Subject: neighbour: switch to standard rcu, instead of rcu_bh
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 09eed1192cec1755967f2af8394207acdde579a1 ]
+
+rcu_bh is no longer a win, especially for objects freed
+with standard call_rcu().
+
+Switch neighbour code to no longer disable BH when not necessary.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 5baa0433a15e ("neighbour: fix data-races around n->output")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/arp.h        |  8 ++---
+ include/net/ndisc.h      | 12 ++++----
+ include/net/neighbour.h  |  6 ++--
+ include/net/nexthop.h    |  6 ++--
+ net/core/filter.c        | 16 ++++++----
+ net/core/neighbour.c     | 64 ++++++++++++++++++++--------------------
+ net/ipv4/fib_semantics.c |  4 +--
+ net/ipv4/ip_output.c     |  6 ++--
+ net/ipv4/nexthop.c       |  8 ++---
+ net/ipv4/route.c         |  4 +--
+ net/ipv6/addrconf.c      | 14 ++++-----
+ net/ipv6/ip6_output.c    | 10 +++----
+ net/ipv6/route.c         | 12 ++++----
+ 13 files changed, 87 insertions(+), 83 deletions(-)
+
+diff --git a/include/net/arp.h b/include/net/arp.h
+index d7ef4ec71dfeb..e8747e0713c79 100644
+--- a/include/net/arp.h
++++ b/include/net/arp.h
+@@ -38,11 +38,11 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32
+ {
+       struct neighbour *n;
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       n = __ipv4_neigh_lookup_noref(dev, key);
+       if (n && !refcount_inc_not_zero(&n->refcnt))
+               n = NULL;
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+       return n;
+ }
+@@ -51,10 +51,10 @@ static inline void __ipv4_confirm_neigh(struct net_device *dev, u32 key)
+ {
+       struct neighbour *n;
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       n = __ipv4_neigh_lookup_noref(dev, key);
+       neigh_confirm(n);
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+ }
+ void arp_init(void);
+diff --git a/include/net/ndisc.h b/include/net/ndisc.h
+index da7eec8669ec4..325a6fb65c896 100644
+--- a/include/net/ndisc.h
++++ b/include/net/ndisc.h
+@@ -395,11 +395,11 @@ static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, cons
+ {
+       struct neighbour *n;
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       n = __ipv6_neigh_lookup_noref(dev, pkey);
+       if (n && !refcount_inc_not_zero(&n->refcnt))
+               n = NULL;
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+       return n;
+ }
+@@ -409,10 +409,10 @@ static inline void __ipv6_confirm_neigh(struct net_device *dev,
+ {
+       struct neighbour *n;
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       n = __ipv6_neigh_lookup_noref(dev, pkey);
+       neigh_confirm(n);
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+ }
+ static inline void __ipv6_confirm_neigh_stub(struct net_device *dev,
+@@ -420,10 +420,10 @@ static inline void __ipv6_confirm_neigh_stub(struct net_device *dev,
+ {
+       struct neighbour *n;
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       n = __ipv6_neigh_lookup_noref_stub(dev, pkey);
+       neigh_confirm(n);
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+ }
+ /* uses ipv6_stub and is meant for use outside of IPv6 core */
+diff --git a/include/net/neighbour.h b/include/net/neighbour.h
+index cd30aac9ec835..f6a8ecc6b1fa7 100644
+--- a/include/net/neighbour.h
++++ b/include/net/neighbour.h
+@@ -299,14 +299,14 @@ static inline struct neighbour *___neigh_lookup_noref(
+       const void *pkey,
+       struct net_device *dev)
+ {
+-      struct neigh_hash_table *nht = rcu_dereference_bh(tbl->nht);
++      struct neigh_hash_table *nht = rcu_dereference(tbl->nht);
+       struct neighbour *n;
+       u32 hash_val;
+       hash_val = hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift);
+-      for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
++      for (n = rcu_dereference(nht->hash_buckets[hash_val]);
+            n != NULL;
+-           n = rcu_dereference_bh(n->next)) {
++           n = rcu_dereference(n->next)) {
+               if (n->dev == dev && key_eq(n, pkey))
+                       return n;
+       }
+diff --git a/include/net/nexthop.h b/include/net/nexthop.h
+index 28085b995ddcf..9fa291a046211 100644
+--- a/include/net/nexthop.h
++++ b/include/net/nexthop.h
+@@ -498,7 +498,7 @@ static inline struct fib6_nh *nexthop_fib6_nh(struct nexthop *nh)
+ }
+ /* Variant of nexthop_fib6_nh().
+- * Caller should either hold rcu_read_lock_bh(), or RTNL.
++ * Caller should either hold rcu_read_lock(), or RTNL.
+  */
+ static inline struct fib6_nh *nexthop_fib6_nh_bh(struct nexthop *nh)
+ {
+@@ -507,13 +507,13 @@ static inline struct fib6_nh *nexthop_fib6_nh_bh(struct nexthop *nh)
+       if (nh->is_group) {
+               struct nh_group *nh_grp;
+-              nh_grp = rcu_dereference_bh_rtnl(nh->nh_grp);
++              nh_grp = rcu_dereference_rtnl(nh->nh_grp);
+               nh = nexthop_mpath_select(nh_grp, 0);
+               if (!nh)
+                       return NULL;
+       }
+-      nhi = rcu_dereference_bh_rtnl(nh->nh_info);
++      nhi = rcu_dereference_rtnl(nh->nh_info);
+       if (nhi->family == AF_INET6)
+               return &nhi->fib6_nh;
+diff --git a/net/core/filter.c b/net/core/filter.c
+index d32c6bd4d579a..adc327f4af1e9 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -2197,7 +2197,7 @@ static int bpf_out_neigh_v6(struct net *net, struct sk_buff *skb,
+                       return -ENOMEM;
+       }
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       if (!nh) {
+               dst = skb_dst(skb);
+               nexthop = rt6_nexthop(container_of(dst, struct rt6_info, dst),
+@@ -2210,10 +2210,12 @@ static int bpf_out_neigh_v6(struct net *net, struct sk_buff *skb,
+               int ret;
+               sock_confirm_neigh(skb, neigh);
++              local_bh_disable();
+               dev_xmit_recursion_inc();
+               ret = neigh_output(neigh, skb, false);
+               dev_xmit_recursion_dec();
+-              rcu_read_unlock_bh();
++              local_bh_enable();
++              rcu_read_unlock();
+               return ret;
+       }
+       rcu_read_unlock_bh();
+@@ -2295,7 +2297,7 @@ static int bpf_out_neigh_v4(struct net *net, struct sk_buff *skb,
+                       return -ENOMEM;
+       }
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       if (!nh) {
+               struct dst_entry *dst = skb_dst(skb);
+               struct rtable *rt = container_of(dst, struct rtable, dst);
+@@ -2307,7 +2309,7 @@ static int bpf_out_neigh_v4(struct net *net, struct sk_buff *skb,
+       } else if (nh->nh_family == AF_INET) {
+               neigh = ip_neigh_gw4(dev, nh->ipv4_nh);
+       } else {
+-              rcu_read_unlock_bh();
++              rcu_read_unlock();
+               goto out_drop;
+       }
+@@ -2315,13 +2317,15 @@ static int bpf_out_neigh_v4(struct net *net, struct sk_buff *skb,
+               int ret;
+               sock_confirm_neigh(skb, neigh);
++              local_bh_disable();
+               dev_xmit_recursion_inc();
+               ret = neigh_output(neigh, skb, is_v6gw);
+               dev_xmit_recursion_dec();
+-              rcu_read_unlock_bh();
++              local_bh_enable();
++              rcu_read_unlock();
+               return ret;
+       }
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+ out_drop:
+       kfree_skb(skb);
+       return -ENETDOWN;
+diff --git a/net/core/neighbour.c b/net/core/neighbour.c
+index 51393079487ae..bafd72e5f5886 100644
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -614,7 +614,7 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
+       NEIGH_CACHE_STAT_INC(tbl, lookups);
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       n = __neigh_lookup_noref(tbl, pkey, dev);
+       if (n) {
+               if (!refcount_inc_not_zero(&n->refcnt))
+@@ -622,7 +622,7 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
+               NEIGH_CACHE_STAT_INC(tbl, hits);
+       }
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+       return n;
+ }
+ EXPORT_SYMBOL(neigh_lookup);
+@@ -2176,11 +2176,11 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
+                       .ndtc_proxy_qlen        = tbl->proxy_queue.qlen,
+               };
+-              rcu_read_lock_bh();
+-              nht = rcu_dereference_bh(tbl->nht);
++              rcu_read_lock();
++              nht = rcu_dereference(tbl->nht);
+               ndc.ndtc_hash_rnd = nht->hash_rnd[0];
+               ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1);
+-              rcu_read_unlock_bh();
++              rcu_read_unlock();
+               if (nla_put(skb, NDTA_CONFIG, sizeof(ndc), &ndc))
+                       goto nla_put_failure;
+@@ -2695,15 +2695,15 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
+       if (filter->dev_idx || filter->master_idx)
+               flags |= NLM_F_DUMP_FILTERED;
+-      rcu_read_lock_bh();
+-      nht = rcu_dereference_bh(tbl->nht);
++      rcu_read_lock();
++      nht = rcu_dereference(tbl->nht);
+       for (h = s_h; h < (1 << nht->hash_shift); h++) {
+               if (h > s_h)
+                       s_idx = 0;
+-              for (n = rcu_dereference_bh(nht->hash_buckets[h]), idx = 0;
++              for (n = rcu_dereference(nht->hash_buckets[h]), idx = 0;
+                    n != NULL;
+-                   n = rcu_dereference_bh(n->next)) {
++                   n = rcu_dereference(n->next)) {
+                       if (idx < s_idx || !net_eq(dev_net(n->dev), net))
+                               goto next;
+                       if (neigh_ifindex_filtered(n->dev, filter->dev_idx) ||
+@@ -2722,7 +2722,7 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
+       }
+       rc = skb->len;
+ out:
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+       cb->args[1] = h;
+       cb->args[2] = idx;
+       return rc;
+@@ -3067,20 +3067,20 @@ void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void
+       int chain;
+       struct neigh_hash_table *nht;
+-      rcu_read_lock_bh();
+-      nht = rcu_dereference_bh(tbl->nht);
++      rcu_read_lock();
++      nht = rcu_dereference(tbl->nht);
+-      read_lock(&tbl->lock); /* avoid resizes */
++      read_lock_bh(&tbl->lock); /* avoid resizes */
+       for (chain = 0; chain < (1 << nht->hash_shift); chain++) {
+               struct neighbour *n;
+-              for (n = rcu_dereference_bh(nht->hash_buckets[chain]);
++              for (n = rcu_dereference(nht->hash_buckets[chain]);
+                    n != NULL;
+-                   n = rcu_dereference_bh(n->next))
++                   n = rcu_dereference(n->next))
+                       cb(n, cookie);
+       }
+-      read_unlock(&tbl->lock);
+-      rcu_read_unlock_bh();
++      read_unlock_bh(&tbl->lock);
++      rcu_read_unlock();
+ }
+ EXPORT_SYMBOL(neigh_for_each);
+@@ -3130,7 +3130,7 @@ int neigh_xmit(int index, struct net_device *dev,
+               tbl = neigh_tables[index];
+               if (!tbl)
+                       goto out;
+-              rcu_read_lock_bh();
++              rcu_read_lock();
+               if (index == NEIGH_ARP_TABLE) {
+                       u32 key = *((u32 *)addr);
+@@ -3142,11 +3142,11 @@ int neigh_xmit(int index, struct net_device *dev,
+                       neigh = __neigh_create(tbl, addr, dev, false);
+               err = PTR_ERR(neigh);
+               if (IS_ERR(neigh)) {
+-                      rcu_read_unlock_bh();
++                      rcu_read_unlock();
+                       goto out_kfree_skb;
+               }
+               err = neigh->output(neigh, skb);
+-              rcu_read_unlock_bh();
++              rcu_read_unlock();
+       }
+       else if (index == NEIGH_LINK_TABLE) {
+               err = dev_hard_header(skb, dev, ntohs(skb->protocol),
+@@ -3175,7 +3175,7 @@ static struct neighbour *neigh_get_first(struct seq_file *seq)
+       state->flags &= ~NEIGH_SEQ_IS_PNEIGH;
+       for (bucket = 0; bucket < (1 << nht->hash_shift); bucket++) {
+-              n = rcu_dereference_bh(nht->hash_buckets[bucket]);
++              n = rcu_dereference(nht->hash_buckets[bucket]);
+               while (n) {
+                       if (!net_eq(dev_net(n->dev), net))
+@@ -3193,7 +3193,7 @@ static struct neighbour *neigh_get_first(struct seq_file *seq)
+                       if (READ_ONCE(n->nud_state) & ~NUD_NOARP)
+                               break;
+ next:
+-                      n = rcu_dereference_bh(n->next);
++                      n = rcu_dereference(n->next);
+               }
+               if (n)
+@@ -3217,7 +3217,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
+               if (v)
+                       return n;
+       }
+-      n = rcu_dereference_bh(n->next);
++      n = rcu_dereference(n->next);
+       while (1) {
+               while (n) {
+@@ -3235,7 +3235,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
+                       if (READ_ONCE(n->nud_state) & ~NUD_NOARP)
+                               break;
+ next:
+-                      n = rcu_dereference_bh(n->next);
++                      n = rcu_dereference(n->next);
+               }
+               if (n)
+@@ -3244,7 +3244,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
+               if (++state->bucket >= (1 << nht->hash_shift))
+                       break;
+-              n = rcu_dereference_bh(nht->hash_buckets[state->bucket]);
++              n = rcu_dereference(nht->hash_buckets[state->bucket]);
+       }
+       if (n && pos)
+@@ -3346,7 +3346,7 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos)
+ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags)
+       __acquires(tbl->lock)
+-      __acquires(rcu_bh)
++      __acquires(rcu)
+ {
+       struct neigh_seq_state *state = seq->private;
+@@ -3354,9 +3354,9 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl
+       state->bucket = 0;
+       state->flags = (neigh_seq_flags & ~NEIGH_SEQ_IS_PNEIGH);
+-      rcu_read_lock_bh();
+-      state->nht = rcu_dereference_bh(tbl->nht);
+-      read_lock(&tbl->lock);
++      rcu_read_lock();
++      state->nht = rcu_dereference(tbl->nht);
++      read_lock_bh(&tbl->lock);
+       return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN;
+ }
+@@ -3391,13 +3391,13 @@ EXPORT_SYMBOL(neigh_seq_next);
+ void neigh_seq_stop(struct seq_file *seq, void *v)
+       __releases(tbl->lock)
+-      __releases(rcu_bh)
++      __releases(rcu)
+ {
+       struct neigh_seq_state *state = seq->private;
+       struct neigh_table *tbl = state->tbl;
+-      read_unlock(&tbl->lock);
+-      rcu_read_unlock_bh();
++      read_unlock_bh(&tbl->lock);
++      rcu_read_unlock();
+ }
+ EXPORT_SYMBOL(neigh_seq_stop);
+diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
+index 158ad3c2662f5..eafa4a0335157 100644
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -2194,7 +2194,7 @@ static bool fib_good_nh(const struct fib_nh *nh)
+       if (nh->fib_nh_scope == RT_SCOPE_LINK) {
+               struct neighbour *n;
+-              rcu_read_lock_bh();
++              rcu_read_lock();
+               if (likely(nh->fib_nh_gw_family == AF_INET))
+                       n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev,
+@@ -2207,7 +2207,7 @@ static bool fib_good_nh(const struct fib_nh *nh)
+               if (n)
+                       state = READ_ONCE(n->nud_state);
+-              rcu_read_unlock_bh();
++              rcu_read_unlock();
+       }
+       return !!(state & NUD_VALID);
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index 66908ce2dd116..493c679ea54f3 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -218,7 +218,7 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s
+                       return res;
+       }
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       neigh = ip_neigh_for_gw(rt, skb, &is_v6gw);
+       if (!IS_ERR(neigh)) {
+               int res;
+@@ -226,10 +226,10 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s
+               sock_confirm_neigh(skb, neigh);
+               /* if crossing protocols, can not use the cached header */
+               res = neigh_output(neigh, skb, is_v6gw);
+-              rcu_read_unlock_bh();
++              rcu_read_unlock();
+               return res;
+       }
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+       net_dbg_ratelimited("%s: No header cache and no neighbour!\n",
+                           __func__);
+diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
+index d699a41c9d955..be5498f5dd319 100644
+--- a/net/ipv4/nexthop.c
++++ b/net/ipv4/nexthop.c
+@@ -1124,13 +1124,13 @@ static bool ipv6_good_nh(const struct fib6_nh *nh)
+       int state = NUD_REACHABLE;
+       struct neighbour *n;
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       n = __ipv6_neigh_lookup_noref_stub(nh->fib_nh_dev, &nh->fib_nh_gw6);
+       if (n)
+               state = READ_ONCE(n->nud_state);
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+       return !!(state & NUD_VALID);
+ }
+@@ -1140,14 +1140,14 @@ static bool ipv4_good_nh(const struct fib_nh *nh)
+       int state = NUD_REACHABLE;
+       struct neighbour *n;
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev,
+                                     (__force u32)nh->fib_nh_gw4);
+       if (n)
+               state = READ_ONCE(n->nud_state);
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+       return !!(state & NUD_VALID);
+ }
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 8d838b0046900..608bd9f8dbc86 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -408,7 +408,7 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
+       struct net_device *dev = dst->dev;
+       struct neighbour *n;
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       if (likely(rt->rt_gw_family == AF_INET)) {
+               n = ip_neigh_gw4(dev, rt->rt_gw4);
+@@ -424,7 +424,7 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
+       if (!IS_ERR(n) && !refcount_inc_not_zero(&n->refcnt))
+               n = NULL;
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+       return n;
+ }
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 96f4351b55a6f..c63ccd39fc552 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -1035,7 +1035,7 @@ static int ipv6_add_addr_hash(struct net_device *dev, struct inet6_ifaddr *ifa)
+       unsigned int hash = inet6_addr_hash(net, &ifa->addr);
+       int err = 0;
+-      spin_lock(&net->ipv6.addrconf_hash_lock);
++      spin_lock_bh(&net->ipv6.addrconf_hash_lock);
+       /* Ignore adding duplicate addresses on an interface */
+       if (ipv6_chk_same_addr(net, &ifa->addr, dev, hash)) {
+@@ -1045,7 +1045,7 @@ static int ipv6_add_addr_hash(struct net_device *dev, struct inet6_ifaddr *ifa)
+               hlist_add_head_rcu(&ifa->addr_lst, &net->ipv6.inet6_addr_lst[hash]);
+       }
+-      spin_unlock(&net->ipv6.addrconf_hash_lock);
++      spin_unlock_bh(&net->ipv6.addrconf_hash_lock);
+       return err;
+ }
+@@ -1140,15 +1140,15 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg,
+       /* For caller */
+       refcount_set(&ifa->refcnt, 1);
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       err = ipv6_add_addr_hash(idev->dev, ifa);
+       if (err < 0) {
+-              rcu_read_unlock_bh();
++              rcu_read_unlock();
+               goto out;
+       }
+-      write_lock(&idev->lock);
++      write_lock_bh(&idev->lock);
+       /* Add to inet6_dev unicast addr list. */
+       ipv6_link_dev_addr(idev, ifa);
+@@ -1159,9 +1159,9 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg,
+       }
+       in6_ifa_hold(ifa);
+-      write_unlock(&idev->lock);
++      write_unlock_bh(&idev->lock);
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+       inet6addr_notifier_call_chain(NETDEV_UP, ifa);
+ out:
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index 5bf15a530fe73..ce2c5e728745f 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -116,7 +116,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
+                       return res;
+       }
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       nexthop = rt6_nexthop((struct rt6_info *)dst, daddr);
+       neigh = __ipv6_neigh_lookup_noref(dev, nexthop);
+@@ -124,7 +124,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
+               if (unlikely(!neigh))
+                       neigh = __neigh_create(&nd_tbl, nexthop, dev, false);
+               if (IS_ERR(neigh)) {
+-                      rcu_read_unlock_bh();
++                      rcu_read_unlock();
+                       IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTNOROUTES);
+                       kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_CREATEFAIL);
+                       return -EINVAL;
+@@ -132,7 +132,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
+       }
+       sock_confirm_neigh(skb, neigh);
+       ret = neigh_output(neigh, skb, false);
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+       return ret;
+ }
+@@ -1150,11 +1150,11 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk,
+        * dst entry of the nexthop router
+        */
+       rt = (struct rt6_info *) *dst;
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       n = __ipv6_neigh_lookup_noref(rt->dst.dev,
+                                     rt6_nexthop(rt, &fl6->daddr));
+       err = n && !(READ_ONCE(n->nud_state) & NUD_VALID) ? -EINVAL : 0;
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+       if (err) {
+               struct inet6_ifaddr *ifp;
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 4f103e7c4ea25..0a9f854bfa50c 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -636,7 +636,7 @@ static void rt6_probe(struct fib6_nh *fib6_nh)
+       nh_gw = &fib6_nh->fib_nh_gw6;
+       dev = fib6_nh->fib_nh_dev;
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       last_probe = READ_ONCE(fib6_nh->last_probe);
+       idev = __in6_dev_get(dev);
+       neigh = __ipv6_neigh_lookup_noref(dev, nh_gw);
+@@ -644,7 +644,7 @@ static void rt6_probe(struct fib6_nh *fib6_nh)
+               if (READ_ONCE(neigh->nud_state) & NUD_VALID)
+                       goto out;
+-              write_lock(&neigh->lock);
++              write_lock_bh(&neigh->lock);
+               if (!(neigh->nud_state & NUD_VALID) &&
+                   time_after(jiffies,
+                              neigh->updated + idev->cnf.rtr_probe_interval)) {
+@@ -652,7 +652,7 @@ static void rt6_probe(struct fib6_nh *fib6_nh)
+                       if (work)
+                               __neigh_set_probe_once(neigh);
+               }
+-              write_unlock(&neigh->lock);
++              write_unlock_bh(&neigh->lock);
+       } else if (time_after(jiffies, last_probe +
+                                      idev->cnf.rtr_probe_interval)) {
+               work = kmalloc(sizeof(*work), GFP_ATOMIC);
+@@ -670,7 +670,7 @@ static void rt6_probe(struct fib6_nh *fib6_nh)
+       }
+ out:
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+ }
+ #else
+ static inline void rt6_probe(struct fib6_nh *fib6_nh)
+@@ -686,7 +686,7 @@ static enum rt6_nud_state rt6_check_neigh(const struct fib6_nh *fib6_nh)
+       enum rt6_nud_state ret = RT6_NUD_FAIL_HARD;
+       struct neighbour *neigh;
+-      rcu_read_lock_bh();
++      rcu_read_lock();
+       neigh = __ipv6_neigh_lookup_noref(fib6_nh->fib_nh_dev,
+                                         &fib6_nh->fib_nh_gw6);
+       if (neigh) {
+@@ -704,7 +704,7 @@ static enum rt6_nud_state rt6_check_neigh(const struct fib6_nh *fib6_nh)
+               ret = IS_ENABLED(CONFIG_IPV6_ROUTER_PREF) ?
+                     RT6_NUD_SUCCEED : RT6_NUD_FAIL_DO_RR;
+       }
+-      rcu_read_unlock_bh();
++      rcu_read_unlock();
+       return ret;
+ }
+-- 
+2.40.1
+
diff --git a/queue-6.1/net-dsa-mv88e6xxx-avoid-eeprom-timeout-when-eeprom-i.patch b/queue-6.1/net-dsa-mv88e6xxx-avoid-eeprom-timeout-when-eeprom-i.patch
new file mode 100644 (file)
index 0000000..09e368b
--- /dev/null
@@ -0,0 +1,175 @@
+From 6d3398a194df302745f3d970983e01c4de197c96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Sep 2023 09:47:41 -0300
+Subject: net: dsa: mv88e6xxx: Avoid EEPROM timeout when EEPROM is absent
+
+From: Fabio Estevam <festevam@denx.de>
+
+[ Upstream commit 6ccf50d4d4741e064ba35511a95402c63bbe21a8 ]
+
+Since commit 23d775f12dcd ("net: dsa: mv88e6xxx: Wait for EEPROM done
+before HW reset") the following error is seen on a imx8mn board with
+a 88E6320 switch:
+
+mv88e6085 30be0000.ethernet-1:00: Timeout waiting for EEPROM done
+
+This board does not have an EEPROM attached to the switch though.
+
+This problem is well explained by Andrew Lunn:
+
+"If there is an EEPROM, and the EEPROM contains a lot of data, it could
+be that when we perform a hardware reset towards the end of probe, it
+interrupts an I2C bus transaction, leaving the I2C bus in a bad state,
+and future reads of the EEPROM do not work.
+
+The work around for this was to poll the EEInt status and wait for it
+to go true before performing the hardware reset.
+
+However, we have discovered that for some boards which do not have an
+EEPROM, EEInt never indicates complete. As a result,
+mv88e6xxx_g1_wait_eeprom_done() spins for a second and then prints a
+warning.
+
+We probably need a different solution than calling
+mv88e6xxx_g1_wait_eeprom_done(). The datasheet for 6352 documents the
+EEPROM Command register:
+
+bit 15 is:
+
+  EEPROM Unit Busy. This bit must be set to a one to start an EEPROM
+  operation (see EEOp below). Only one EEPROM operation can be
+  executing at one time so this bit must be zero before setting it to
+  a one.  When the requested EEPROM operation completes this bit will
+  automatically be cleared to a zero. The transition of this bit from
+  a one to a zero can be used to generate an interrupt (the EEInt in
+  Global 1, offset 0x00).
+
+and more interesting is bit 11:
+
+  Register Loader Running. This bit is set to one whenever the
+  register loader is busy executing instructions contained in the
+  EEPROM."
+
+Change to using mv88e6xxx_g2_eeprom_wait() to fix the timeout error
+when the EEPROM chip is not present.
+
+Fixes: 23d775f12dcd ("net: dsa: mv88e6xxx: Wait for EEPROM done before HW reset")
+Suggested-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Fabio Estevam <festevam@denx.de>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.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/dsa/mv88e6xxx/chip.c    |  6 ++++--
+ drivers/net/dsa/mv88e6xxx/global1.c | 31 -----------------------------
+ drivers/net/dsa/mv88e6xxx/global1.h |  1 -
+ drivers/net/dsa/mv88e6xxx/global2.c |  2 +-
+ drivers/net/dsa/mv88e6xxx/global2.h |  1 +
+ 5 files changed, 6 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index a73008b9e0b3c..ba906dfab055c 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -3012,14 +3012,16 @@ static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
+                * from the wrong location resulting in the switch booting
+                * to wrong mode and inoperable.
+                */
+-              mv88e6xxx_g1_wait_eeprom_done(chip);
++              if (chip->info->ops->get_eeprom)
++                      mv88e6xxx_g2_eeprom_wait(chip);
+               gpiod_set_value_cansleep(gpiod, 1);
+               usleep_range(10000, 20000);
+               gpiod_set_value_cansleep(gpiod, 0);
+               usleep_range(10000, 20000);
+-              mv88e6xxx_g1_wait_eeprom_done(chip);
++              if (chip->info->ops->get_eeprom)
++                      mv88e6xxx_g2_eeprom_wait(chip);
+       }
+ }
+diff --git a/drivers/net/dsa/mv88e6xxx/global1.c b/drivers/net/dsa/mv88e6xxx/global1.c
+index 5848112036b08..964928285782c 100644
+--- a/drivers/net/dsa/mv88e6xxx/global1.c
++++ b/drivers/net/dsa/mv88e6xxx/global1.c
+@@ -75,37 +75,6 @@ static int mv88e6xxx_g1_wait_init_ready(struct mv88e6xxx_chip *chip)
+       return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1);
+ }
+-void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip)
+-{
+-      const unsigned long timeout = jiffies + 1 * HZ;
+-      u16 val;
+-      int err;
+-
+-      /* Wait up to 1 second for the switch to finish reading the
+-       * EEPROM.
+-       */
+-      while (time_before(jiffies, timeout)) {
+-              err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &val);
+-              if (err) {
+-                      dev_err(chip->dev, "Error reading status");
+-                      return;
+-              }
+-
+-              /* If the switch is still resetting, it may not
+-               * respond on the bus, and so MDIO read returns
+-               * 0xffff. Differentiate between that, and waiting for
+-               * the EEPROM to be done by bit 0 being set.
+-               */
+-              if (val != 0xffff &&
+-                  val & BIT(MV88E6XXX_G1_STS_IRQ_EEPROM_DONE))
+-                      return;
+-
+-              usleep_range(1000, 2000);
+-      }
+-
+-      dev_err(chip->dev, "Timeout waiting for EEPROM done");
+-}
+-
+ /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1
+  * Offset 0x02: Switch MAC Address Register Bytes 2 & 3
+  * Offset 0x03: Switch MAC Address Register Bytes 4 & 5
+diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h
+index 65958b2a0d3a3..04b57a21f7868 100644
+--- a/drivers/net/dsa/mv88e6xxx/global1.h
++++ b/drivers/net/dsa/mv88e6xxx/global1.h
+@@ -281,7 +281,6 @@ int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr);
+ int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip);
+ int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip);
+ int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip);
+-void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip);
+ int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip);
+ int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip);
+diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c
+index ec49939968fac..ac302a935ce69 100644
+--- a/drivers/net/dsa/mv88e6xxx/global2.c
++++ b/drivers/net/dsa/mv88e6xxx/global2.c
+@@ -340,7 +340,7 @@ int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
+  * Offset 0x15: EEPROM Addr (for 8-bit data access)
+  */
+-static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
++int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
+ {
+       int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY);
+       int err;
+diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
+index c05fad5c9f19d..751a6c988de42 100644
+--- a/drivers/net/dsa/mv88e6xxx/global2.h
++++ b/drivers/net/dsa/mv88e6xxx/global2.h
+@@ -359,6 +359,7 @@ int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip);
+ int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target,
+                                     int port);
++int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip);
+ extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops;
+ extern const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops;
+-- 
+2.40.1
+
diff --git a/queue-6.1/net-ethernet-ti-am65-cpsw-fix-error-code-in-am65_cps.patch b/queue-6.1/net-ethernet-ti-am65-cpsw-fix-error-code-in-am65_cps.patch
new file mode 100644 (file)
index 0000000..b33065c
--- /dev/null
@@ -0,0 +1,37 @@
+From 0b1db8e8e8d7e81aff8ee17b2ca00c6a6ee9337a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Sep 2023 17:04:43 +0300
+Subject: net: ethernet: ti: am65-cpsw: Fix error code in
+ am65_cpsw_nuss_init_tx_chns()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 37d4f55567982e445f86dc0ff4ecfa72921abfe8 ]
+
+This accidentally returns success, but it should return a negative error
+code.
+
+Fixes: 93a76530316a ("net: ethernet: ti: introduce am65x/j721e gigabit eth subsystem driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Roger Quadros <rogerq@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index 25466cbdc16bd..9f2553799895d 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -1614,6 +1614,7 @@ static int am65_cpsw_nuss_init_tx_chns(struct am65_cpsw_common *common)
+               if (tx_chn->irq <= 0) {
+                       dev_err(dev, "Failed to get tx dma irq %d\n",
+                               tx_chn->irq);
++                      ret = tx_chn->irq ?: -ENXIO;
+                       goto err;
+               }
+-- 
+2.40.1
+
diff --git a/queue-6.1/net-fix-possible-store-tearing-in-neigh_periodic_wor.patch b/queue-6.1/net-fix-possible-store-tearing-in-neigh_periodic_wor.patch
new file mode 100644 (file)
index 0000000..11c99cd
--- /dev/null
@@ -0,0 +1,48 @@
+From 0d679e940ffa1b28a8c11f1742d91394726b865b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Sep 2023 08:46:26 +0000
+Subject: net: fix possible store tearing in neigh_periodic_work()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 25563b581ba3a1f263a00e8c9a97f5e7363be6fd ]
+
+While looking at a related syzbot report involving neigh_periodic_work(),
+I found that I forgot to add an annotation when deleting an
+RCU protected item from a list.
+
+Readers use rcu_deference(*np), we need to use either
+rcu_assign_pointer() or WRITE_ONCE() on writer side
+to prevent store tearing.
+
+I use rcu_assign_pointer() to have lockdep support,
+this was the choice made in neigh_flush_dev().
+
+Fixes: 767e97e1e0db ("neigh: RCU conversion of struct neighbour")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/neighbour.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/core/neighbour.c b/net/core/neighbour.c
+index 6c0f2149f2c72..8e726eb0548f6 100644
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -988,7 +988,9 @@ static void neigh_periodic_work(struct work_struct *work)
+                           (state == NUD_FAILED ||
+                            !time_in_range_open(jiffies, n->used,
+                                                n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) {
+-                              *np = n->next;
++                              rcu_assign_pointer(*np,
++                                      rcu_dereference_protected(n->next,
++                                              lockdep_is_held(&tbl->lock)));
+                               neigh_mark_dead(n);
+                               write_unlock(&n->lock);
+                               neigh_cleanup_and_release(n);
+-- 
+2.40.1
+
diff --git a/queue-6.1/net-nfc-llcp-add-lock-when-modifying-device-list.patch b/queue-6.1/net-nfc-llcp-add-lock-when-modifying-device-list.patch
new file mode 100644 (file)
index 0000000..f6a07a3
--- /dev/null
@@ -0,0 +1,41 @@
+From c94c55104952800d08d8716d3bf95e4a1bd83e18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Sep 2023 19:58:53 -0400
+Subject: net: nfc: llcp: Add lock when modifying device list
+
+From: Jeremy Cline <jeremy@jcline.org>
+
+[ Upstream commit dfc7f7a988dad34c3bf4c053124fb26aa6c5f916 ]
+
+The device list needs its associated lock held when modifying it, or the
+list could become corrupted, as syzbot discovered.
+
+Reported-and-tested-by: syzbot+c1d0a03d305972dbbe14@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=c1d0a03d305972dbbe14
+Signed-off-by: Jeremy Cline <jeremy@jcline.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Fixes: 6709d4b7bc2e ("net: nfc: Fix use-after-free caused by nfc_llcp_find_local")
+Link: https://lore.kernel.org/r/20230908235853.1319596-1-jeremy@jcline.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
+index f60e424e06076..6705bb895e239 100644
+--- a/net/nfc/llcp_core.c
++++ b/net/nfc/llcp_core.c
+@@ -1636,7 +1636,9 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
+       timer_setup(&local->sdreq_timer, nfc_llcp_sdreq_timer, 0);
+       INIT_WORK(&local->sdreq_timeout_work, nfc_llcp_sdreq_timeout_work);
++      spin_lock(&llcp_devices_lock);
+       list_add(&local->list, &llcp_devices);
++      spin_unlock(&llcp_devices_lock);
+       return 0;
+ }
+-- 
+2.40.1
+
diff --git a/queue-6.1/net-stmmac-dwmac-stm32-fix-resume-on-stm32-mcu.patch b/queue-6.1/net-stmmac-dwmac-stm32-fix-resume-on-stm32-mcu.patch
new file mode 100644 (file)
index 0000000..1434615
--- /dev/null
@@ -0,0 +1,68 @@
+From 11e13b9b3922e888ff2a28a9627b6a4d30215a5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Sep 2023 13:57:49 -0400
+Subject: net: stmmac: dwmac-stm32: fix resume on STM32 MCU
+
+From: Ben Wolsieffer <ben.wolsieffer@hefring.com>
+
+[ Upstream commit 6f195d6b0da3b689922ba9e302af2f49592fa9fc ]
+
+The STM32MP1 keeps clk_rx enabled during suspend, and therefore the
+driver does not enable the clock in stm32_dwmac_init() if the device was
+suspended. The problem is that this same code runs on STM32 MCUs, which
+do disable clk_rx during suspend, causing the clock to never be
+re-enabled on resume.
+
+This patch adds a variant flag to indicate that clk_rx remains enabled
+during suspend, and uses this to decide whether to enable the clock in
+stm32_dwmac_init() if the device was suspended.
+
+This approach fixes this specific bug with limited opportunity for
+unintended side-effects, but I have a follow up patch that will refactor
+the clock configuration and hopefully make it less error prone.
+
+Fixes: 6528e02cc9ff ("net: ethernet: stmmac: add adaptation for stm32mp157c.")
+Signed-off-by: Ben Wolsieffer <ben.wolsieffer@hefring.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://lore.kernel.org/r/20230927175749.1419774-1-ben.wolsieffer@hefring.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+index 2b38a499a4045..533f5245ad945 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+@@ -105,6 +105,7 @@ struct stm32_ops {
+       int (*parse_data)(struct stm32_dwmac *dwmac,
+                         struct device *dev);
+       u32 syscfg_eth_mask;
++      bool clk_rx_enable_in_suspend;
+ };
+ static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
+@@ -122,7 +123,8 @@ static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
+       if (ret)
+               return ret;
+-      if (!dwmac->dev->power.is_suspended) {
++      if (!dwmac->ops->clk_rx_enable_in_suspend ||
++          !dwmac->dev->power.is_suspended) {
+               ret = clk_prepare_enable(dwmac->clk_rx);
+               if (ret) {
+                       clk_disable_unprepare(dwmac->clk_tx);
+@@ -515,7 +517,8 @@ static struct stm32_ops stm32mp1_dwmac_data = {
+       .suspend = stm32mp1_suspend,
+       .resume = stm32mp1_resume,
+       .parse_data = stm32mp1_parse_data,
+-      .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK
++      .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK,
++      .clk_rx_enable_in_suspend = true
+ };
+ static const struct of_device_id stm32_dwmac_match[] = {
+-- 
+2.40.1
+
diff --git a/queue-6.1/net-usb-smsc75xx-fix-uninit-value-access-in-__smsc75.patch b/queue-6.1/net-usb-smsc75xx-fix-uninit-value-access-in-__smsc75.patch
new file mode 100644 (file)
index 0000000..53723b3
--- /dev/null
@@ -0,0 +1,99 @@
+From c9706d8ec5f7738eb57072fc4e66c8e84fcbcdaa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Sep 2023 02:35:49 +0900
+Subject: net: usb: smsc75xx: Fix uninit-value access in __smsc75xx_read_reg
+
+From: Shigeru Yoshida <syoshida@redhat.com>
+
+[ Upstream commit e9c65989920f7c28775ec4e0c11b483910fb67b8 ]
+
+syzbot reported the following uninit-value access issue:
+
+=====================================================
+BUG: KMSAN: uninit-value in smsc75xx_wait_ready drivers/net/usb/smsc75xx.c:975 [inline]
+BUG: KMSAN: uninit-value in smsc75xx_bind+0x5c9/0x11e0 drivers/net/usb/smsc75xx.c:1482
+CPU: 0 PID: 8696 Comm: kworker/0:3 Not tainted 5.8.0-rc5-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Workqueue: usb_hub_wq hub_event
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0x21c/0x280 lib/dump_stack.c:118
+ kmsan_report+0xf7/0x1e0 mm/kmsan/kmsan_report.c:121
+ __msan_warning+0x58/0xa0 mm/kmsan/kmsan_instr.c:215
+ smsc75xx_wait_ready drivers/net/usb/smsc75xx.c:975 [inline]
+ smsc75xx_bind+0x5c9/0x11e0 drivers/net/usb/smsc75xx.c:1482
+ usbnet_probe+0x1152/0x3f90 drivers/net/usb/usbnet.c:1737
+ usb_probe_interface+0xece/0x1550 drivers/usb/core/driver.c:374
+ really_probe+0xf20/0x20b0 drivers/base/dd.c:529
+ driver_probe_device+0x293/0x390 drivers/base/dd.c:701
+ __device_attach_driver+0x63f/0x830 drivers/base/dd.c:807
+ bus_for_each_drv+0x2ca/0x3f0 drivers/base/bus.c:431
+ __device_attach+0x4e2/0x7f0 drivers/base/dd.c:873
+ device_initial_probe+0x4a/0x60 drivers/base/dd.c:920
+ bus_probe_device+0x177/0x3d0 drivers/base/bus.c:491
+ device_add+0x3b0e/0x40d0 drivers/base/core.c:2680
+ usb_set_configuration+0x380f/0x3f10 drivers/usb/core/message.c:2032
+ usb_generic_driver_probe+0x138/0x300 drivers/usb/core/generic.c:241
+ usb_probe_device+0x311/0x490 drivers/usb/core/driver.c:272
+ really_probe+0xf20/0x20b0 drivers/base/dd.c:529
+ driver_probe_device+0x293/0x390 drivers/base/dd.c:701
+ __device_attach_driver+0x63f/0x830 drivers/base/dd.c:807
+ bus_for_each_drv+0x2ca/0x3f0 drivers/base/bus.c:431
+ __device_attach+0x4e2/0x7f0 drivers/base/dd.c:873
+ device_initial_probe+0x4a/0x60 drivers/base/dd.c:920
+ bus_probe_device+0x177/0x3d0 drivers/base/bus.c:491
+ device_add+0x3b0e/0x40d0 drivers/base/core.c:2680
+ usb_new_device+0x1bd4/0x2a30 drivers/usb/core/hub.c:2554
+ hub_port_connect drivers/usb/core/hub.c:5208 [inline]
+ hub_port_connect_change drivers/usb/core/hub.c:5348 [inline]
+ port_event drivers/usb/core/hub.c:5494 [inline]
+ hub_event+0x5e7b/0x8a70 drivers/usb/core/hub.c:5576
+ process_one_work+0x1688/0x2140 kernel/workqueue.c:2269
+ worker_thread+0x10bc/0x2730 kernel/workqueue.c:2415
+ kthread+0x551/0x590 kernel/kthread.c:292
+ ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:293
+
+Local variable ----buf.i87@smsc75xx_bind created at:
+ __smsc75xx_read_reg drivers/net/usb/smsc75xx.c:83 [inline]
+ smsc75xx_wait_ready drivers/net/usb/smsc75xx.c:968 [inline]
+ smsc75xx_bind+0x485/0x11e0 drivers/net/usb/smsc75xx.c:1482
+ __smsc75xx_read_reg drivers/net/usb/smsc75xx.c:83 [inline]
+ smsc75xx_wait_ready drivers/net/usb/smsc75xx.c:968 [inline]
+ smsc75xx_bind+0x485/0x11e0 drivers/net/usb/smsc75xx.c:1482
+
+This issue is caused because usbnet_read_cmd() reads less bytes than requested
+(zero byte in the reproducer). In this case, 'buf' is not properly filled.
+
+This patch fixes the issue by returning -ENODATA if usbnet_read_cmd() reads
+less bytes than requested.
+
+Fixes: d0cad871703b ("smsc75xx: SMSC LAN75xx USB gigabit ethernet adapter driver")
+Reported-and-tested-by: syzbot+6966546b78d050bb0b5d@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=6966546b78d050bb0b5d
+Signed-off-by: Shigeru Yoshida <syoshida@redhat.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20230923173549.3284502-1-syoshida@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/smsc75xx.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
+index 5d6454fedb3f1..78ad2da3ee29b 100644
+--- a/drivers/net/usb/smsc75xx.c
++++ b/drivers/net/usb/smsc75xx.c
+@@ -90,7 +90,9 @@ static int __must_check __smsc75xx_read_reg(struct usbnet *dev, u32 index,
+       ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN
+                | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                0, index, &buf, 4);
+-      if (unlikely(ret < 0)) {
++      if (unlikely(ret < 4)) {
++              ret = ret < 0 ? ret : -ENODATA;
++
+               netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n",
+                           index, ret);
+               return ret;
+-- 
+2.40.1
+
diff --git a/queue-6.1/netfilter-handle-the-connecting-collision-properly-i.patch b/queue-6.1/netfilter-handle-the-connecting-collision-properly-i.patch
new file mode 100644 (file)
index 0000000..6d9a296
--- /dev/null
@@ -0,0 +1,175 @@
+From 4db39a9e3efc34bf9425d59a5916296d87aac754 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Oct 2023 13:17:53 -0400
+Subject: netfilter: handle the connecting collision properly in
+ nf_conntrack_proto_sctp
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 8e56b063c86569e51eed1c5681ce6361fa97fc7a ]
+
+In Scenario A and B below, as the delayed INIT_ACK always changes the peer
+vtag, SCTP ct with the incorrect vtag may cause packet loss.
+
+Scenario A: INIT_ACK is delayed until the peer receives its own INIT_ACK
+
+  192.168.1.2 > 192.168.1.1: [INIT] [init tag: 1328086772]
+    192.168.1.1 > 192.168.1.2: [INIT] [init tag: 1414468151]
+    192.168.1.2 > 192.168.1.1: [INIT ACK] [init tag: 1328086772]
+  192.168.1.1 > 192.168.1.2: [INIT ACK] [init tag: 1650211246] *
+  192.168.1.2 > 192.168.1.1: [COOKIE ECHO]
+    192.168.1.1 > 192.168.1.2: [COOKIE ECHO]
+    192.168.1.2 > 192.168.1.1: [COOKIE ACK]
+
+Scenario B: INIT_ACK is delayed until the peer completes its own handshake
+
+  192.168.1.2 > 192.168.1.1: sctp (1) [INIT] [init tag: 3922216408]
+    192.168.1.1 > 192.168.1.2: sctp (1) [INIT] [init tag: 144230885]
+    192.168.1.2 > 192.168.1.1: sctp (1) [INIT ACK] [init tag: 3922216408]
+    192.168.1.1 > 192.168.1.2: sctp (1) [COOKIE ECHO]
+    192.168.1.2 > 192.168.1.1: sctp (1) [COOKIE ACK]
+  192.168.1.1 > 192.168.1.2: sctp (1) [INIT ACK] [init tag: 3914796021] *
+
+This patch fixes it as below:
+
+In SCTP_CID_INIT processing:
+- clear ct->proto.sctp.init[!dir] if ct->proto.sctp.init[dir] &&
+  ct->proto.sctp.init[!dir]. (Scenario E)
+- set ct->proto.sctp.init[dir].
+
+In SCTP_CID_INIT_ACK processing:
+- drop it if !ct->proto.sctp.init[!dir] && ct->proto.sctp.vtag[!dir] &&
+  ct->proto.sctp.vtag[!dir] != ih->init_tag. (Scenario B, Scenario C)
+- drop it if ct->proto.sctp.init[dir] && ct->proto.sctp.init[!dir] &&
+  ct->proto.sctp.vtag[!dir] != ih->init_tag. (Scenario A)
+
+In SCTP_CID_COOKIE_ACK processing:
+- clear ct->proto.sctp.init[dir] and ct->proto.sctp.init[!dir].
+  (Scenario D)
+
+Also, it's important to allow the ct state to move forward with cookie_echo
+and cookie_ack from the opposite dir for the collision scenarios.
+
+There are also other Scenarios where it should allow the packet through,
+addressed by the processing above:
+
+Scenario C: new CT is created by INIT_ACK.
+
+Scenario D: start INIT on the existing ESTABLISHED ct.
+
+Scenario E: start INIT after the old collision on the existing ESTABLISHED
+ct.
+
+  192.168.1.2 > 192.168.1.1: sctp (1) [INIT] [init tag: 3922216408]
+  192.168.1.1 > 192.168.1.2: sctp (1) [INIT] [init tag: 144230885]
+  (both side are stopped, then start new connection again in hours)
+  192.168.1.2 > 192.168.1.1: sctp (1) [INIT] [init tag: 242308742]
+
+Fixes: 9fb9cbb1082d ("[NETFILTER]: Add nf_conntrack subsystem.")
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/netfilter/nf_conntrack_sctp.h |  1 +
+ net/netfilter/nf_conntrack_proto_sctp.c     | 43 ++++++++++++++++-----
+ 2 files changed, 34 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/netfilter/nf_conntrack_sctp.h b/include/linux/netfilter/nf_conntrack_sctp.h
+index 625f491b95de8..fb31312825ae5 100644
+--- a/include/linux/netfilter/nf_conntrack_sctp.h
++++ b/include/linux/netfilter/nf_conntrack_sctp.h
+@@ -9,6 +9,7 @@ struct ip_ct_sctp {
+       enum sctp_conntrack state;
+       __be32 vtag[IP_CT_DIR_MAX];
++      u8 init[IP_CT_DIR_MAX];
+       u8 last_dir;
+       u8 flags;
+ };
+diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
+index 7247af51bdfc4..c94a9971d790c 100644
+--- a/net/netfilter/nf_conntrack_proto_sctp.c
++++ b/net/netfilter/nf_conntrack_proto_sctp.c
+@@ -112,7 +112,7 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = {
+ /* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA, sSA},
+ /* error        */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't have Stale cookie*/
+ /* cookie_echo  */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA, sCL},/* 5.2.4 - Big TODO */
+-/* cookie_ack   */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't come in orig dir */
++/* cookie_ack   */ {sCL, sCL, sCW, sES, sES, sSS, sSR, sSA, sCL},/* Can't come in orig dir */
+ /* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL, sCL},
+ /* heartbeat    */ {sHS, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS},
+ /* heartbeat_ack*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS},
+@@ -126,7 +126,7 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = {
+ /* shutdown     */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA, sIV},
+ /* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA, sIV},
+ /* error        */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA, sIV},
+-/* cookie_echo  */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV},/* Can't come in reply dir */
++/* cookie_echo  */ {sIV, sCL, sCE, sCE, sES, sSS, sSR, sSA, sIV},/* Can't come in reply dir */
+ /* cookie_ack   */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA, sIV},
+ /* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL, sIV},
+ /* heartbeat    */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS},
+@@ -426,6 +426,9 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,
+                       /* (D) vtag must be same as init_vtag as found in INIT_ACK */
+                       if (sh->vtag != ct->proto.sctp.vtag[dir])
+                               goto out_unlock;
++              } else if (sch->type == SCTP_CID_COOKIE_ACK) {
++                      ct->proto.sctp.init[dir] = 0;
++                      ct->proto.sctp.init[!dir] = 0;
+               } else if (sch->type == SCTP_CID_HEARTBEAT) {
+                       if (ct->proto.sctp.vtag[dir] == 0) {
+                               pr_debug("Setting %d vtag %x for dir %d\n", sch->type, sh->vtag, dir);
+@@ -474,16 +477,18 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,
+               }
+               /* If it is an INIT or an INIT ACK note down the vtag */
+-              if (sch->type == SCTP_CID_INIT ||
+-                  sch->type == SCTP_CID_INIT_ACK) {
+-                      struct sctp_inithdr _inithdr, *ih;
++              if (sch->type == SCTP_CID_INIT) {
++                      struct sctp_inithdr _ih, *ih;
+-                      ih = skb_header_pointer(skb, offset + sizeof(_sch),
+-                                              sizeof(_inithdr), &_inithdr);
+-                      if (ih == NULL)
++                      ih = skb_header_pointer(skb, offset + sizeof(_sch), sizeof(*ih), &_ih);
++                      if (!ih)
+                               goto out_unlock;
+-                      pr_debug("Setting vtag %x for dir %d\n",
+-                               ih->init_tag, !dir);
++
++                      if (ct->proto.sctp.init[dir] && ct->proto.sctp.init[!dir])
++                              ct->proto.sctp.init[!dir] = 0;
++                      ct->proto.sctp.init[dir] = 1;
++
++                      pr_debug("Setting vtag %x for dir %d\n", ih->init_tag, !dir);
+                       ct->proto.sctp.vtag[!dir] = ih->init_tag;
+                       /* don't renew timeout on init retransmit so
+@@ -494,6 +499,24 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,
+                           old_state == SCTP_CONNTRACK_CLOSED &&
+                           nf_ct_is_confirmed(ct))
+                               ignore = true;
++              } else if (sch->type == SCTP_CID_INIT_ACK) {
++                      struct sctp_inithdr _ih, *ih;
++                      __be32 vtag;
++
++                      ih = skb_header_pointer(skb, offset + sizeof(_sch), sizeof(*ih), &_ih);
++                      if (!ih)
++                              goto out_unlock;
++
++                      vtag = ct->proto.sctp.vtag[!dir];
++                      if (!ct->proto.sctp.init[!dir] && vtag && vtag != ih->init_tag)
++                              goto out_unlock;
++                      /* collision */
++                      if (ct->proto.sctp.init[dir] && ct->proto.sctp.init[!dir] &&
++                          vtag != ih->init_tag)
++                              goto out_unlock;
++
++                      pr_debug("Setting vtag %x for dir %d\n", ih->init_tag, !dir);
++                      ct->proto.sctp.vtag[!dir] = ih->init_tag;
+               }
+               ct->proto.sctp.state = new_state;
+-- 
+2.40.1
+
diff --git a/queue-6.1/netfilter-nf_tables-deduplicate-nft_register_obj-aud.patch b/queue-6.1/netfilter-nf_tables-deduplicate-nft_register_obj-aud.patch
new file mode 100644 (file)
index 0000000..2c0c1d5
--- /dev/null
@@ -0,0 +1,130 @@
+From 18649677d56eedac0a6ff0a613021184fb121338 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Sep 2023 03:53:50 +0200
+Subject: netfilter: nf_tables: Deduplicate nft_register_obj audit logs
+
+From: Phil Sutter <phil@nwl.cc>
+
+[ Upstream commit 0d880dc6f032e0b541520e9926f398a77d3d433c ]
+
+When adding/updating an object, the transaction handler emits suitable
+audit log entries already, the one in nft_obj_notify() is redundant. To
+fix that (and retain the audit logging from objects' 'update' callback),
+Introduce an "audit log free" variant for internal use.
+
+Fixes: c520292f29b8 ("audit: log nftables configuration change events once per table")
+Signed-off-by: Phil Sutter <phil@nwl.cc>
+Reviewed-by: Richard Guy Briggs <rgb@redhat.com>
+Acked-by: Paul Moore <paul@paul-moore.com> (Audit)
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c                 | 44 ++++++++++++-------
+ .../testing/selftests/netfilter/nft_audit.sh  | 20 +++++++++
+ 2 files changed, 48 insertions(+), 16 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 52b81dc1fcf5b..5e3dbe2652dbd 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -7576,24 +7576,14 @@ static int nf_tables_delobj(struct sk_buff *skb, const struct nfnl_info *info,
+       return nft_delobj(&ctx, obj);
+ }
+-void nft_obj_notify(struct net *net, const struct nft_table *table,
+-                  struct nft_object *obj, u32 portid, u32 seq, int event,
+-                  u16 flags, int family, int report, gfp_t gfp)
++static void
++__nft_obj_notify(struct net *net, const struct nft_table *table,
++               struct nft_object *obj, u32 portid, u32 seq, int event,
++               u16 flags, int family, int report, gfp_t gfp)
+ {
+       struct nftables_pernet *nft_net = nft_pernet(net);
+       struct sk_buff *skb;
+       int err;
+-      char *buf = kasprintf(gfp, "%s:%u",
+-                            table->name, nft_net->base_seq);
+-
+-      audit_log_nfcfg(buf,
+-                      family,
+-                      obj->handle,
+-                      event == NFT_MSG_NEWOBJ ?
+-                               AUDIT_NFT_OP_OBJ_REGISTER :
+-                               AUDIT_NFT_OP_OBJ_UNREGISTER,
+-                      gfp);
+-      kfree(buf);
+       if (!report &&
+           !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
+@@ -7616,13 +7606,35 @@ void nft_obj_notify(struct net *net, const struct nft_table *table,
+ err:
+       nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
+ }
++
++void nft_obj_notify(struct net *net, const struct nft_table *table,
++                  struct nft_object *obj, u32 portid, u32 seq, int event,
++                  u16 flags, int family, int report, gfp_t gfp)
++{
++      struct nftables_pernet *nft_net = nft_pernet(net);
++      char *buf = kasprintf(gfp, "%s:%u",
++                            table->name, nft_net->base_seq);
++
++      audit_log_nfcfg(buf,
++                      family,
++                      obj->handle,
++                      event == NFT_MSG_NEWOBJ ?
++                               AUDIT_NFT_OP_OBJ_REGISTER :
++                               AUDIT_NFT_OP_OBJ_UNREGISTER,
++                      gfp);
++      kfree(buf);
++
++      __nft_obj_notify(net, table, obj, portid, seq, event,
++                       flags, family, report, gfp);
++}
+ EXPORT_SYMBOL_GPL(nft_obj_notify);
+ static void nf_tables_obj_notify(const struct nft_ctx *ctx,
+                                struct nft_object *obj, int event)
+ {
+-      nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event,
+-                     ctx->flags, ctx->family, ctx->report, GFP_KERNEL);
++      __nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid,
++                       ctx->seq, event, ctx->flags, ctx->family,
++                       ctx->report, GFP_KERNEL);
+ }
+ /*
+diff --git a/tools/testing/selftests/netfilter/nft_audit.sh b/tools/testing/selftests/netfilter/nft_audit.sh
+index 0b3255e7b3538..bb34329e02a7f 100755
+--- a/tools/testing/selftests/netfilter/nft_audit.sh
++++ b/tools/testing/selftests/netfilter/nft_audit.sh
+@@ -85,6 +85,26 @@ do_test "nft add set t1 s2 $setblock; add set t1 s3 { $settype; }" \
+ do_test "nft add element t1 s3 $setelem" \
+ "table=t1 family=2 entries=3 op=nft_register_setelem"
++# adding counters
++
++do_test 'nft add counter t1 c1' \
++'table=t1 family=2 entries=1 op=nft_register_obj'
++
++do_test 'nft add counter t2 c1; add counter t2 c2' \
++'table=t2 family=2 entries=2 op=nft_register_obj'
++
++# adding/updating quotas
++
++do_test 'nft add quota t1 q1 { 10 bytes }' \
++'table=t1 family=2 entries=1 op=nft_register_obj'
++
++do_test 'nft add quota t2 q1 { 10 bytes }; add quota t2 q2 { 10 bytes }' \
++'table=t2 family=2 entries=2 op=nft_register_obj'
++
++# changing the quota value triggers obj update path
++do_test 'nft add quota t1 q1 { 20 bytes }' \
++'table=t1 family=2 entries=1 op=nft_register_obj'
++
+ # resetting rules
+ do_test 'nft reset rules t1 c2' \
+-- 
+2.40.1
+
diff --git a/queue-6.1/netfilter-nf_tables-nft_set_rbtree-fix-spurious-inse.patch b/queue-6.1/netfilter-nf_tables-nft_set_rbtree-fix-spurious-inse.patch
new file mode 100644 (file)
index 0000000..4dea526
--- /dev/null
@@ -0,0 +1,181 @@
+From 57cb886580900aa6b0868338d4bb75abcd81cd51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Sep 2023 15:12:44 +0200
+Subject: netfilter: nf_tables: nft_set_rbtree: fix spurious insertion failure
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 087388278e0f301f4c61ddffb1911d3a180f84b8 ]
+
+nft_rbtree_gc_elem() walks back and removes the end interval element that
+comes before the expired element.
+
+There is a small chance that we've cached this element as 'rbe_ge'.
+If this happens, we hold and test a pointer that has been queued for
+freeing.
+
+It also causes spurious insertion failures:
+
+$ cat test-testcases-sets-0044interval_overlap_0.1/testout.log
+Error: Could not process rule: File exists
+add element t s {  0 -  2 }
+                   ^^^^^^
+Failed to insert  0 -  2 given:
+table ip t {
+        set s {
+                type inet_service
+                flags interval,timeout
+                timeout 2s
+                gc-interval 2s
+        }
+}
+
+The set (rbtree) is empty. The 'failure' doesn't happen on next attempt.
+
+Reason is that when we try to insert, the tree may hold an expired
+element that collides with the range we're adding.
+While we do evict/erase this element, we can trip over this check:
+
+if (rbe_ge && nft_rbtree_interval_end(rbe_ge) && nft_rbtree_interval_end(new))
+      return -ENOTEMPTY;
+
+rbe_ge was erased by the synchronous gc, we should not have done this
+check.  Next attempt won't find it, so retry results in successful
+insertion.
+
+Restart in-kernel to avoid such spurious errors.
+
+Such restart are rare, unless userspace intentionally adds very large
+numbers of elements with very short timeouts while setting a huge
+gc interval.
+
+Even in this case, this cannot loop forever, on each retry an existing
+element has been removed.
+
+As the caller is holding the transaction mutex, its impossible
+for a second entity to add more expiring elements to the tree.
+
+After this it also becomes feasible to remove the async gc worker
+and perform all garbage collection from the commit path.
+
+Fixes: c9e6978e2725 ("netfilter: nft_set_rbtree: Switch to node list walk for overlap detection")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_set_rbtree.c | 46 +++++++++++++++++++++-------------
+ 1 file changed, 29 insertions(+), 17 deletions(-)
+
+diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c
+index 487572dcd6144..2660ceab3759d 100644
+--- a/net/netfilter/nft_set_rbtree.c
++++ b/net/netfilter/nft_set_rbtree.c
+@@ -233,10 +233,9 @@ static void nft_rbtree_gc_remove(struct net *net, struct nft_set *set,
+       rb_erase(&rbe->node, &priv->root);
+ }
+-static int nft_rbtree_gc_elem(const struct nft_set *__set,
+-                            struct nft_rbtree *priv,
+-                            struct nft_rbtree_elem *rbe,
+-                            u8 genmask)
++static const struct nft_rbtree_elem *
++nft_rbtree_gc_elem(const struct nft_set *__set, struct nft_rbtree *priv,
++                 struct nft_rbtree_elem *rbe, u8 genmask)
+ {
+       struct nft_set *set = (struct nft_set *)__set;
+       struct rb_node *prev = rb_prev(&rbe->node);
+@@ -246,7 +245,7 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set,
+       gc = nft_trans_gc_alloc(set, 0, GFP_ATOMIC);
+       if (!gc)
+-              return -ENOMEM;
++              return ERR_PTR(-ENOMEM);
+       /* search for end interval coming before this element.
+        * end intervals don't carry a timeout extension, they
+@@ -261,6 +260,7 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set,
+               prev = rb_prev(prev);
+       }
++      rbe_prev = NULL;
+       if (prev) {
+               rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node);
+               nft_rbtree_gc_remove(net, set, priv, rbe_prev);
+@@ -272,7 +272,7 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set,
+                */
+               gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
+               if (WARN_ON_ONCE(!gc))
+-                      return -ENOMEM;
++                      return ERR_PTR(-ENOMEM);
+               nft_trans_gc_elem_add(gc, rbe_prev);
+       }
+@@ -280,13 +280,13 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set,
+       nft_rbtree_gc_remove(net, set, priv, rbe);
+       gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
+       if (WARN_ON_ONCE(!gc))
+-              return -ENOMEM;
++              return ERR_PTR(-ENOMEM);
+       nft_trans_gc_elem_add(gc, rbe);
+       nft_trans_gc_queue_sync_done(gc);
+-      return 0;
++      return rbe_prev;
+ }
+ static bool nft_rbtree_update_first(const struct nft_set *set,
+@@ -314,7 +314,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
+       struct nft_rbtree *priv = nft_set_priv(set);
+       u8 cur_genmask = nft_genmask_cur(net);
+       u8 genmask = nft_genmask_next(net);
+-      int d, err;
++      int d;
+       /* Descend the tree to search for an existing element greater than the
+        * key value to insert that is greater than the new element. This is the
+@@ -363,9 +363,14 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
+                */
+               if (nft_set_elem_expired(&rbe->ext) &&
+                   nft_set_elem_active(&rbe->ext, cur_genmask)) {
+-                      err = nft_rbtree_gc_elem(set, priv, rbe, genmask);
+-                      if (err < 0)
+-                              return err;
++                      const struct nft_rbtree_elem *removed_end;
++
++                      removed_end = nft_rbtree_gc_elem(set, priv, rbe, genmask);
++                      if (IS_ERR(removed_end))
++                              return PTR_ERR(removed_end);
++
++                      if (removed_end == rbe_le || removed_end == rbe_ge)
++                              return -EAGAIN;
+                       continue;
+               }
+@@ -486,11 +491,18 @@ static int nft_rbtree_insert(const struct net *net, const struct nft_set *set,
+       struct nft_rbtree_elem *rbe = elem->priv;
+       int err;
+-      write_lock_bh(&priv->lock);
+-      write_seqcount_begin(&priv->count);
+-      err = __nft_rbtree_insert(net, set, rbe, ext);
+-      write_seqcount_end(&priv->count);
+-      write_unlock_bh(&priv->lock);
++      do {
++              if (fatal_signal_pending(current))
++                      return -EINTR;
++
++              cond_resched();
++
++              write_lock_bh(&priv->lock);
++              write_seqcount_begin(&priv->count);
++              err = __nft_rbtree_insert(net, set, rbe, ext);
++              write_seqcount_end(&priv->count);
++              write_unlock_bh(&priv->lock);
++      } while (err == -EAGAIN);
+       return err;
+ }
+-- 
+2.40.1
+
diff --git a/queue-6.1/netlink-annotate-data-races-around-sk-sk_err.patch b/queue-6.1/netlink-annotate-data-races-around-sk-sk_err.patch
new file mode 100644 (file)
index 0000000..3da415c
--- /dev/null
@@ -0,0 +1,100 @@
+From ccc9fcf0536a18f4679be52a36b25bb85466f5db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Oct 2023 18:34:55 +0000
+Subject: netlink: annotate data-races around sk->sk_err
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit d0f95894fda7d4f895b29c1097f92d7fee278cb2 ]
+
+syzbot caught another data-race in netlink when
+setting sk->sk_err.
+
+Annotate all of them for good measure.
+
+BUG: KCSAN: data-race in netlink_recvmsg / netlink_recvmsg
+
+write to 0xffff8881613bb220 of 4 bytes by task 28147 on cpu 0:
+netlink_recvmsg+0x448/0x780 net/netlink/af_netlink.c:1994
+sock_recvmsg_nosec net/socket.c:1027 [inline]
+sock_recvmsg net/socket.c:1049 [inline]
+__sys_recvfrom+0x1f4/0x2e0 net/socket.c:2229
+__do_sys_recvfrom net/socket.c:2247 [inline]
+__se_sys_recvfrom net/socket.c:2243 [inline]
+__x64_sys_recvfrom+0x78/0x90 net/socket.c:2243
+do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
+entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+write to 0xffff8881613bb220 of 4 bytes by task 28146 on cpu 1:
+netlink_recvmsg+0x448/0x780 net/netlink/af_netlink.c:1994
+sock_recvmsg_nosec net/socket.c:1027 [inline]
+sock_recvmsg net/socket.c:1049 [inline]
+__sys_recvfrom+0x1f4/0x2e0 net/socket.c:2229
+__do_sys_recvfrom net/socket.c:2247 [inline]
+__se_sys_recvfrom net/socket.c:2243 [inline]
+__x64_sys_recvfrom+0x78/0x90 net/socket.c:2243
+do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
+entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+value changed: 0x00000000 -> 0x00000016
+
+Reported by Kernel Concurrency Sanitizer on:
+CPU: 1 PID: 28146 Comm: syz-executor.0 Not tainted 6.6.0-rc3-syzkaller-00055-g9ed22ae6be81 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/06/2023
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20231003183455.3410550-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 845ac56a3ac2e..a572a30dfd98d 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -352,7 +352,7 @@ static void netlink_overrun(struct sock *sk)
+       if (!nlk_test_bit(RECV_NO_ENOBUFS, sk)) {
+               if (!test_and_set_bit(NETLINK_S_CONGESTED,
+                                     &nlk_sk(sk)->state)) {
+-                      sk->sk_err = ENOBUFS;
++                      WRITE_ONCE(sk->sk_err, ENOBUFS);
+                       sk_error_report(sk);
+               }
+       }
+@@ -1566,7 +1566,7 @@ static int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p)
+               goto out;
+       }
+-      sk->sk_err = p->code;
++      WRITE_ONCE(sk->sk_err, p->code);
+       sk_error_report(sk);
+ out:
+       return ret;
+@@ -1955,7 +1955,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+           atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
+               ret = netlink_dump(sk);
+               if (ret) {
+-                      sk->sk_err = -ret;
++                      WRITE_ONCE(sk->sk_err, -ret);
+                       sk_error_report(sk);
+               }
+       }
+@@ -2474,7 +2474,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
+ err_bad_put:
+       nlmsg_free(skb);
+ err_skb:
+-      NETLINK_CB(in_skb).sk->sk_err = ENOBUFS;
++      WRITE_ONCE(NETLINK_CB(in_skb).sk->sk_err, ENOBUFS);
+       sk_error_report(NETLINK_CB(in_skb).sk);
+ }
+ EXPORT_SYMBOL(netlink_ack);
+-- 
+2.40.1
+
diff --git a/queue-6.1/netlink-fix-potential-skb-memleak-in-netlink_ack.patch b/queue-6.1/netlink-fix-potential-skb-memleak-in-netlink_ack.patch
new file mode 100644 (file)
index 0000000..04d4bd0
--- /dev/null
@@ -0,0 +1,48 @@
+From d5d1c6bac9529e2e1b91f9a603e2a0cffe6dca9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Nov 2022 17:05:04 +0800
+Subject: netlink: Fix potential skb memleak in netlink_ack
+
+From: Tao Chen <chentao.kernel@linux.alibaba.com>
+
+[ Upstream commit e69761483361f3df455bc493c99af0ef1744a14f ]
+
+Fix coverity issue 'Resource leak'.
+
+We should clean the skb resource if nlmsg_put/append failed.
+
+Fixes: 738136a0e375 ("netlink: split up copies in the ack construction")
+Signed-off-by: Tao Chen <chentao.kernel@linux.alibaba.com>
+Link: https://lore.kernel.org/r/bff442d62c87de6299817fe1897cc5a5694ba9cc.1667638204.git.chentao.kernel@linux.alibaba.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: d0f95894fda7 ("netlink: annotate data-races around sk->sk_err")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 4ddb2ed7706ad..845ac56a3ac2e 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -2444,7 +2444,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
+       skb = nlmsg_new(payload + tlvlen, GFP_KERNEL);
+       if (!skb)
+-              goto err_bad_put;
++              goto err_skb;
+       rep = nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
+                       NLMSG_ERROR, sizeof(*errmsg), flags);
+@@ -2472,6 +2472,8 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
+       return;
+ err_bad_put:
++      nlmsg_free(skb);
++err_skb:
+       NETLINK_CB(in_skb).sk->sk_err = ENOBUFS;
+       sk_error_report(NETLINK_CB(in_skb).sk);
+ }
+-- 
+2.40.1
+
diff --git a/queue-6.1/netlink-split-up-copies-in-the-ack-construction.patch b/queue-6.1/netlink-split-up-copies-in-the-ack-construction.patch
new file mode 100644 (file)
index 0000000..77de6ea
--- /dev/null
@@ -0,0 +1,130 @@
+From 1cb9bb4256b0bf587b446892e84c28a13c146fd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Oct 2022 14:25:53 -0700
+Subject: netlink: split up copies in the ack construction
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 738136a0e3757a8534df3ad97d6ff6d7f429f6c1 ]
+
+Clean up the use of unsafe_memcpy() by adding a flexible array
+at the end of netlink message header and splitting up the header
+and data copies.
+
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: d0f95894fda7 ("netlink: annotate data-races around sk->sk_err")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netlink.h        | 21 +++++++++++++++++++++
+ include/uapi/linux/netlink.h |  2 ++
+ net/netlink/af_netlink.c     | 29 ++++++++++++++++++++---------
+ 3 files changed, 43 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/netlink.h b/include/net/netlink.h
+index 6bfa972f2fbf2..a686c9041ddc0 100644
+--- a/include/net/netlink.h
++++ b/include/net/netlink.h
+@@ -937,6 +937,27 @@ static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 portid, u32 se
+       return __nlmsg_put(skb, portid, seq, type, payload, flags);
+ }
++/**
++ * nlmsg_append - Add more data to a nlmsg in a skb
++ * @skb: socket buffer to store message in
++ * @size: length of message payload
++ *
++ * Append data to an existing nlmsg, used when constructing a message
++ * with multiple fixed-format headers (which is rare).
++ * Returns NULL if the tailroom of the skb is insufficient to store
++ * the extra payload.
++ */
++static inline void *nlmsg_append(struct sk_buff *skb, u32 size)
++{
++      if (unlikely(skb_tailroom(skb) < NLMSG_ALIGN(size)))
++              return NULL;
++
++      if (NLMSG_ALIGN(size) - size)
++              memset(skb_tail_pointer(skb) + size, 0,
++                     NLMSG_ALIGN(size) - size);
++      return __skb_put(skb, NLMSG_ALIGN(size));
++}
++
+ /**
+  * nlmsg_put_answer - Add a new callback based netlink message to an skb
+  * @skb: socket buffer to store message in
+diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
+index e2ae82e3f9f71..5da0da59bf010 100644
+--- a/include/uapi/linux/netlink.h
++++ b/include/uapi/linux/netlink.h
+@@ -48,6 +48,7 @@ struct sockaddr_nl {
+  * @nlmsg_flags: Additional flags
+  * @nlmsg_seq:   Sequence number
+  * @nlmsg_pid:   Sending process port ID
++ * @nlmsg_data:  Message payload
+  */
+ struct nlmsghdr {
+       __u32           nlmsg_len;
+@@ -55,6 +56,7 @@ struct nlmsghdr {
+       __u16           nlmsg_flags;
+       __u32           nlmsg_seq;
+       __u32           nlmsg_pid;
++      __u8            nlmsg_data[];
+ };
+ /* Flags values */
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 387e430a35ccc..4ddb2ed7706ad 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -2443,19 +2443,24 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
+               flags |= NLM_F_ACK_TLVS;
+       skb = nlmsg_new(payload + tlvlen, GFP_KERNEL);
+-      if (!skb) {
+-              NETLINK_CB(in_skb).sk->sk_err = ENOBUFS;
+-              sk_error_report(NETLINK_CB(in_skb).sk);
+-              return;
+-      }
++      if (!skb)
++              goto err_bad_put;
+       rep = nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
+-                      NLMSG_ERROR, payload, flags);
++                      NLMSG_ERROR, sizeof(*errmsg), flags);
++      if (!rep)
++              goto err_bad_put;
+       errmsg = nlmsg_data(rep);
+       errmsg->error = err;
+-      unsafe_memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg)
+-                                       ? nlh->nlmsg_len : sizeof(*nlh),
+-                    /* Bounds checked by the skb layer. */);
++      errmsg->msg = *nlh;
++
++      if (!(flags & NLM_F_CAPPED)) {
++              if (!nlmsg_append(skb, nlmsg_len(nlh)))
++                      goto err_bad_put;
++
++              memcpy(errmsg->msg.nlmsg_data, nlh->nlmsg_data,
++                     nlmsg_len(nlh));
++      }
+       if (tlvlen)
+               netlink_ack_tlv_fill(in_skb, skb, nlh, err, extack);
+@@ -2463,6 +2468,12 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
+       nlmsg_end(skb, rep);
+       nlmsg_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid);
++
++      return;
++
++err_bad_put:
++      NETLINK_CB(in_skb).sk->sk_err = ENOBUFS;
++      sk_error_report(NETLINK_CB(in_skb).sk);
+ }
+ EXPORT_SYMBOL(netlink_ack);
+-- 
+2.40.1
+
diff --git a/queue-6.1/nfsv4-fix-a-nfs4_state_manager-race.patch b/queue-6.1/nfsv4-fix-a-nfs4_state_manager-race.patch
new file mode 100644 (file)
index 0000000..9896deb
--- /dev/null
@@ -0,0 +1,43 @@
+From 23966503daa327e529f021824c9298797d367878 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Sep 2023 19:05:50 -0400
+Subject: NFSv4: Fix a nfs4_state_manager() race
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit ed1cc05aa1f7fe8197d300e914afc28ab9818f89 ]
+
+If the NFS4CLNT_RUN_MANAGER flag got set just before we cleared
+NFS4CLNT_MANAGER_RUNNING, then we might have won the race against
+nfs4_schedule_state_manager(), and are responsible for handling the
+recovery situation.
+
+Fixes: aeabb3c96186 ("NFSv4: Fix a NFSv4 state manager deadlock")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4state.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
+index ed789e0cb9431..457b2b2f804ab 100644
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -2710,6 +2710,13 @@ static void nfs4_state_manager(struct nfs_client *clp)
+               nfs4_end_drain_session(clp);
+               nfs4_clear_state_manager_bit(clp);
++              if (test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) &&
++                  !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING,
++                                    &clp->cl_state)) {
++                      memflags = memalloc_nofs_save();
++                      continue;
++              }
++
+               if (!test_and_set_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state)) {
+                       if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) {
+                               nfs_client_return_marked_delegations(clp);
+-- 
+2.40.1
+
diff --git a/queue-6.1/perf-x86-amd-core-fix-overflow-reset-on-hotplug.patch b/queue-6.1/perf-x86-amd-core-fix-overflow-reset-on-hotplug.patch
new file mode 100644 (file)
index 0000000..29722b4
--- /dev/null
@@ -0,0 +1,90 @@
+From c33f0a52e0ec88cb3a7af0802916a639511ff964 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Sep 2023 19:36:04 +0530
+Subject: perf/x86/amd/core: Fix overflow reset on hotplug
+
+From: Sandipan Das <sandipan.das@amd.com>
+
+[ Upstream commit 23d2626b841c2adccdeb477665313c02dff02dc3 ]
+
+Kernels older than v5.19 do not support PerfMonV2 and the PMI handler
+does not clear the overflow bits of the PerfCntrGlobalStatus register.
+Because of this, loading a recent kernel using kexec from an older
+kernel can result in inconsistent register states on Zen 4 systems.
+
+The PMI handler of the new kernel gets confused and shows a warning when
+an overflow occurs because some of the overflow bits are set even if the
+corresponding counters are inactive. These are remnants from overflows
+that were handled by the older kernel.
+
+During CPU hotplug, the PerfCntrGlobalCtl and PerfCntrGlobalStatus
+registers should always be cleared for PerfMonV2-capable processors.
+However, a condition used for NB event constaints applicable only to
+older processors currently prevents this from happening. Move the reset
+sequence to an appropriate place and also clear the LBR Freeze bit.
+
+Fixes: 21d59e3e2c40 ("perf/x86/amd/core: Detect PerfMonV2 support")
+Signed-off-by: Sandipan Das <sandipan.das@amd.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/882a87511af40792ba69bb0e9026f19a2e71e8a3.1694696888.git.sandipan.das@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/amd/core.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
+index 6672a3f05fc68..bb9d99b45a459 100644
+--- a/arch/x86/events/amd/core.c
++++ b/arch/x86/events/amd/core.c
+@@ -534,8 +534,12 @@ static void amd_pmu_cpu_reset(int cpu)
+       /* Clear enable bits i.e. PerfCntrGlobalCtl.PerfCntrEn */
+       wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, 0);
+-      /* Clear overflow bits i.e. PerfCntrGLobalStatus.PerfCntrOvfl */
+-      wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, amd_pmu_global_cntr_mask);
++      /*
++       * Clear freeze and overflow bits i.e. PerfCntrGLobalStatus.LbrFreeze
++       * and PerfCntrGLobalStatus.PerfCntrOvfl
++       */
++      wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR,
++             GLOBAL_STATUS_LBRS_FROZEN | amd_pmu_global_cntr_mask);
+ }
+ static int amd_pmu_cpu_prepare(int cpu)
+@@ -570,6 +574,7 @@ static void amd_pmu_cpu_starting(int cpu)
+       int i, nb_id;
+       cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY;
++      amd_pmu_cpu_reset(cpu);
+       if (!x86_pmu.amd_nb_constraints)
+               return;
+@@ -591,8 +596,6 @@ static void amd_pmu_cpu_starting(int cpu)
+       cpuc->amd_nb->nb_id = nb_id;
+       cpuc->amd_nb->refcnt++;
+-
+-      amd_pmu_cpu_reset(cpu);
+ }
+ static void amd_pmu_cpu_dead(int cpu)
+@@ -601,6 +604,7 @@ static void amd_pmu_cpu_dead(int cpu)
+       kfree(cpuhw->lbr_sel);
+       cpuhw->lbr_sel = NULL;
++      amd_pmu_cpu_reset(cpu);
+       if (!x86_pmu.amd_nb_constraints)
+               return;
+@@ -613,8 +617,6 @@ static void amd_pmu_cpu_dead(int cpu)
+               cpuhw->amd_nb = NULL;
+       }
+-
+-      amd_pmu_cpu_reset(cpu);
+ }
+ static inline void amd_pmu_set_global_ctl(u64 ctl)
+-- 
+2.40.1
+
diff --git a/queue-6.1/perf-x86-amd-do-not-warn-on-every-irq.patch b/queue-6.1/perf-x86-amd-do-not-warn-on-every-irq.patch
new file mode 100644 (file)
index 0000000..2174277
--- /dev/null
@@ -0,0 +1,87 @@
+From 232df8a9560dbc4f1565bd8e80f88dd6b8b6f68a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Sep 2023 19:58:40 +0530
+Subject: perf/x86/amd: Do not WARN() on every IRQ
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 599522d9d2e19d6240e4312577f1c5f3ffca22f6 ]
+
+Zen 4 systems running buggy microcode can hit a WARN_ON() in the PMI
+handler, as shown below, several times while perf runs. A simple
+`perf top` run is enough to render the system unusable:
+
+  WARNING: CPU: 18 PID: 20608 at arch/x86/events/amd/core.c:944 amd_pmu_v2_handle_irq+0x1be/0x2b0
+
+This happens because the Performance Counter Global Status Register
+(PerfCntGlobalStatus) has one or more bits set which are considered
+reserved according to the "AMD64 Architecture Programmer’s Manual,
+Volume 2: System Programming, 24593":
+
+  https://www.amd.com/system/files/TechDocs/24593.pdf
+
+To make this less intrusive, warn just once if any reserved bit is set
+and prompt the user to update the microcode. Also sanitize the value to
+what the code is handling, so that the overflow events continue to be
+handled for the number of counters that are known to be sane.
+
+Going forward, the following microcode patch levels are recommended
+for Zen 4 processors in order to avoid such issues with reserved bits:
+
+  Family=0x19 Model=0x11 Stepping=0x01: Patch=0x0a10113e
+  Family=0x19 Model=0x11 Stepping=0x02: Patch=0x0a10123e
+  Family=0x19 Model=0xa0 Stepping=0x01: Patch=0x0aa00116
+  Family=0x19 Model=0xa0 Stepping=0x02: Patch=0x0aa00212
+
+Commit f2eb058afc57 ("linux-firmware: Update AMD cpu microcode") from
+the linux-firmware tree has binaries that meet the minimum required
+patch levels.
+
+  [ sandipan: - add message to prompt users to update microcode
+              - rework commit message and call out required microcode levels ]
+
+Fixes: 7685665c390d ("perf/x86/amd/core: Add PerfMonV2 overflow handling")
+Reported-by: Jirka Hladky <jhladky@redhat.com>
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Signed-off-by: Sandipan Das <sandipan.das@amd.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/all/3540f985652f41041e54ee82aa53e7dbd55739ae.1694696888.git.sandipan.das@amd.com/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/amd/core.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
+index bb9d99b45a459..04f4b96dec6df 100644
+--- a/arch/x86/events/amd/core.c
++++ b/arch/x86/events/amd/core.c
+@@ -886,7 +886,7 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs)
+       struct hw_perf_event *hwc;
+       struct perf_event *event;
+       int handled = 0, idx;
+-      u64 status, mask;
++      u64 reserved, status, mask;
+       bool pmu_enabled;
+       /*
+@@ -911,6 +911,14 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs)
+               status &= ~GLOBAL_STATUS_LBRS_FROZEN;
+       }
++      reserved = status & ~amd_pmu_global_cntr_mask;
++      if (reserved)
++              pr_warn_once("Reserved PerfCntrGlobalStatus bits are set (0x%llx), please consider updating microcode\n",
++                           reserved);
++
++      /* Clear any reserved bits set by buggy microcode */
++      status &= amd_pmu_global_cntr_mask;
++
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+               if (!test_bit(idx, cpuc->active_mask))
+                       continue;
+-- 
+2.40.1
+
diff --git a/queue-6.1/ptp-ocp-fix-error-handling-in-ptp_ocp_device_init.patch b/queue-6.1/ptp-ocp-fix-error-handling-in-ptp_ocp_device_init.patch
new file mode 100644 (file)
index 0000000..8852295
--- /dev/null
@@ -0,0 +1,37 @@
+From f1ad194004ef811c7a6d50456334178a48a7cabd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Sep 2023 17:40:44 +0800
+Subject: ptp: ocp: Fix error handling in ptp_ocp_device_init
+
+From: Dinghao Liu <dinghao.liu@zju.edu.cn>
+
+[ Upstream commit caa0578c1d487d39e4bb947a1b4965417053b409 ]
+
+When device_add() fails, ptp_ocp_dev_release() will be called
+after put_device(). Therefore, it seems that the
+ptp_ocp_dev_release() before put_device() is redundant.
+
+Fixes: 773bda964921 ("ptp: ocp: Expose various resources on the timecard.")
+Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
+Reviewed-by: Vadim Feodrenko <vadim.fedorenko@linux.dev>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_ocp.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
+index a48d9b7d29217..8fee9b330b613 100644
+--- a/drivers/ptp/ptp_ocp.c
++++ b/drivers/ptp/ptp_ocp.c
+@@ -3532,7 +3532,6 @@ ptp_ocp_device_init(struct ptp_ocp *bp, struct pci_dev *pdev)
+       return 0;
+ out:
+-      ptp_ocp_dev_release(&bp->dev);
+       put_device(&bp->dev);
+       return err;
+ }
+-- 
+2.40.1
+
diff --git a/queue-6.1/regmap-rbtree-fix-wrong-register-marked-as-in-cache-.patch b/queue-6.1/regmap-rbtree-fix-wrong-register-marked-as-in-cache-.patch
new file mode 100644 (file)
index 0000000..b6a0548
--- /dev/null
@@ -0,0 +1,50 @@
+From cc7b68a4727c8dac77853769296be0d800352eb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Sep 2023 16:37:11 +0100
+Subject: regmap: rbtree: Fix wrong register marked as in-cache when creating
+ new node
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 7a795ac8d49e2433e1b97caf5e99129daf8e1b08 ]
+
+When regcache_rbtree_write() creates a new rbtree_node it was passing the
+wrong bit number to regcache_rbtree_set_register(). The bit number is the
+offset __in number of registers__, but in the case of creating a new block
+regcache_rbtree_write() was not dividing by the address stride to get the
+number of registers.
+
+Fix this by dividing by map->reg_stride.
+Compare with regcache_rbtree_read() where the bit is checked.
+
+This bug meant that the wrong register was marked as present. The register
+that was written to the cache could not be read from the cache because it
+was not marked as cached. But a nearby register could be marked as having
+a cached value even if it was never written to the cache.
+
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Fixes: 3f4ff561bc88 ("regmap: rbtree: Make cache_present bitmap per node")
+Link: https://lore.kernel.org/r/20230922153711.28103-1-rf@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/regmap/regcache-rbtree.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
+index ae6b8788d5f3f..d65715b9e129e 100644
+--- a/drivers/base/regmap/regcache-rbtree.c
++++ b/drivers/base/regmap/regcache-rbtree.c
+@@ -453,7 +453,8 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
+               if (!rbnode)
+                       return -ENOMEM;
+               regcache_rbtree_set_register(map, rbnode,
+-                                           reg - rbnode->base_reg, value);
++                                           (reg - rbnode->base_reg) / map->reg_stride,
++                                           value);
+               regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode);
+               rbtree_ctx->cached_rbnode = rbnode;
+       }
+-- 
+2.40.1
+
diff --git a/queue-6.1/regulator-core-regulator_register-set-device-class-e.patch b/queue-6.1/regulator-core-regulator_register-set-device-class-e.patch
new file mode 100644 (file)
index 0000000..b96f8a9
--- /dev/null
@@ -0,0 +1,60 @@
+From f5d426eddc1200d63ac70c42948c1bc1c971ee52 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Sep 2023 00:50:26 +0200
+Subject: regulator/core: regulator_register: set device->class earlier
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: MichaÅ‚ MirosÅ‚aw <mirq-linux@rere.qmqm.pl>
+
+[ Upstream commit 8adb4e647a83cb5928c05dae95b010224aea0705 ]
+
+When fixing a memory leak in commit d3c731564e09 ("regulator: plug
+of_node leak in regulator_register()'s error path") it moved the
+device_initialize() call earlier, but did not move the `dev->class`
+initialization.  The bug was spotted and fixed by reverting part of
+the commit (in commit 5f4b204b6b81 "regulator: core: fix kobject
+release warning and memory leak in regulator_register()") but
+introducing a different bug: now early error paths use `kfree(dev)`
+instead of `put_device()` for an already initialized `struct device`.
+
+Move the missing assignments to just after `device_initialize()`.
+
+Fixes: d3c731564e09 ("regulator: plug of_node leak in regulator_register()'s error path")
+Signed-off-by: MichaÅ‚ MirosÅ‚aw <mirq-linux@rere.qmqm.pl>
+Link: https://lore.kernel.org/r/b5b19cb458c40c9d02f3d5a7bd1ba7d97ba17279.1695077303.git.mirq-linux@rere.qmqm.pl
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 351f0fd225b14..f6a95f72af18d 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -5543,6 +5543,8 @@ regulator_register(struct device *dev,
+               goto rinse;
+       }
+       device_initialize(&rdev->dev);
++      dev_set_drvdata(&rdev->dev, rdev);
++      rdev->dev.class = &regulator_class;
+       spin_lock_init(&rdev->err_lock);
+       /*
+@@ -5604,11 +5606,9 @@ regulator_register(struct device *dev,
+               rdev->supply_name = regulator_desc->supply_name;
+       /* register with sysfs */
+-      rdev->dev.class = &regulator_class;
+       rdev->dev.parent = config->dev;
+       dev_set_name(&rdev->dev, "regulator.%lu",
+                   (unsigned long) atomic_inc_return(&regulator_no));
+-      dev_set_drvdata(&rdev->dev, rdev);
+       /* set regulator constraints */
+       if (init_data)
+-- 
+2.40.1
+
diff --git a/queue-6.1/regulator-mt6358-drop-_sshub-regulators.patch b/queue-6.1/regulator-mt6358-drop-_sshub-regulators.patch
new file mode 100644 (file)
index 0000000..ea17ff8
--- /dev/null
@@ -0,0 +1,101 @@
+From fb60a5ee7ebbe3dcf718b81ad54eb654ffd6f355 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 16:30:01 +0800
+Subject: regulator: mt6358: Drop *_SSHUB regulators
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit 04ba665248ed91576d326041108e5fc2ec2254eb ]
+
+The *_SSHUB regulators are actually alternate configuration interfaces
+for their non *_SSHUB counterparts. They are not separate regulator
+outputs. These registers are intended for the companion processor to
+use to configure the power rails while the main processor is sleeping.
+They are not intended for the main operating system to use.
+
+Since they are not real outputs they shouldn't be modeled separately.
+Remove them. Luckily no device tree actually uses them.
+
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Link: https://lore.kernel.org/r/20230609083009.2822259-5-wenst@chromium.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 7e37c851374e ("regulator: mt6358: split ops for buck and linear range LDO regulators")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/mt6358-regulator.c       | 14 --------------
+ include/linux/regulator/mt6358-regulator.h |  4 ----
+ 2 files changed, 18 deletions(-)
+
+diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c
+index 8a5ce990f1bf9..153c1fd5fb0b7 100644
+--- a/drivers/regulator/mt6358-regulator.c
++++ b/drivers/regulator/mt6358-regulator.c
+@@ -505,9 +505,6 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
+       MT6358_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
+                   MT6358_VCORE_VGPU_ANA_CON0, 1),
+-      MT6358_BUCK("buck_vcore_sshub", VCORE_SSHUB, 500000, 1293750, 6250,
+-                  buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_SSHUB_ELR0, 0x7f,
+-                  MT6358_VCORE_VGPU_ANA_CON0, 1),
+       MT6358_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
+                   buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f,
+                   MT6358_VPA_ANA_CON0, 3),
+@@ -587,10 +584,6 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
+       MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00,
+                   MT6358_LDO_VSRAM_CON2, 0x7f),
+-      MT6358_LDO1("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB, 500000,
+-                  1293750, 6250, buck_volt_range1,
+-                  MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f,
+-                  MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f),
+       MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00,
+                   MT6358_LDO_VSRAM_CON3, 0x7f),
+@@ -607,9 +600,6 @@ static struct mt6358_regulator_info mt6366_regulators[] = {
+       MT6366_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
+                   MT6358_VCORE_VGPU_ANA_CON0, 1),
+-      MT6366_BUCK("buck_vcore_sshub", VCORE_SSHUB, 500000, 1293750, 6250,
+-                  buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_SSHUB_ELR0, 0x7f,
+-                  MT6358_VCORE_VGPU_ANA_CON0, 1),
+       MT6366_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
+                   buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f,
+                   MT6358_VPA_ANA_CON0, 3),
+@@ -678,10 +668,6 @@ static struct mt6358_regulator_info mt6366_regulators[] = {
+       MT6366_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00,
+                   MT6358_LDO_VSRAM_CON2, 0x7f),
+-      MT6366_LDO1("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB, 500000,
+-                  1293750, 6250, buck_volt_range1,
+-                  MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f,
+-                  MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f),
+       MT6366_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00,
+                   MT6358_LDO_VSRAM_CON3, 0x7f),
+diff --git a/include/linux/regulator/mt6358-regulator.h b/include/linux/regulator/mt6358-regulator.h
+index bdcf83cd719ef..be9f61e3e8e6d 100644
+--- a/include/linux/regulator/mt6358-regulator.h
++++ b/include/linux/regulator/mt6358-regulator.h
+@@ -48,8 +48,6 @@ enum {
+       MT6358_ID_VLDO28,
+       MT6358_ID_VAUD28,
+       MT6358_ID_VSIM2,
+-      MT6358_ID_VCORE_SSHUB,
+-      MT6358_ID_VSRAM_OTHERS_SSHUB,
+       MT6358_ID_RG_MAX,
+ };
+@@ -90,8 +88,6 @@ enum {
+       MT6366_ID_VMC,
+       MT6366_ID_VAUD28,
+       MT6366_ID_VSIM2,
+-      MT6366_ID_VCORE_SSHUB,
+-      MT6366_ID_VSRAM_OTHERS_SSHUB,
+       MT6366_ID_RG_MAX,
+ };
+-- 
+2.40.1
+
diff --git a/queue-6.1/regulator-mt6358-split-ops-for-buck-and-linear-range.patch b/queue-6.1/regulator-mt6358-split-ops-for-buck-and-linear-range.patch
new file mode 100644 (file)
index 0000000..f4800b5
--- /dev/null
@@ -0,0 +1,81 @@
+From 88b3d5388269c18898d3cb454e4c8c2895e90cf4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Sep 2023 16:53:34 +0800
+Subject: regulator: mt6358: split ops for buck and linear range LDO regulators
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit 7e37c851374eca2d1f6128de03195c9f7b4baaf2 ]
+
+The buck and linear range LDO (VSRAM_*) regulators share one set of ops.
+This set includes support for get/set mode. However this only makes
+sense for buck regulators, not LDOs. The callbacks were not checking
+whether the register offset and/or mask for mode setting was valid or
+not. This ends up making the kernel report "normal" mode operation for
+the LDOs.
+
+Create a new set of ops without the get/set mode callbacks for the
+linear range LDO regulators.
+
+Fixes: f67ff1bd58f0 ("regulator: mt6358: Add support for MT6358 regulator")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Link: https://lore.kernel.org/r/20230920085336.136238-1-wenst@chromium.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/mt6358-regulator.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c
+index 56b5fc9f62c94..a0441b8086712 100644
+--- a/drivers/regulator/mt6358-regulator.c
++++ b/drivers/regulator/mt6358-regulator.c
+@@ -41,7 +41,7 @@ struct mt6358_regulator_info {
+       .desc = {       \
+               .name = #vreg,  \
+               .of_match = of_match_ptr(match),        \
+-              .ops = &mt6358_volt_range_ops,  \
++              .ops = &mt6358_buck_ops,        \
+               .type = REGULATOR_VOLTAGE,      \
+               .id = MT6358_ID_##vreg,         \
+               .owner = THIS_MODULE,           \
+@@ -137,7 +137,7 @@ struct mt6358_regulator_info {
+       .desc = {       \
+               .name = #vreg,  \
+               .of_match = of_match_ptr(match),        \
+-              .ops = &mt6358_volt_range_ops,  \
++              .ops = &mt6358_buck_ops,        \
+               .type = REGULATOR_VOLTAGE,      \
+               .id = MT6366_ID_##vreg,         \
+               .owner = THIS_MODULE,           \
+@@ -448,7 +448,7 @@ static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev)
+       }
+ }
+-static const struct regulator_ops mt6358_volt_range_ops = {
++static const struct regulator_ops mt6358_buck_ops = {
+       .list_voltage = regulator_list_voltage_linear,
+       .map_voltage = regulator_map_voltage_linear,
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
+@@ -462,6 +462,18 @@ static const struct regulator_ops mt6358_volt_range_ops = {
+       .get_mode = mt6358_regulator_get_mode,
+ };
++static const struct regulator_ops mt6358_volt_range_ops = {
++      .list_voltage = regulator_list_voltage_linear,
++      .map_voltage = regulator_map_voltage_linear,
++      .set_voltage_sel = regulator_set_voltage_sel_regmap,
++      .get_voltage_sel = mt6358_get_buck_voltage_sel,
++      .set_voltage_time_sel = regulator_set_voltage_time_sel,
++      .enable = regulator_enable_regmap,
++      .disable = regulator_disable_regmap,
++      .is_enabled = regulator_is_enabled_regmap,
++      .get_status = mt6358_get_status,
++};
++
+ static const struct regulator_ops mt6358_volt_table_ops = {
+       .list_voltage = regulator_list_voltage_table,
+       .map_voltage = regulator_map_voltage_iterate,
+-- 
+2.40.1
+
diff --git a/queue-6.1/regulator-mt6358-use-linear-voltage-helpers-for-sing.patch b/queue-6.1/regulator-mt6358-use-linear-voltage-helpers-for-sing.patch
new file mode 100644 (file)
index 0000000..0231176
--- /dev/null
@@ -0,0 +1,274 @@
+From 217ed2bdb9b6c26ffb825646900c277fedfbf7ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 16:30:03 +0800
+Subject: regulator: mt6358: Use linear voltage helpers for single range
+ regulators
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit ea861df772fd8cca715d43f62fe13c09c975f7a2 ]
+
+Some of the regulators on the MT6358/MT6366 PMICs have just one linear
+voltage range. These are the bulk regulators and VSRAM_* LDOs. Currently
+they are modeled with one linear range, but also have their minimum,
+maximum, and step voltage described.
+
+Convert them to the linear voltage helpers. These helpers are a bit
+simpler, and we can also drop the linear range definitions. Also reflow
+the touched lines now that they are shorter.
+
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Link: https://lore.kernel.org/r/20230609083009.2822259-7-wenst@chromium.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 7e37c851374e ("regulator: mt6358: split ops for buck and linear range LDO regulators")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/mt6358-regulator.c | 121 +++++++++------------------
+ 1 file changed, 40 insertions(+), 81 deletions(-)
+
+diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c
+index 153c1fd5fb0b7..56b5fc9f62c94 100644
+--- a/drivers/regulator/mt6358-regulator.c
++++ b/drivers/regulator/mt6358-regulator.c
+@@ -35,7 +35,7 @@ struct mt6358_regulator_info {
+ };
+ #define MT6358_BUCK(match, vreg, min, max, step,              \
+-      volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask,   \
++      vosel_mask, _da_vsel_reg, _da_vsel_mask,        \
+       _modeset_reg, _modeset_shift)           \
+ [MT6358_ID_##vreg] = {        \
+       .desc = {       \
+@@ -46,8 +46,8 @@ struct mt6358_regulator_info {
+               .id = MT6358_ID_##vreg,         \
+               .owner = THIS_MODULE,           \
+               .n_voltages = ((max) - (min)) / (step) + 1,     \
+-              .linear_ranges = volt_ranges,           \
+-              .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
++              .min_uV = (min),                \
++              .uV_step = (step),              \
+               .vsel_reg = MT6358_BUCK_##vreg##_ELR0,  \
+               .vsel_mask = vosel_mask,        \
+               .enable_reg = MT6358_BUCK_##vreg##_CON0,        \
+@@ -87,7 +87,7 @@ struct mt6358_regulator_info {
+ }
+ #define MT6358_LDO1(match, vreg, min, max, step,      \
+-      volt_ranges, _da_vsel_reg, _da_vsel_mask,       \
++      _da_vsel_reg, _da_vsel_mask,    \
+       vosel, vosel_mask)      \
+ [MT6358_ID_##vreg] = {        \
+       .desc = {       \
+@@ -98,8 +98,8 @@ struct mt6358_regulator_info {
+               .id = MT6358_ID_##vreg, \
+               .owner = THIS_MODULE,   \
+               .n_voltages = ((max) - (min)) / (step) + 1,     \
+-              .linear_ranges = volt_ranges,   \
+-              .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
++              .min_uV = (min),                \
++              .uV_step = (step),              \
+               .vsel_reg = vosel,      \
+               .vsel_mask = vosel_mask,        \
+               .enable_reg = MT6358_LDO_##vreg##_CON0, \
+@@ -131,7 +131,7 @@ struct mt6358_regulator_info {
+ }
+ #define MT6366_BUCK(match, vreg, min, max, step,              \
+-      volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask,   \
++      vosel_mask, _da_vsel_reg, _da_vsel_mask,        \
+       _modeset_reg, _modeset_shift)           \
+ [MT6366_ID_##vreg] = {        \
+       .desc = {       \
+@@ -142,8 +142,8 @@ struct mt6358_regulator_info {
+               .id = MT6366_ID_##vreg,         \
+               .owner = THIS_MODULE,           \
+               .n_voltages = ((max) - (min)) / (step) + 1,     \
+-              .linear_ranges = volt_ranges,           \
+-              .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
++              .min_uV = (min),                \
++              .uV_step = (step),              \
+               .vsel_reg = MT6358_BUCK_##vreg##_ELR0,  \
+               .vsel_mask = vosel_mask,        \
+               .enable_reg = MT6358_BUCK_##vreg##_CON0,        \
+@@ -183,7 +183,7 @@ struct mt6358_regulator_info {
+ }
+ #define MT6366_LDO1(match, vreg, min, max, step,      \
+-      volt_ranges, _da_vsel_reg, _da_vsel_mask,       \
++      _da_vsel_reg, _da_vsel_mask,    \
+       vosel, vosel_mask)      \
+ [MT6366_ID_##vreg] = {        \
+       .desc = {       \
+@@ -194,8 +194,8 @@ struct mt6358_regulator_info {
+               .id = MT6366_ID_##vreg, \
+               .owner = THIS_MODULE,   \
+               .n_voltages = ((max) - (min)) / (step) + 1,     \
+-              .linear_ranges = volt_ranges,   \
+-              .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
++              .min_uV = (min),                \
++              .uV_step = (step),              \
+               .vsel_reg = vosel,      \
+               .vsel_mask = vosel_mask,        \
+               .enable_reg = MT6358_LDO_##vreg##_CON0, \
+@@ -226,21 +226,6 @@ struct mt6358_regulator_info {
+       .qi = BIT(15),                                                  \
+ }
+-static const struct linear_range buck_volt_range1[] = {
+-      REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250),
+-};
+-
+-static const struct linear_range buck_volt_range2[] = {
+-      REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 12500),
+-};
+-
+-static const struct linear_range buck_volt_range3[] = {
+-      REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000),
+-};
+-
+-static const struct linear_range buck_volt_range4[] = {
+-      REGULATOR_LINEAR_RANGE(1000000, 0, 0x7f, 12500),
+-};
+ static const unsigned int vdram2_voltages[] = {
+       600000, 1800000,
+@@ -464,8 +449,8 @@ static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev)
+ }
+ static const struct regulator_ops mt6358_volt_range_ops = {
+-      .list_voltage = regulator_list_voltage_linear_range,
+-      .map_voltage = regulator_map_voltage_linear_range,
++      .list_voltage = regulator_list_voltage_linear,
++      .map_voltage = regulator_map_voltage_linear,
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
+       .get_voltage_sel = mt6358_get_buck_voltage_sel,
+       .set_voltage_time_sel = regulator_set_voltage_time_sel,
+@@ -500,32 +485,23 @@ static const struct regulator_ops mt6358_volt_fixed_ops = {
+ /* The array is indexed by id(MT6358_ID_XXX) */
+ static struct mt6358_regulator_info mt6358_regulators[] = {
+       MT6358_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
+-                  buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f,
+-                  MT6358_VDRAM1_ANA_CON0, 8),
++                  0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8),
+       MT6358_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
+-                  buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
+-                  MT6358_VCORE_VGPU_ANA_CON0, 1),
++                  0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1),
+       MT6358_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
+-                  buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f,
+-                  MT6358_VPA_ANA_CON0, 3),
++                  0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3),
+       MT6358_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
+-                  buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f,
+-                  MT6358_VPROC_ANA_CON0, 1),
++                  0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1),
+       MT6358_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
+-                  buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f,
+-                  MT6358_VPROC_ANA_CON0, 2),
++                  0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2),
+       MT6358_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
+-                  buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f,
+-                  MT6358_VCORE_VGPU_ANA_CON0, 2),
++                  0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2),
+       MT6358_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
+-                  buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f,
+-                  MT6358_VS2_ANA_CON0, 8),
++                  0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8),
+       MT6358_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
+-                  buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f,
+-                  MT6358_VMODEM_ANA_CON0, 8),
++                  0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8),
+       MT6358_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
+-                  buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f,
+-                  MT6358_VS1_ANA_CON0, 8),
++                  0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8),
+       MT6358_REG_FIXED("ldo_vrf12", VRF12,
+                        MT6358_LDO_VRF12_CON0, 0, 1200000),
+       MT6358_REG_FIXED("ldo_vio18", VIO18,
+@@ -579,48 +555,35 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
+       MT6358_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
+                  MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00),
+       MT6358_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
+-                  buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00,
+-                  MT6358_LDO_VSRAM_CON0, 0x7f),
++                  MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f),
+       MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
+-                  buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00,
+-                  MT6358_LDO_VSRAM_CON2, 0x7f),
++                  MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f),
+       MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
+-                  buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00,
+-                  MT6358_LDO_VSRAM_CON3, 0x7f),
++                  MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f),
+       MT6358_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
+-                  buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00,
+-                  MT6358_LDO_VSRAM_CON1, 0x7f),
++                  MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f),
+ };
+ /* The array is indexed by id(MT6366_ID_XXX) */
+ static struct mt6358_regulator_info mt6366_regulators[] = {
+       MT6366_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
+-                  buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f,
+-                  MT6358_VDRAM1_ANA_CON0, 8),
++                  0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8),
+       MT6366_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
+-                  buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
+-                  MT6358_VCORE_VGPU_ANA_CON0, 1),
++                  0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1),
+       MT6366_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
+-                  buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f,
+-                  MT6358_VPA_ANA_CON0, 3),
++                  0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3),
+       MT6366_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
+-                  buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f,
+-                  MT6358_VPROC_ANA_CON0, 1),
++                  0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1),
+       MT6366_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
+-                  buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f,
+-                  MT6358_VPROC_ANA_CON0, 2),
++                  0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2),
+       MT6366_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
+-                  buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f,
+-                  MT6358_VCORE_VGPU_ANA_CON0, 2),
++                  0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2),
+       MT6366_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
+-                  buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f,
+-                  MT6358_VS2_ANA_CON0, 8),
++                  0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8),
+       MT6366_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
+-                  buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f,
+-                  MT6358_VMODEM_ANA_CON0, 8),
++                  0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8),
+       MT6366_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
+-                  buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f,
+-                  MT6358_VS1_ANA_CON0, 8),
++                  0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8),
+       MT6366_REG_FIXED("ldo_vrf12", VRF12,
+                        MT6358_LDO_VRF12_CON0, 0, 1200000),
+       MT6366_REG_FIXED("ldo_vio18", VIO18,
+@@ -663,17 +626,13 @@ static struct mt6358_regulator_info mt6366_regulators[] = {
+       MT6366_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
+                  MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00),
+       MT6366_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
+-                  buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00,
+-                  MT6358_LDO_VSRAM_CON0, 0x7f),
++                  MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f),
+       MT6366_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
+-                  buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00,
+-                  MT6358_LDO_VSRAM_CON2, 0x7f),
++                  MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f),
+       MT6366_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
+-                  buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00,
+-                  MT6358_LDO_VSRAM_CON3, 0x7f),
++                  MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f),
+       MT6366_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
+-                  buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00,
+-                  MT6358_LDO_VSRAM_CON1, 0x7f),
++                  MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f),
+ };
+ static int mt6358_regulator_probe(struct platform_device *pdev)
+-- 
+2.40.1
+
diff --git a/queue-6.1/scsi-target-core-fix-deadlock-due-to-recursive-locki.patch b/queue-6.1/scsi-target-core-fix-deadlock-due-to-recursive-locki.patch
new file mode 100644 (file)
index 0000000..e39fea1
--- /dev/null
@@ -0,0 +1,98 @@
+From e3b9fb4b84a0fad9868d5d263318cd06683df806 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Sep 2023 15:58:48 -0700
+Subject: scsi: target: core: Fix deadlock due to recursive locking
+
+From: Junxiao Bi <junxiao.bi@oracle.com>
+
+[ Upstream commit a154f5f643c6ecddd44847217a7a3845b4350003 ]
+
+The following call trace shows a deadlock issue due to recursive locking of
+mutex "device_mutex". First lock acquire is in target_for_each_device() and
+second in target_free_device().
+
+ PID: 148266   TASK: ffff8be21ffb5d00  CPU: 10   COMMAND: "iscsi_ttx"
+  #0 [ffffa2bfc9ec3b18] __schedule at ffffffffa8060e7f
+  #1 [ffffa2bfc9ec3ba0] schedule at ffffffffa8061224
+  #2 [ffffa2bfc9ec3bb8] schedule_preempt_disabled at ffffffffa80615ee
+  #3 [ffffa2bfc9ec3bc8] __mutex_lock at ffffffffa8062fd7
+  #4 [ffffa2bfc9ec3c40] __mutex_lock_slowpath at ffffffffa80631d3
+  #5 [ffffa2bfc9ec3c50] mutex_lock at ffffffffa806320c
+  #6 [ffffa2bfc9ec3c68] target_free_device at ffffffffc0935998 [target_core_mod]
+  #7 [ffffa2bfc9ec3c90] target_core_dev_release at ffffffffc092f975 [target_core_mod]
+  #8 [ffffa2bfc9ec3ca0] config_item_put at ffffffffa79d250f
+  #9 [ffffa2bfc9ec3cd0] config_item_put at ffffffffa79d2583
+ #10 [ffffa2bfc9ec3ce0] target_devices_idr_iter at ffffffffc0933f3a [target_core_mod]
+ #11 [ffffa2bfc9ec3d00] idr_for_each at ffffffffa803f6fc
+ #12 [ffffa2bfc9ec3d60] target_for_each_device at ffffffffc0935670 [target_core_mod]
+ #13 [ffffa2bfc9ec3d98] transport_deregister_session at ffffffffc0946408 [target_core_mod]
+ #14 [ffffa2bfc9ec3dc8] iscsit_close_session at ffffffffc09a44a6 [iscsi_target_mod]
+ #15 [ffffa2bfc9ec3df0] iscsit_close_connection at ffffffffc09a4a88 [iscsi_target_mod]
+ #16 [ffffa2bfc9ec3df8] finish_task_switch at ffffffffa76e5d07
+ #17 [ffffa2bfc9ec3e78] iscsit_take_action_for_connection_exit at ffffffffc0991c23 [iscsi_target_mod]
+ #18 [ffffa2bfc9ec3ea0] iscsi_target_tx_thread at ffffffffc09a403b [iscsi_target_mod]
+ #19 [ffffa2bfc9ec3f08] kthread at ffffffffa76d8080
+ #20 [ffffa2bfc9ec3f50] ret_from_fork at ffffffffa8200364
+
+Fixes: 36d4cb460bcb ("scsi: target: Avoid that EXTENDED COPY commands trigger lock inversion")
+Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com>
+Link: https://lore.kernel.org/r/20230918225848.66463-1-junxiao.bi@oracle.com
+Reviewed-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/target/target_core_device.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
+index d21f88de197c7..301fe376a1206 100644
+--- a/drivers/target/target_core_device.c
++++ b/drivers/target/target_core_device.c
+@@ -883,7 +883,6 @@ sector_t target_to_linux_sector(struct se_device *dev, sector_t lb)
+ EXPORT_SYMBOL(target_to_linux_sector);
+ struct devices_idr_iter {
+-      struct config_item *prev_item;
+       int (*fn)(struct se_device *dev, void *data);
+       void *data;
+ };
+@@ -893,11 +892,9 @@ static int target_devices_idr_iter(int id, void *p, void *data)
+ {
+       struct devices_idr_iter *iter = data;
+       struct se_device *dev = p;
++      struct config_item *item;
+       int ret;
+-      config_item_put(iter->prev_item);
+-      iter->prev_item = NULL;
+-
+       /*
+        * We add the device early to the idr, so it can be used
+        * by backend modules during configuration. We do not want
+@@ -907,12 +904,13 @@ static int target_devices_idr_iter(int id, void *p, void *data)
+       if (!target_dev_configured(dev))
+               return 0;
+-      iter->prev_item = config_item_get_unless_zero(&dev->dev_group.cg_item);
+-      if (!iter->prev_item)
++      item = config_item_get_unless_zero(&dev->dev_group.cg_item);
++      if (!item)
+               return 0;
+       mutex_unlock(&device_mutex);
+       ret = iter->fn(dev, iter->data);
++      config_item_put(item);
+       mutex_lock(&device_mutex);
+       return ret;
+@@ -935,7 +933,6 @@ int target_for_each_device(int (*fn)(struct se_device *dev, void *data),
+       mutex_lock(&device_mutex);
+       ret = idr_for_each(&devices_idr, target_devices_idr_iter, &iter);
+       mutex_unlock(&device_mutex);
+-      config_item_put(iter.prev_item);
+       return ret;
+ }
+-- 
+2.40.1
+
diff --git a/queue-6.1/sctp-update-hb-timer-immediately-after-users-change-.patch b/queue-6.1/sctp-update-hb-timer-immediately-after-users-change-.patch
new file mode 100644 (file)
index 0000000..dae6335
--- /dev/null
@@ -0,0 +1,48 @@
+From 93aea21e9fa074adcf5f908d5b993aaf3435e83f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Oct 2023 11:04:20 -0400
+Subject: sctp: update hb timer immediately after users change hb_interval
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 1f4e803cd9c9166eb8b6c8b0b8e4124f7499fc07 ]
+
+Currently, when hb_interval is changed by users, it won't take effect
+until the next expiry of hb timer. As the default value is 30s, users
+have to wait up to 30s to wait its hb_interval update to work.
+
+This becomes pretty bad in containers where a much smaller value is
+usually set on hb_interval. This patch improves it by resetting the
+hb timer immediately once the value of hb_interval is updated by users.
+
+Note that we don't address the already existing 'problem' when sending
+a heartbeat 'on demand' if one hb has just been sent(from the timer)
+mentioned in:
+
+  https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg590224.html
+
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Link: https://lore.kernel.org/r/75465785f8ee5df2fb3acdca9b8fafdc18984098.1696172660.git.lucien.xin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/socket.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 32e3669adf146..e25dc17091311 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -2449,6 +2449,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
+                       if (trans) {
+                               trans->hbinterval =
+                                   msecs_to_jiffies(params->spp_hbinterval);
++                              sctp_transport_reset_hb_timer(trans);
+                       } else if (asoc) {
+                               asoc->hbinterval =
+                                   msecs_to_jiffies(params->spp_hbinterval);
+-- 
+2.40.1
+
diff --git a/queue-6.1/sctp-update-transport-state-when-processing-a-dupcoo.patch b/queue-6.1/sctp-update-transport-state-when-processing-a-dupcoo.patch
new file mode 100644 (file)
index 0000000..42ea7da
--- /dev/null
@@ -0,0 +1,67 @@
+From 373f722c1018632ca6c1853bd4c3c5f31ec28878 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Oct 2023 10:58:45 -0400
+Subject: sctp: update transport state when processing a dupcook packet
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 2222a78075f0c19ca18db53fd6623afb4aff602d ]
+
+During the 4-way handshake, the transport's state is set to ACTIVE in
+sctp_process_init() when processing INIT_ACK chunk on client or
+COOKIE_ECHO chunk on server.
+
+In the collision scenario below:
+
+  192.168.1.2 > 192.168.1.1: sctp (1) [INIT] [init tag: 3922216408]
+    192.168.1.1 > 192.168.1.2: sctp (1) [INIT] [init tag: 144230885]
+    192.168.1.2 > 192.168.1.1: sctp (1) [INIT ACK] [init tag: 3922216408]
+    192.168.1.1 > 192.168.1.2: sctp (1) [COOKIE ECHO]
+    192.168.1.2 > 192.168.1.1: sctp (1) [COOKIE ACK]
+  192.168.1.1 > 192.168.1.2: sctp (1) [INIT ACK] [init tag: 3914796021]
+
+when processing COOKIE_ECHO on 192.168.1.2, as it's in COOKIE_WAIT state,
+sctp_sf_do_dupcook_b() is called by sctp_sf_do_5_2_4_dupcook() where it
+creates a new association and sets its transport to ACTIVE then updates
+to the old association in sctp_assoc_update().
+
+However, in sctp_assoc_update(), it will skip the transport update if it
+finds a transport with the same ipaddr already existing in the old asoc,
+and this causes the old asoc's transport state not to move to ACTIVE
+after the handshake.
+
+This means if DATA retransmission happens at this moment, it won't be able
+to enter PF state because of the check 'transport->state == SCTP_ACTIVE'
+in sctp_do_8_2_transport_strike().
+
+This patch fixes it by updating the transport in sctp_assoc_update() with
+sctp_assoc_add_peer() where it updates the transport state if there is
+already a transport with the same ipaddr exists in the old asoc.
+
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Link: https://lore.kernel.org/r/fd17356abe49713ded425250cc1ae51e9f5846c6.1696172325.git.lucien.xin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/associola.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/net/sctp/associola.c b/net/sctp/associola.c
+index 3460abceba443..2965a12fe8aa2 100644
+--- a/net/sctp/associola.c
++++ b/net/sctp/associola.c
+@@ -1161,8 +1161,7 @@ int sctp_assoc_update(struct sctp_association *asoc,
+               /* Add any peer addresses from the new association. */
+               list_for_each_entry(trans, &new->peer.transport_addr_list,
+                                   transports)
+-                      if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr) &&
+-                          !sctp_assoc_add_peer(asoc, &trans->ipaddr,
++                      if (!sctp_assoc_add_peer(asoc, &trans->ipaddr,
+                                                GFP_ATOMIC, trans->state))
+                               return -ENOMEM;
+-- 
+2.40.1
+
diff --git a/queue-6.1/selftests-netfilter-extend-nft_audit.sh.patch b/queue-6.1/selftests-netfilter-extend-nft_audit.sh.patch
new file mode 100644 (file)
index 0000000..3978fc8
--- /dev/null
@@ -0,0 +1,171 @@
+From df7ed112a553d8cf389514338223df00770ae024 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Sep 2023 03:53:49 +0200
+Subject: selftests: netfilter: Extend nft_audit.sh
+
+From: Phil Sutter <phil@nwl.cc>
+
+[ Upstream commit 203bb9d39866d3c5a8135433ce3742fe4f9d5741 ]
+
+Add tests for sets and elements and deletion of all kinds. Also
+reorder rule reset tests: By moving the bulk rule add command up, the
+two 'reset rules' tests become identical.
+
+While at it, fix for a failing bulk rule add test's error status getting
+lost due to its use in a pipe. Avoid this by using a temporary file.
+
+Headings in diff output for failing tests contain no useful data, strip
+them.
+
+Signed-off-by: Phil Sutter <phil@nwl.cc>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Stable-dep-of: 0d880dc6f032 ("netfilter: nf_tables: Deduplicate nft_register_obj audit logs")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../testing/selftests/netfilter/nft_audit.sh  | 97 ++++++++++++++++---
+ 1 file changed, 81 insertions(+), 16 deletions(-)
+
+diff --git a/tools/testing/selftests/netfilter/nft_audit.sh b/tools/testing/selftests/netfilter/nft_audit.sh
+index 83c271b1c7352..0b3255e7b3538 100755
+--- a/tools/testing/selftests/netfilter/nft_audit.sh
++++ b/tools/testing/selftests/netfilter/nft_audit.sh
+@@ -12,10 +12,11 @@ nft --version >/dev/null 2>&1 || {
+ }
+ logfile=$(mktemp)
++rulefile=$(mktemp)
+ echo "logging into $logfile"
+ ./audit_logread >"$logfile" &
+ logread_pid=$!
+-trap 'kill $logread_pid; rm -f $logfile' EXIT
++trap 'kill $logread_pid; rm -f $logfile $rulefile' EXIT
+ exec 3<"$logfile"
+ do_test() { # (cmd, log)
+@@ -26,12 +27,14 @@ do_test() { # (cmd, log)
+       res=$(diff -a -u <(echo "$2") - <&3)
+       [ $? -eq 0 ] && { echo "OK"; return; }
+       echo "FAIL"
+-      echo "$res"
+-      ((RC++))
++      grep -v '^\(---\|+++\|@@\)' <<< "$res"
++      ((RC--))
+ }
+ nft flush ruleset
++# adding tables, chains and rules
++
+ for table in t1 t2; do
+       do_test "nft add table $table" \
+       "table=$table family=2 entries=1 op=nft_register_table"
+@@ -62,6 +65,28 @@ for table in t1 t2; do
+       "table=$table family=2 entries=6 op=nft_register_rule"
+ done
++for ((i = 0; i < 500; i++)); do
++      echo "add rule t2 c3 counter accept comment \"rule $i\""
++done >$rulefile
++do_test "nft -f $rulefile" \
++'table=t2 family=2 entries=500 op=nft_register_rule'
++
++# adding sets and elements
++
++settype='type inet_service; counter'
++setelem='{ 22, 80, 443 }'
++setblock="{ $settype; elements = $setelem; }"
++do_test "nft add set t1 s $setblock" \
++"table=t1 family=2 entries=4 op=nft_register_set"
++
++do_test "nft add set t1 s2 $setblock; add set t1 s3 { $settype; }" \
++"table=t1 family=2 entries=5 op=nft_register_set"
++
++do_test "nft add element t1 s3 $setelem" \
++"table=t1 family=2 entries=3 op=nft_register_setelem"
++
++# resetting rules
++
+ do_test 'nft reset rules t1 c2' \
+ 'table=t1 family=2 entries=3 op=nft_reset_rule'
+@@ -70,19 +95,6 @@ do_test 'nft reset rules table t1' \
+ table=t1 family=2 entries=3 op=nft_reset_rule
+ table=t1 family=2 entries=3 op=nft_reset_rule'
+-do_test 'nft reset rules' \
+-'table=t1 family=2 entries=3 op=nft_reset_rule
+-table=t1 family=2 entries=3 op=nft_reset_rule
+-table=t1 family=2 entries=3 op=nft_reset_rule
+-table=t2 family=2 entries=3 op=nft_reset_rule
+-table=t2 family=2 entries=3 op=nft_reset_rule
+-table=t2 family=2 entries=3 op=nft_reset_rule'
+-
+-for ((i = 0; i < 500; i++)); do
+-      echo "add rule t2 c3 counter accept comment \"rule $i\""
+-done | do_test 'nft -f -' \
+-'table=t2 family=2 entries=500 op=nft_register_rule'
+-
+ do_test 'nft reset rules t2 c3' \
+ 'table=t2 family=2 entries=189 op=nft_reset_rule
+ table=t2 family=2 entries=188 op=nft_reset_rule
+@@ -105,4 +117,57 @@ table=t2 family=2 entries=180 op=nft_reset_rule
+ table=t2 family=2 entries=188 op=nft_reset_rule
+ table=t2 family=2 entries=135 op=nft_reset_rule'
++# resetting sets and elements
++
++elem=(22 ,80 ,443)
++relem=""
++for i in {1..3}; do
++      relem+="${elem[((i - 1))]}"
++      do_test "nft reset element t1 s { $relem }" \
++      "table=t1 family=2 entries=$i op=nft_reset_setelem"
++done
++
++do_test 'nft reset set t1 s' \
++'table=t1 family=2 entries=3 op=nft_reset_setelem'
++
++# deleting rules
++
++readarray -t handles < <(nft -a list chain t1 c1 | \
++                       sed -n 's/.*counter.* handle \(.*\)$/\1/p')
++
++do_test "nft delete rule t1 c1 handle ${handles[0]}" \
++'table=t1 family=2 entries=1 op=nft_unregister_rule'
++
++cmd='delete rule t1 c1 handle'
++do_test "nft $cmd ${handles[1]}; $cmd ${handles[2]}" \
++'table=t1 family=2 entries=2 op=nft_unregister_rule'
++
++do_test 'nft flush chain t1 c2' \
++'table=t1 family=2 entries=3 op=nft_unregister_rule'
++
++do_test 'nft flush table t2' \
++'table=t2 family=2 entries=509 op=nft_unregister_rule'
++
++# deleting chains
++
++do_test 'nft delete chain t2 c2' \
++'table=t2 family=2 entries=1 op=nft_unregister_chain'
++
++# deleting sets and elements
++
++do_test 'nft delete element t1 s { 22 }' \
++'table=t1 family=2 entries=1 op=nft_unregister_setelem'
++
++do_test 'nft delete element t1 s { 80, 443 }' \
++'table=t1 family=2 entries=2 op=nft_unregister_setelem'
++
++do_test 'nft flush set t1 s2' \
++'table=t1 family=2 entries=3 op=nft_unregister_setelem'
++
++do_test 'nft delete set t1 s2' \
++'table=t1 family=2 entries=1 op=nft_unregister_set'
++
++do_test 'nft delete set t1 s3' \
++'table=t1 family=2 entries=1 op=nft_unregister_set'
++
+ exit $RC
+-- 
+2.40.1
+
diff --git a/queue-6.1/selftests-netfilter-test-nf_tables-audit-logging.patch b/queue-6.1/selftests-netfilter-test-nf_tables-audit-logging.patch
new file mode 100644 (file)
index 0000000..ff588d8
--- /dev/null
@@ -0,0 +1,352 @@
+From 04aa2c5ed0619a43a8fa3a7d8bd31d6013529bff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Sep 2023 15:51:37 +0200
+Subject: selftests: netfilter: Test nf_tables audit logging
+
+From: Phil Sutter <phil@nwl.cc>
+
+[ Upstream commit e8dbde59ca3fe925d0105bfb380e8429928b16dd ]
+
+Compare NETFILTER_CFG type audit logs emitted from kernel upon ruleset
+modifications against expected output.
+
+Signed-off-by: Phil Sutter <phil@nwl.cc>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: 0d880dc6f032 ("netfilter: nf_tables: Deduplicate nft_register_obj audit logs")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/netfilter/.gitignore  |   1 +
+ tools/testing/selftests/netfilter/Makefile    |   4 +-
+ .../selftests/netfilter/audit_logread.c       | 165 ++++++++++++++++++
+ tools/testing/selftests/netfilter/config      |   1 +
+ .../testing/selftests/netfilter/nft_audit.sh  | 108 ++++++++++++
+ 5 files changed, 277 insertions(+), 2 deletions(-)
+ create mode 100644 tools/testing/selftests/netfilter/audit_logread.c
+ create mode 100755 tools/testing/selftests/netfilter/nft_audit.sh
+
+diff --git a/tools/testing/selftests/netfilter/.gitignore b/tools/testing/selftests/netfilter/.gitignore
+index 4cb887b574138..4b2928e1c19d8 100644
+--- a/tools/testing/selftests/netfilter/.gitignore
++++ b/tools/testing/selftests/netfilter/.gitignore
+@@ -1,3 +1,4 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ nf-queue
+ connect_close
++audit_logread
+diff --git a/tools/testing/selftests/netfilter/Makefile b/tools/testing/selftests/netfilter/Makefile
+index 3686bfa6c58d7..321db8850da00 100644
+--- a/tools/testing/selftests/netfilter/Makefile
++++ b/tools/testing/selftests/netfilter/Makefile
+@@ -6,13 +6,13 @@ TEST_PROGS := nft_trans_stress.sh nft_fib.sh nft_nat.sh bridge_brouter.sh \
+       nft_concat_range.sh nft_conntrack_helper.sh \
+       nft_queue.sh nft_meta.sh nf_nat_edemux.sh \
+       ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh \
+-      conntrack_vrf.sh nft_synproxy.sh rpath.sh
++      conntrack_vrf.sh nft_synproxy.sh rpath.sh nft_audit.sh
+ HOSTPKG_CONFIG := pkg-config
+ CFLAGS += $(shell $(HOSTPKG_CONFIG) --cflags libmnl 2>/dev/null)
+ LDLIBS += $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl)
+-TEST_GEN_FILES =  nf-queue connect_close
++TEST_GEN_FILES =  nf-queue connect_close audit_logread
+ include ../lib.mk
+diff --git a/tools/testing/selftests/netfilter/audit_logread.c b/tools/testing/selftests/netfilter/audit_logread.c
+new file mode 100644
+index 0000000000000..a0a880fc2d9de
+--- /dev/null
++++ b/tools/testing/selftests/netfilter/audit_logread.c
+@@ -0,0 +1,165 @@
++// SPDX-License-Identifier: GPL-2.0
++
++#define _GNU_SOURCE
++#include <errno.h>
++#include <fcntl.h>
++#include <poll.h>
++#include <signal.h>
++#include <stdint.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/socket.h>
++#include <unistd.h>
++#include <linux/audit.h>
++#include <linux/netlink.h>
++
++static int fd;
++
++#define MAX_AUDIT_MESSAGE_LENGTH      8970
++struct audit_message {
++      struct nlmsghdr nlh;
++      union {
++              struct audit_status s;
++              char data[MAX_AUDIT_MESSAGE_LENGTH];
++      } u;
++};
++
++int audit_recv(int fd, struct audit_message *rep)
++{
++      struct sockaddr_nl addr;
++      socklen_t addrlen = sizeof(addr);
++      int ret;
++
++      do {
++              ret = recvfrom(fd, rep, sizeof(*rep), 0,
++                             (struct sockaddr *)&addr, &addrlen);
++      } while (ret < 0 && errno == EINTR);
++
++      if (ret < 0 ||
++          addrlen != sizeof(addr) ||
++          addr.nl_pid != 0 ||
++          rep->nlh.nlmsg_type == NLMSG_ERROR) /* short-cut for now */
++              return -1;
++
++      return ret;
++}
++
++int audit_send(int fd, uint16_t type, uint32_t key, uint32_t val)
++{
++      static int seq = 0;
++      struct audit_message msg = {
++              .nlh = {
++                      .nlmsg_len   = NLMSG_SPACE(sizeof(msg.u.s)),
++                      .nlmsg_type  = type,
++                      .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
++                      .nlmsg_seq   = ++seq,
++              },
++              .u.s = {
++                      .mask    = key,
++                      .enabled = key == AUDIT_STATUS_ENABLED ? val : 0,
++                      .pid     = key == AUDIT_STATUS_PID ? val : 0,
++              }
++      };
++      struct sockaddr_nl addr = {
++              .nl_family = AF_NETLINK,
++      };
++      int ret;
++
++      do {
++              ret = sendto(fd, &msg, msg.nlh.nlmsg_len, 0,
++                           (struct sockaddr *)&addr, sizeof(addr));
++      } while (ret < 0 && errno == EINTR);
++
++      if (ret != (int)msg.nlh.nlmsg_len)
++              return -1;
++      return 0;
++}
++
++int audit_set(int fd, uint32_t key, uint32_t val)
++{
++      struct audit_message rep = { 0 };
++      int ret;
++
++      ret = audit_send(fd, AUDIT_SET, key, val);
++      if (ret)
++              return ret;
++
++      ret = audit_recv(fd, &rep);
++      if (ret < 0)
++              return ret;
++      return 0;
++}
++
++int readlog(int fd)
++{
++      struct audit_message rep = { 0 };
++      int ret = audit_recv(fd, &rep);
++      const char *sep = "";
++      char *k, *v;
++
++      if (ret < 0)
++              return ret;
++
++      if (rep.nlh.nlmsg_type != AUDIT_NETFILTER_CFG)
++              return 0;
++
++      /* skip the initial "audit(...): " part */
++      strtok(rep.u.data, " ");
++
++      while ((k = strtok(NULL, "="))) {
++              v = strtok(NULL, " ");
++
++              /* these vary and/or are uninteresting, ignore */
++              if (!strcmp(k, "pid") ||
++                  !strcmp(k, "comm") ||
++                  !strcmp(k, "subj"))
++                      continue;
++
++              /* strip the varying sequence number */
++              if (!strcmp(k, "table"))
++                      *strchrnul(v, ':') = '\0';
++
++              printf("%s%s=%s", sep, k, v);
++              sep = " ";
++      }
++      if (*sep) {
++              printf("\n");
++              fflush(stdout);
++      }
++      return 0;
++}
++
++void cleanup(int sig)
++{
++      audit_set(fd, AUDIT_STATUS_ENABLED, 0);
++      close(fd);
++      if (sig)
++              exit(0);
++}
++
++int main(int argc, char **argv)
++{
++      struct sigaction act = {
++              .sa_handler = cleanup,
++      };
++
++      fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
++      if (fd < 0) {
++              perror("Can't open netlink socket");
++              return -1;
++      }
++
++      if (sigaction(SIGTERM, &act, NULL) < 0 ||
++          sigaction(SIGINT, &act, NULL) < 0) {
++              perror("Can't set signal handler");
++              close(fd);
++              return -1;
++      }
++
++      audit_set(fd, AUDIT_STATUS_ENABLED, 1);
++      audit_set(fd, AUDIT_STATUS_PID, getpid());
++
++      while (1)
++              readlog(fd);
++}
+diff --git a/tools/testing/selftests/netfilter/config b/tools/testing/selftests/netfilter/config
+index 4faf2ce021d90..7c42b1b2c69b4 100644
+--- a/tools/testing/selftests/netfilter/config
++++ b/tools/testing/selftests/netfilter/config
+@@ -6,3 +6,4 @@ CONFIG_NFT_REDIR=m
+ CONFIG_NFT_MASQ=m
+ CONFIG_NFT_FLOW_OFFLOAD=m
+ CONFIG_NF_CT_NETLINK=m
++CONFIG_AUDIT=y
+diff --git a/tools/testing/selftests/netfilter/nft_audit.sh b/tools/testing/selftests/netfilter/nft_audit.sh
+new file mode 100755
+index 0000000000000..83c271b1c7352
+--- /dev/null
++++ b/tools/testing/selftests/netfilter/nft_audit.sh
+@@ -0,0 +1,108 @@
++#!/bin/bash
++# SPDX-License-Identifier: GPL-2.0
++#
++# Check that audit logs generated for nft commands are as expected.
++
++SKIP_RC=4
++RC=0
++
++nft --version >/dev/null 2>&1 || {
++      echo "SKIP: missing nft tool"
++      exit $SKIP_RC
++}
++
++logfile=$(mktemp)
++echo "logging into $logfile"
++./audit_logread >"$logfile" &
++logread_pid=$!
++trap 'kill $logread_pid; rm -f $logfile' EXIT
++exec 3<"$logfile"
++
++do_test() { # (cmd, log)
++      echo -n "testing for cmd: $1 ... "
++      cat <&3 >/dev/null
++      $1 >/dev/null || exit 1
++      sleep 0.1
++      res=$(diff -a -u <(echo "$2") - <&3)
++      [ $? -eq 0 ] && { echo "OK"; return; }
++      echo "FAIL"
++      echo "$res"
++      ((RC++))
++}
++
++nft flush ruleset
++
++for table in t1 t2; do
++      do_test "nft add table $table" \
++      "table=$table family=2 entries=1 op=nft_register_table"
++
++      do_test "nft add chain $table c1" \
++      "table=$table family=2 entries=1 op=nft_register_chain"
++
++      do_test "nft add chain $table c2; add chain $table c3" \
++      "table=$table family=2 entries=2 op=nft_register_chain"
++
++      cmd="add rule $table c1 counter"
++
++      do_test "nft $cmd" \
++      "table=$table family=2 entries=1 op=nft_register_rule"
++
++      do_test "nft $cmd; $cmd" \
++      "table=$table family=2 entries=2 op=nft_register_rule"
++
++      cmd=""
++      sep=""
++      for chain in c2 c3; do
++              for i in {1..3}; do
++                      cmd+="$sep add rule $table $chain counter"
++                      sep=";"
++              done
++      done
++      do_test "nft $cmd" \
++      "table=$table family=2 entries=6 op=nft_register_rule"
++done
++
++do_test 'nft reset rules t1 c2' \
++'table=t1 family=2 entries=3 op=nft_reset_rule'
++
++do_test 'nft reset rules table t1' \
++'table=t1 family=2 entries=3 op=nft_reset_rule
++table=t1 family=2 entries=3 op=nft_reset_rule
++table=t1 family=2 entries=3 op=nft_reset_rule'
++
++do_test 'nft reset rules' \
++'table=t1 family=2 entries=3 op=nft_reset_rule
++table=t1 family=2 entries=3 op=nft_reset_rule
++table=t1 family=2 entries=3 op=nft_reset_rule
++table=t2 family=2 entries=3 op=nft_reset_rule
++table=t2 family=2 entries=3 op=nft_reset_rule
++table=t2 family=2 entries=3 op=nft_reset_rule'
++
++for ((i = 0; i < 500; i++)); do
++      echo "add rule t2 c3 counter accept comment \"rule $i\""
++done | do_test 'nft -f -' \
++'table=t2 family=2 entries=500 op=nft_register_rule'
++
++do_test 'nft reset rules t2 c3' \
++'table=t2 family=2 entries=189 op=nft_reset_rule
++table=t2 family=2 entries=188 op=nft_reset_rule
++table=t2 family=2 entries=126 op=nft_reset_rule'
++
++do_test 'nft reset rules t2' \
++'table=t2 family=2 entries=3 op=nft_reset_rule
++table=t2 family=2 entries=3 op=nft_reset_rule
++table=t2 family=2 entries=186 op=nft_reset_rule
++table=t2 family=2 entries=188 op=nft_reset_rule
++table=t2 family=2 entries=129 op=nft_reset_rule'
++
++do_test 'nft reset rules' \
++'table=t1 family=2 entries=3 op=nft_reset_rule
++table=t1 family=2 entries=3 op=nft_reset_rule
++table=t1 family=2 entries=3 op=nft_reset_rule
++table=t2 family=2 entries=3 op=nft_reset_rule
++table=t2 family=2 entries=3 op=nft_reset_rule
++table=t2 family=2 entries=180 op=nft_reset_rule
++table=t2 family=2 entries=188 op=nft_reset_rule
++table=t2 family=2 entries=135 op=nft_reset_rule'
++
++exit $RC
+-- 
+2.40.1
+
index de781467fb0715c4295bad1095a9a8a2d0beebe8..88522b59be2b63f8502b41e3f301e670c6f501bf 100644 (file)
@@ -54,3 +54,68 @@ block-fix-use-after-free-of-q-q_usage_counter.patch
 hwmon-nzxt-smart2-add-device-id.patch
 hwmon-nzxt-smart2-add-another-usb-id.patch
 i40e-fix-the-wrong-ptp-frequency-calculation.patch
+hid-sony-fix-a-potential-memory-leak-in-sony_probe.patch
+ubi-refuse-attaching-if-mtd-s-erasesize-is-0.patch
+erofs-fix-memory-leak-of-lzma-global-compressed-dedu.patch
+wifi-iwlwifi-dbg_ini-fix-structure-packing.patch
+wifi-iwlwifi-mvm-fix-a-memory-corruption-issue.patch
+wifi-cfg80211-hold-wiphy-lock-in-auto-disconnect.patch
+wifi-cfg80211-move-wowlan-disable-under-locks.patch
+wifi-cfg80211-add-a-work-abstraction-with-special-se.patch
+wifi-cfg80211-fix-cqm_config-access-race.patch
+wifi-cfg80211-add-missing-kernel-doc-for-cqm_rssi_wo.patch
+wifi-mwifiex-fix-oob-check-condition-in-mwifiex_proc.patch
+leds-drop-bug_on-check-for-led_color_id_multi.patch
+bpf-fix-tr-dereferencing.patch
+regulator-mt6358-drop-_sshub-regulators.patch
+regulator-mt6358-use-linear-voltage-helpers-for-sing.patch
+regulator-mt6358-split-ops-for-buck-and-linear-range.patch
+bluetooth-delete-unused-hci_req_prepare_suspend-decl.patch
+bluetooth-iso-fix-handling-of-listen-for-unicast.patch
+drivers-net-process-the-result-of-hdlc_open-and-add-.patch
+wifi-mt76-mt76x02-fix-mt76x0-external-lna-gain-handl.patch
+perf-x86-amd-core-fix-overflow-reset-on-hotplug.patch
+regmap-rbtree-fix-wrong-register-marked-as-in-cache-.patch
+wifi-mac80211-fix-potential-key-use-after-free.patch
+perf-x86-amd-do-not-warn-on-every-irq.patch
+iommu-mediatek-fix-share-pgtable-for-iova-over-4gb.patch
+regulator-core-regulator_register-set-device-class-e.patch
+ima-finish-deprecation-of-ima_trusted_keyring-kconfi.patch
+scsi-target-core-fix-deadlock-due-to-recursive-locki.patch
+ima-rework-config_ima-dependency-block.patch
+nfsv4-fix-a-nfs4_state_manager-race.patch
+bpf-tcp_read_skb-needs-to-pop-skb-regardless-of-seq.patch
+bpf-sockmap-do-not-inc-copied_seq-when-peek-flag-set.patch
+bpf-sockmap-reject-sk_msg-egress-redirects-to-non-tc.patch
+modpost-add-missing-else-to-the-of-check.patch
+net-fix-possible-store-tearing-in-neigh_periodic_wor.patch
+bpf-add-bpf_fib_lookup_skip_neigh-for-bpf_fib_lookup.patch
+neighbour-annotate-lockless-accesses-to-n-nud_state.patch
+neighbour-switch-to-standard-rcu-instead-of-rcu_bh.patch
+neighbour-fix-data-races-around-n-output.patch
+ipv4-ipv6-fix-handling-of-transhdrlen-in-__ip-6-_app.patch
+ptp-ocp-fix-error-handling-in-ptp_ocp_device_init.patch
+net-dsa-mv88e6xxx-avoid-eeprom-timeout-when-eeprom-i.patch
+ipv6-tcp-add-a-missing-nf_reset_ct-in-3whs-handling.patch
+net-usb-smsc75xx-fix-uninit-value-access-in-__smsc75.patch
+net-nfc-llcp-add-lock-when-modifying-device-list.patch
+net-ethernet-ti-am65-cpsw-fix-error-code-in-am65_cps.patch
+ibmveth-remove-condition-to-recompute-tcp-header-che.patch
+netfilter-handle-the-connecting-collision-properly-i.patch
+selftests-netfilter-test-nf_tables-audit-logging.patch
+selftests-netfilter-extend-nft_audit.sh.patch
+netfilter-nf_tables-deduplicate-nft_register_obj-aud.patch
+netfilter-nf_tables-nft_set_rbtree-fix-spurious-inse.patch
+ipv4-set-offload_failed-flag-in-fibmatch-results.patch
+net-stmmac-dwmac-stm32-fix-resume-on-stm32-mcu.patch
+tipc-fix-a-potential-deadlock-on-tx-lock.patch
+tcp-fix-quick-ack-counting-to-count-actual-acks-of-n.patch
+tcp-fix-delayed-acks-for-mss-boundary-condition.patch
+sctp-update-transport-state-when-processing-a-dupcoo.patch
+sctp-update-hb-timer-immediately-after-users-change-.patch
+netlink-split-up-copies-in-the-ack-construction.patch
+netlink-fix-potential-skb-memleak-in-netlink_ack.patch
+netlink-annotate-data-races-around-sk-sk_err.patch
+hid-sony-remove-duplicate-null-check-before-calling-.patch
+hid-intel-ish-hid-ipc-disable-and-reenable-acpi-gpe-.patch
+intel_idle-add-emerald-rapids-xeon-support.patch
diff --git a/queue-6.1/tcp-fix-delayed-acks-for-mss-boundary-condition.patch b/queue-6.1/tcp-fix-delayed-acks-for-mss-boundary-condition.patch
new file mode 100644 (file)
index 0000000..c0381c6
--- /dev/null
@@ -0,0 +1,99 @@
+From 161aba22ed911cc65a6e09508dda5e962825afac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Oct 2023 11:12:39 -0400
+Subject: tcp: fix delayed ACKs for MSS boundary condition
+
+From: Neal Cardwell <ncardwell@google.com>
+
+[ Upstream commit 4720852ed9afb1c5ab84e96135cb5b73d5afde6f ]
+
+This commit fixes poor delayed ACK behavior that can cause poor TCP
+latency in a particular boundary condition: when an application makes
+a TCP socket write that is an exact multiple of the MSS size.
+
+The problem is that there is painful boundary discontinuity in the
+current delayed ACK behavior. With the current delayed ACK behavior,
+we have:
+
+(1) If an app reads data when > 1*MSS is unacknowledged, then
+    tcp_cleanup_rbuf() ACKs immediately because of:
+
+     tp->rcv_nxt - tp->rcv_wup > icsk->icsk_ack.rcv_mss ||
+
+(2) If an app reads all received data, and the packets were < 1*MSS,
+    and either (a) the app is not ping-pong or (b) we received two
+    packets < 1*MSS, then tcp_cleanup_rbuf() ACKs immediately beecause
+    of:
+
+     ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED2) ||
+      ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED) &&
+       !inet_csk_in_pingpong_mode(sk))) &&
+
+(3) *However*: if an app reads exactly 1*MSS of data,
+    tcp_cleanup_rbuf() does not send an immediate ACK. This is true
+    even if the app is not ping-pong and the 1*MSS of data had the PSH
+    bit set, suggesting the sending application completed an
+    application write.
+
+Thus if the app is not ping-pong, we have this painful case where
+>1*MSS gets an immediate ACK, and <1*MSS gets an immediate ACK, but a
+write whose last skb is an exact multiple of 1*MSS can get a 40ms
+delayed ACK. This means that any app that transfers data in one
+direction and takes care to align write size or packet size with MSS
+can suffer this problem. With receive zero copy making 4KB MSS values
+more common, it is becoming more common to have application writes
+naturally align with MSS, and more applications are likely to
+encounter this delayed ACK problem.
+
+The fix in this commit is to refine the delayed ACK heuristics with a
+simple check: immediately ACK a received 1*MSS skb with PSH bit set if
+the app reads all data. Why? If an skb has a len of exactly 1*MSS and
+has the PSH bit set then it is likely the end of an application
+write. So more data may not be arriving soon, and yet the data sender
+may be waiting for an ACK if cwnd-bound or using TX zero copy. Thus we
+set ICSK_ACK_PUSHED in this case so that tcp_cleanup_rbuf() will send
+an ACK immediately if the app reads all of the data and is not
+ping-pong. Note that this logic is also executed for the case where
+len > MSS, but in that case this logic does not matter (and does not
+hurt) because tcp_cleanup_rbuf() will always ACK immediately if the
+app reads data and there is more than an MSS of unACKed data.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Reviewed-by: Yuchung Cheng <ycheng@google.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Cc: Xin Guo <guoxin0309@gmail.com>
+Link: https://lore.kernel.org/r/20231001151239.1866845-2-ncardwell.sw@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_input.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index c697836f2b5b4..068221e742425 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -243,6 +243,19 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb)
+               if (unlikely(len > icsk->icsk_ack.rcv_mss +
+                                  MAX_TCP_OPTION_SPACE))
+                       tcp_gro_dev_warn(sk, skb, len);
++              /* If the skb has a len of exactly 1*MSS and has the PSH bit
++               * set then it is likely the end of an application write. So
++               * more data may not be arriving soon, and yet the data sender
++               * may be waiting for an ACK if cwnd-bound or using TX zero
++               * copy. So we set ICSK_ACK_PUSHED here so that
++               * tcp_cleanup_rbuf() will send an ACK immediately if the app
++               * reads all of the data and is not ping-pong. If len > MSS
++               * then this logic does not matter (and does not hurt) because
++               * tcp_cleanup_rbuf() will always ACK immediately if the app
++               * reads data and there is more than an MSS of unACKed data.
++               */
++              if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_PSH)
++                      icsk->icsk_ack.pending |= ICSK_ACK_PUSHED;
+       } else {
+               /* Otherwise, we make more careful check taking into account,
+                * that SACKs block is variable.
+-- 
+2.40.1
+
diff --git a/queue-6.1/tcp-fix-quick-ack-counting-to-count-actual-acks-of-n.patch b/queue-6.1/tcp-fix-quick-ack-counting-to-count-actual-acks-of-n.patch
new file mode 100644 (file)
index 0000000..61daa47
--- /dev/null
@@ -0,0 +1,102 @@
+From be5ded608328576a379fe15c434d70df65dd6629 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Oct 2023 11:12:38 -0400
+Subject: tcp: fix quick-ack counting to count actual ACKs of new data
+
+From: Neal Cardwell <ncardwell@google.com>
+
+[ Upstream commit 059217c18be6757b95bfd77ba53fb50b48b8a816 ]
+
+This commit fixes quick-ack counting so that it only considers that a
+quick-ack has been provided if we are sending an ACK that newly
+acknowledges data.
+
+The code was erroneously using the number of data segments in outgoing
+skbs when deciding how many quick-ack credits to remove. This logic
+does not make sense, and could cause poor performance in
+request-response workloads, like RPC traffic, where requests or
+responses can be multi-segment skbs.
+
+When a TCP connection decides to send N quick-acks, that is to
+accelerate the cwnd growth of the congestion control module
+controlling the remote endpoint of the TCP connection. That quick-ack
+decision is purely about the incoming data and outgoing ACKs. It has
+nothing to do with the outgoing data or the size of outgoing data.
+
+And in particular, an ACK only serves the intended purpose of allowing
+the remote congestion control to grow the congestion window quickly if
+the ACK is ACKing or SACKing new data.
+
+The fix is simple: only count packets as serving the goal of the
+quickack mechanism if they are ACKing/SACKing new data. We can tell
+whether this is the case by checking inet_csk_ack_scheduled(), since
+we schedule an ACK exactly when we are ACKing/SACKing new data.
+
+Fixes: fc6415bcb0f5 ("[TCP]: Fix quick-ack decrementing with TSO.")
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Reviewed-by: Yuchung Cheng <ycheng@google.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://lore.kernel.org/r/20231001151239.1866845-1-ncardwell.sw@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tcp.h     | 6 ++++--
+ net/ipv4/tcp_output.c | 7 +++----
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 5fd69f2342a44..9ebb54122bb71 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -355,12 +355,14 @@ ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos,
+ struct sk_buff *tcp_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp,
+                                    bool force_schedule);
+-static inline void tcp_dec_quickack_mode(struct sock *sk,
+-                                       const unsigned int pkts)
++static inline void tcp_dec_quickack_mode(struct sock *sk)
+ {
+       struct inet_connection_sock *icsk = inet_csk(sk);
+       if (icsk->icsk_ack.quick) {
++              /* How many ACKs S/ACKing new data have we sent? */
++              const unsigned int pkts = inet_csk_ack_scheduled(sk) ? 1 : 0;
++
+               if (pkts >= icsk->icsk_ack.quick) {
+                       icsk->icsk_ack.quick = 0;
+                       /* Leaving quickack mode we deflate ATO. */
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index dc3166e56169f..5921b0f6f9f41 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -177,8 +177,7 @@ static void tcp_event_data_sent(struct tcp_sock *tp,
+ }
+ /* Account for an ACK we sent. */
+-static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts,
+-                                    u32 rcv_nxt)
++static inline void tcp_event_ack_sent(struct sock *sk, u32 rcv_nxt)
+ {
+       struct tcp_sock *tp = tcp_sk(sk);
+@@ -192,7 +191,7 @@ static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts,
+       if (unlikely(rcv_nxt != tp->rcv_nxt))
+               return;  /* Special ACK sent by DCTCP to reflect ECN */
+-      tcp_dec_quickack_mode(sk, pkts);
++      tcp_dec_quickack_mode(sk);
+       inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
+ }
+@@ -1373,7 +1372,7 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb,
+                          sk, skb);
+       if (likely(tcb->tcp_flags & TCPHDR_ACK))
+-              tcp_event_ack_sent(sk, tcp_skb_pcount(skb), rcv_nxt);
++              tcp_event_ack_sent(sk, rcv_nxt);
+       if (skb->len != tcp_header_size) {
+               tcp_event_data_sent(tp, sk);
+-- 
+2.40.1
+
diff --git a/queue-6.1/tipc-fix-a-potential-deadlock-on-tx-lock.patch b/queue-6.1/tipc-fix-a-potential-deadlock-on-tx-lock.patch
new file mode 100644 (file)
index 0000000..700181f
--- /dev/null
@@ -0,0 +1,70 @@
+From 3ba9752c45507a0caccf3849323a7c936cf1d9c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Sep 2023 18:14:14 +0000
+Subject: tipc: fix a potential deadlock on &tx->lock
+
+From: Chengfeng Ye <dg573847474@gmail.com>
+
+[ Upstream commit 08e50cf071847323414df0835109b6f3560d44f5 ]
+
+It seems that tipc_crypto_key_revoke() could be be invoked by
+wokequeue tipc_crypto_work_rx() under process context and
+timer/rx callback under softirq context, thus the lock acquisition
+on &tx->lock seems better use spin_lock_bh() to prevent possible
+deadlock.
+
+This flaw was found by an experimental static analysis tool I am
+developing for irq-related deadlock.
+
+tipc_crypto_work_rx() <workqueue>
+--> tipc_crypto_key_distr()
+--> tipc_bcast_xmit()
+--> tipc_bcbase_xmit()
+--> tipc_bearer_bc_xmit()
+--> tipc_crypto_xmit()
+--> tipc_ehdr_build()
+--> tipc_crypto_key_revoke()
+--> spin_lock(&tx->lock)
+<timer interrupt>
+   --> tipc_disc_timeout()
+   --> tipc_bearer_xmit_skb()
+   --> tipc_crypto_xmit()
+   --> tipc_ehdr_build()
+   --> tipc_crypto_key_revoke()
+   --> spin_lock(&tx->lock) <deadlock here>
+
+Signed-off-by: Chengfeng Ye <dg573847474@gmail.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Acked-by: Jon Maloy <jmaloy@redhat.com>
+Fixes: fc1b6d6de220 ("tipc: introduce TIPC encryption & authentication")
+Link: https://lore.kernel.org/r/20230927181414.59928-1-dg573847474@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/crypto.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c
+index 2b236d95a6469..65f59739a041a 100644
+--- a/net/tipc/crypto.c
++++ b/net/tipc/crypto.c
+@@ -1441,14 +1441,14 @@ static int tipc_crypto_key_revoke(struct net *net, u8 tx_key)
+       struct tipc_crypto *tx = tipc_net(net)->crypto_tx;
+       struct tipc_key key;
+-      spin_lock(&tx->lock);
++      spin_lock_bh(&tx->lock);
+       key = tx->key;
+       WARN_ON(!key.active || tx_key != key.active);
+       /* Free the active key */
+       tipc_crypto_key_set_state(tx, key.passive, 0, key.pending);
+       tipc_crypto_key_detach(tx->aead[key.active], &tx->lock);
+-      spin_unlock(&tx->lock);
++      spin_unlock_bh(&tx->lock);
+       pr_warn("%s: key is revoked\n", tx->name);
+       return -EKEYREVOKED;
+-- 
+2.40.1
+
diff --git a/queue-6.1/ubi-refuse-attaching-if-mtd-s-erasesize-is-0.patch b/queue-6.1/ubi-refuse-attaching-if-mtd-s-erasesize-is-0.patch
new file mode 100644 (file)
index 0000000..76b46d4
--- /dev/null
@@ -0,0 +1,45 @@
+From e3577ea872d6ad98d1cfeabd34823618f0a00491 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Apr 2023 19:10:41 +0800
+Subject: ubi: Refuse attaching if mtd's erasesize is 0
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit 017c73a34a661a861712f7cc1393a123e5b2208c ]
+
+There exists mtd devices with zero erasesize, which will trigger a
+divide-by-zero exception while attaching ubi device.
+Fix it by refusing attaching if mtd's erasesize is 0.
+
+Fixes: 801c135ce73d ("UBI: Unsorted Block Images")
+Reported-by: Yu Hao <yhao016@ucr.edu>
+Link: https://lore.kernel.org/lkml/977347543.226888.1682011999468.JavaMail.zimbra@nod.at/T/
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/build.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
+index 1662c12e24ada..6fbd77dc1d18f 100644
+--- a/drivers/mtd/ubi/build.c
++++ b/drivers/mtd/ubi/build.c
+@@ -893,6 +893,13 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
+               return -EINVAL;
+       }
++      /* UBI cannot work on flashes with zero erasesize. */
++      if (!mtd->erasesize) {
++              pr_err("ubi: refuse attaching mtd%d - zero erasesize flash is not supported\n",
++                      mtd->index);
++              return -EINVAL;
++      }
++
+       if (ubi_num == UBI_DEV_NUM_AUTO) {
+               /* Search for an empty slot in the @ubi_devices array */
+               for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++)
+-- 
+2.40.1
+
diff --git a/queue-6.1/wifi-cfg80211-add-a-work-abstraction-with-special-se.patch b/queue-6.1/wifi-cfg80211-add-a-work-abstraction-with-special-se.patch
new file mode 100644 (file)
index 0000000..838ae2c
--- /dev/null
@@ -0,0 +1,377 @@
+From cc69ae9c246731c74fc0e1f70c1fc86734cb4700 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 14:49:25 +0200
+Subject: wifi: cfg80211: add a work abstraction with special semantics
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit a3ee4dc84c4e9d14cb34dad095fd678127aca5b6 ]
+
+Add a work abstraction at the cfg80211 level that will always
+hold the wiphy_lock() for any work executed and therefore also
+can be canceled safely (without waiting) while holding that.
+This improves on what we do now as with the new wiphy works we
+don't have to worry about locking while cancelling them safely.
+
+Also, don't let such works run while the device is suspended,
+since they'll likely need to interact with the device. Flush
+them before suspend though.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Stable-dep-of: 37c20b2effe9 ("wifi: cfg80211: fix cqm_config access race")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/cfg80211.h |  95 ++++++++++++++++++++++++++++++--
+ net/wireless/core.c    | 122 +++++++++++++++++++++++++++++++++++++++++
+ net/wireless/core.h    |   7 +++
+ net/wireless/sysfs.c   |   8 ++-
+ 4 files changed, 227 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 5976545aa26b9..f2144db89183c 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -5621,12 +5621,17 @@ struct cfg80211_cqm_config;
+  * wiphy_lock - lock the wiphy
+  * @wiphy: the wiphy to lock
+  *
+- * This is mostly exposed so it can be done around registering and
+- * unregistering netdevs that aren't created through cfg80211 calls,
+- * since that requires locking in cfg80211 when the notifiers is
+- * called, but that cannot differentiate which way it's called.
++ * This is needed around registering and unregistering netdevs that
++ * aren't created through cfg80211 calls, since that requires locking
++ * in cfg80211 when the notifiers is called, but that cannot
++ * differentiate which way it's called.
++ *
++ * It can also be used by drivers for their own purposes.
+  *
+  * When cfg80211 ops are called, the wiphy is already locked.
++ *
++ * Note that this makes sure that no workers that have been queued
++ * with wiphy_queue_work() are running.
+  */
+ static inline void wiphy_lock(struct wiphy *wiphy)
+       __acquires(&wiphy->mtx)
+@@ -5646,6 +5651,88 @@ static inline void wiphy_unlock(struct wiphy *wiphy)
+       mutex_unlock(&wiphy->mtx);
+ }
++struct wiphy_work;
++typedef void (*wiphy_work_func_t)(struct wiphy *, struct wiphy_work *);
++
++struct wiphy_work {
++      struct list_head entry;
++      wiphy_work_func_t func;
++};
++
++static inline void wiphy_work_init(struct wiphy_work *work,
++                                 wiphy_work_func_t func)
++{
++      INIT_LIST_HEAD(&work->entry);
++      work->func = func;
++}
++
++/**
++ * wiphy_work_queue - queue work for the wiphy
++ * @wiphy: the wiphy to queue for
++ * @work: the work item
++ *
++ * This is useful for work that must be done asynchronously, and work
++ * queued here has the special property that the wiphy mutex will be
++ * held as if wiphy_lock() was called, and that it cannot be running
++ * after wiphy_lock() was called. Therefore, wiphy_cancel_work() can
++ * use just cancel_work() instead of cancel_work_sync(), it requires
++ * being in a section protected by wiphy_lock().
++ */
++void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work);
++
++/**
++ * wiphy_work_cancel - cancel previously queued work
++ * @wiphy: the wiphy, for debug purposes
++ * @work: the work to cancel
++ *
++ * Cancel the work *without* waiting for it, this assumes being
++ * called under the wiphy mutex acquired by wiphy_lock().
++ */
++void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work);
++
++struct wiphy_delayed_work {
++      struct wiphy_work work;
++      struct wiphy *wiphy;
++      struct timer_list timer;
++};
++
++void wiphy_delayed_work_timer(struct timer_list *t);
++
++static inline void wiphy_delayed_work_init(struct wiphy_delayed_work *dwork,
++                                         wiphy_work_func_t func)
++{
++      timer_setup(&dwork->timer, wiphy_delayed_work_timer, 0);
++      wiphy_work_init(&dwork->work, func);
++}
++
++/**
++ * wiphy_delayed_work_queue - queue delayed work for the wiphy
++ * @wiphy: the wiphy to queue for
++ * @dwork: the delayable worker
++ * @delay: number of jiffies to wait before queueing
++ *
++ * This is useful for work that must be done asynchronously, and work
++ * queued here has the special property that the wiphy mutex will be
++ * held as if wiphy_lock() was called, and that it cannot be running
++ * after wiphy_lock() was called. Therefore, wiphy_cancel_work() can
++ * use just cancel_work() instead of cancel_work_sync(), it requires
++ * being in a section protected by wiphy_lock().
++ */
++void wiphy_delayed_work_queue(struct wiphy *wiphy,
++                            struct wiphy_delayed_work *dwork,
++                            unsigned long delay);
++
++/**
++ * wiphy_delayed_work_cancel - cancel previously queued delayed work
++ * @wiphy: the wiphy, for debug purposes
++ * @dwork: the delayed work to cancel
++ *
++ * Cancel the work *without* waiting for it, this assumes being
++ * called under the wiphy mutex acquired by wiphy_lock().
++ */
++void wiphy_delayed_work_cancel(struct wiphy *wiphy,
++                             struct wiphy_delayed_work *dwork);
++
+ /**
+  * struct wireless_dev - wireless device state
+  *
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 28ae86c62f805..8a1f34e95c4f0 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -408,6 +408,34 @@ static void cfg80211_propagate_cac_done_wk(struct work_struct *work)
+       rtnl_unlock();
+ }
++static void cfg80211_wiphy_work(struct work_struct *work)
++{
++      struct cfg80211_registered_device *rdev;
++      struct wiphy_work *wk;
++
++      rdev = container_of(work, struct cfg80211_registered_device, wiphy_work);
++
++      wiphy_lock(&rdev->wiphy);
++      if (rdev->suspended)
++              goto out;
++
++      spin_lock_irq(&rdev->wiphy_work_lock);
++      wk = list_first_entry_or_null(&rdev->wiphy_work_list,
++                                    struct wiphy_work, entry);
++      if (wk) {
++              list_del_init(&wk->entry);
++              if (!list_empty(&rdev->wiphy_work_list))
++                      schedule_work(work);
++              spin_unlock_irq(&rdev->wiphy_work_lock);
++
++              wk->func(&rdev->wiphy, wk);
++      } else {
++              spin_unlock_irq(&rdev->wiphy_work_lock);
++      }
++out:
++      wiphy_unlock(&rdev->wiphy);
++}
++
+ /* exported functions */
+ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
+@@ -533,6 +561,9 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
+               return NULL;
+       }
++      INIT_WORK(&rdev->wiphy_work, cfg80211_wiphy_work);
++      INIT_LIST_HEAD(&rdev->wiphy_work_list);
++      spin_lock_init(&rdev->wiphy_work_lock);
+       INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work);
+       INIT_WORK(&rdev->conn_work, cfg80211_conn_work);
+       INIT_WORK(&rdev->event_work, cfg80211_event_work);
+@@ -1011,6 +1042,31 @@ void wiphy_rfkill_start_polling(struct wiphy *wiphy)
+ }
+ EXPORT_SYMBOL(wiphy_rfkill_start_polling);
++void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev)
++{
++      unsigned int runaway_limit = 100;
++      unsigned long flags;
++
++      lockdep_assert_held(&rdev->wiphy.mtx);
++
++      spin_lock_irqsave(&rdev->wiphy_work_lock, flags);
++      while (!list_empty(&rdev->wiphy_work_list)) {
++              struct wiphy_work *wk;
++
++              wk = list_first_entry(&rdev->wiphy_work_list,
++                                    struct wiphy_work, entry);
++              list_del_init(&wk->entry);
++              spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags);
++
++              wk->func(&rdev->wiphy, wk);
++
++              spin_lock_irqsave(&rdev->wiphy_work_lock, flags);
++              if (WARN_ON(--runaway_limit == 0))
++                      INIT_LIST_HEAD(&rdev->wiphy_work_list);
++      }
++      spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags);
++}
++
+ void wiphy_unregister(struct wiphy *wiphy)
+ {
+       struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+@@ -1053,9 +1109,15 @@ void wiphy_unregister(struct wiphy *wiphy)
+       if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup)
+               rdev_set_wakeup(rdev, false);
+ #endif
++
++      /* surely nothing is reachable now, clean up work */
++      cfg80211_process_wiphy_works(rdev);
+       wiphy_unlock(&rdev->wiphy);
+       rtnl_unlock();
++      /* this has nothing to do now but make sure it's gone */
++      cancel_work_sync(&rdev->wiphy_work);
++
+       flush_work(&rdev->scan_done_wk);
+       cancel_work_sync(&rdev->conn_work);
+       flush_work(&rdev->event_work);
+@@ -1546,6 +1608,66 @@ static struct pernet_operations cfg80211_pernet_ops = {
+       .exit = cfg80211_pernet_exit,
+ };
++void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work)
++{
++      struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
++      unsigned long flags;
++
++      spin_lock_irqsave(&rdev->wiphy_work_lock, flags);
++      if (list_empty(&work->entry))
++              list_add_tail(&work->entry, &rdev->wiphy_work_list);
++      spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags);
++
++      schedule_work(&rdev->wiphy_work);
++}
++EXPORT_SYMBOL_GPL(wiphy_work_queue);
++
++void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work)
++{
++      struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
++      unsigned long flags;
++
++      lockdep_assert_held(&wiphy->mtx);
++
++      spin_lock_irqsave(&rdev->wiphy_work_lock, flags);
++      if (!list_empty(&work->entry))
++              list_del_init(&work->entry);
++      spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags);
++}
++EXPORT_SYMBOL_GPL(wiphy_work_cancel);
++
++void wiphy_delayed_work_timer(struct timer_list *t)
++{
++      struct wiphy_delayed_work *dwork = from_timer(dwork, t, timer);
++
++      wiphy_work_queue(dwork->wiphy, &dwork->work);
++}
++EXPORT_SYMBOL(wiphy_delayed_work_timer);
++
++void wiphy_delayed_work_queue(struct wiphy *wiphy,
++                            struct wiphy_delayed_work *dwork,
++                            unsigned long delay)
++{
++      if (!delay) {
++              wiphy_work_queue(wiphy, &dwork->work);
++              return;
++      }
++
++      dwork->wiphy = wiphy;
++      mod_timer(&dwork->timer, jiffies + delay);
++}
++EXPORT_SYMBOL_GPL(wiphy_delayed_work_queue);
++
++void wiphy_delayed_work_cancel(struct wiphy *wiphy,
++                             struct wiphy_delayed_work *dwork)
++{
++      lockdep_assert_held(&wiphy->mtx);
++
++      del_timer_sync(&dwork->timer);
++      wiphy_work_cancel(wiphy, &dwork->work);
++}
++EXPORT_SYMBOL_GPL(wiphy_delayed_work_cancel);
++
+ static int __init cfg80211_init(void)
+ {
+       int err;
+diff --git a/net/wireless/core.h b/net/wireless/core.h
+index 775e16cb99eda..0481a8a539d5d 100644
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -108,6 +108,12 @@ struct cfg80211_registered_device {
+       /* lock for all wdev lists */
+       spinlock_t mgmt_registrations_lock;
++      struct work_struct wiphy_work;
++      struct list_head wiphy_work_list;
++      /* protects the list above */
++      spinlock_t wiphy_work_lock;
++      bool suspended;
++
+       /* must be last because of the way we do wiphy_priv(),
+        * and it should at least be aligned to NETDEV_ALIGN */
+       struct wiphy wiphy __aligned(NETDEV_ALIGN);
+@@ -450,6 +456,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
+                         struct net_device *dev, enum nl80211_iftype ntype,
+                         struct vif_params *params);
+ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
++void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev);
+ void cfg80211_process_wdev_events(struct wireless_dev *wdev);
+ bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range,
+diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
+index 0c3f05c9be27a..4d3b658030105 100644
+--- a/net/wireless/sysfs.c
++++ b/net/wireless/sysfs.c
+@@ -5,7 +5,7 @@
+  *
+  * Copyright 2005-2006        Jiri Benc <jbenc@suse.cz>
+  * Copyright 2006     Johannes Berg <johannes@sipsolutions.net>
+- * Copyright (C) 2020-2021 Intel Corporation
++ * Copyright (C) 2020-2021, 2023 Intel Corporation
+  */
+ #include <linux/device.h>
+@@ -105,14 +105,18 @@ static int wiphy_suspend(struct device *dev)
+                       cfg80211_leave_all(rdev);
+                       cfg80211_process_rdev_events(rdev);
+               }
++              cfg80211_process_wiphy_works(rdev);
+               if (rdev->ops->suspend)
+                       ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config);
+               if (ret == 1) {
+                       /* Driver refuse to configure wowlan */
+                       cfg80211_leave_all(rdev);
+                       cfg80211_process_rdev_events(rdev);
++                      cfg80211_process_wiphy_works(rdev);
+                       ret = rdev_suspend(rdev, NULL);
+               }
++              if (ret == 0)
++                      rdev->suspended = true;
+       }
+       wiphy_unlock(&rdev->wiphy);
+       rtnl_unlock();
+@@ -132,6 +136,8 @@ static int wiphy_resume(struct device *dev)
+       wiphy_lock(&rdev->wiphy);
+       if (rdev->wiphy.registered && rdev->ops->resume)
+               ret = rdev_resume(rdev);
++      rdev->suspended = false;
++      schedule_work(&rdev->wiphy_work);
+       wiphy_unlock(&rdev->wiphy);
+       if (ret)
+-- 
+2.40.1
+
diff --git a/queue-6.1/wifi-cfg80211-add-missing-kernel-doc-for-cqm_rssi_wo.patch b/queue-6.1/wifi-cfg80211-add-missing-kernel-doc-for-cqm_rssi_wo.patch
new file mode 100644 (file)
index 0000000..a34fe6e
--- /dev/null
@@ -0,0 +1,35 @@
+From 6fd718a4892b387cbb034475cf5d4a050350db0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Sep 2023 09:36:57 +0200
+Subject: wifi: cfg80211: add missing kernel-doc for cqm_rssi_work
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit d1383077c225ceb87ac7a3b56b2c505193f77ed7 ]
+
+As reported by Stephen, I neglected to add the kernel-doc
+for the new struct member. Fix that.
+
+Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
+Fixes: 37c20b2effe9 ("wifi: cfg80211: fix cqm_config access race")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/cfg80211.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index ab64bb94c92fd..7a6c3059d50b5 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -5805,6 +5805,7 @@ void wiphy_delayed_work_cancel(struct wiphy *wiphy,
+  * @event_lock: (private) lock for event list
+  * @owner_nlportid: (private) owner socket port ID
+  * @nl_owner_dead: (private) owner socket went away
++ * @cqm_rssi_work: (private) CQM RSSI reporting work
+  * @cqm_config: (private) nl80211 RSSI monitor state
+  * @pmsr_list: (private) peer measurement requests
+  * @pmsr_lock: (private) peer measurements requests/results lock
+-- 
+2.40.1
+
diff --git a/queue-6.1/wifi-cfg80211-fix-cqm_config-access-race.patch b/queue-6.1/wifi-cfg80211-fix-cqm_config-access-race.patch
new file mode 100644 (file)
index 0000000..8df5598
--- /dev/null
@@ -0,0 +1,330 @@
+From d9f62a9614369b0b0f5007cd2500f477c1919047 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Aug 2023 15:38:04 +0200
+Subject: wifi: cfg80211: fix cqm_config access race
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 37c20b2effe987b806c8de6d12978e4ffeff026f ]
+
+Max Schulze reports crashes with brcmfmac. The reason seems
+to be a race between userspace removing the CQM config and
+the driver calling cfg80211_cqm_rssi_notify(), where if the
+data is freed while cfg80211_cqm_rssi_notify() runs it will
+crash since it assumes wdev->cqm_config is set. This can't
+be fixed with a simple non-NULL check since there's nothing
+we can do for locking easily, so use RCU instead to protect
+the pointer, but that requires pulling the updates out into
+an asynchronous worker so they can sleep and call back into
+the driver.
+
+Since we need to change the free anyway, also change it to
+go back to the old settings if changing the settings fails.
+
+Reported-and-tested-by: Max Schulze <max.schulze@online.de>
+Closes: https://lore.kernel.org/r/ac96309a-8d8d-4435-36e6-6d152eb31876@online.de
+Fixes: 4a4b8169501b ("cfg80211: Accept multiple RSSI thresholds for CQM")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/cfg80211.h |  3 +-
+ net/wireless/core.c    | 14 +++----
+ net/wireless/core.h    |  7 +++-
+ net/wireless/nl80211.c | 93 +++++++++++++++++++++++++++---------------
+ 4 files changed, 75 insertions(+), 42 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index f2144db89183c..ab64bb94c92fd 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -5877,7 +5877,8 @@ struct wireless_dev {
+       } wext;
+ #endif
+-      struct cfg80211_cqm_config *cqm_config;
++      struct wiphy_work cqm_rssi_work;
++      struct cfg80211_cqm_config __rcu *cqm_config;
+       struct list_head pmsr_list;
+       spinlock_t pmsr_lock;
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 8a1f34e95c4f0..2c79604672062 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1176,16 +1176,11 @@ void wiphy_rfkill_set_hw_state_reason(struct wiphy *wiphy, bool blocked,
+ }
+ EXPORT_SYMBOL(wiphy_rfkill_set_hw_state_reason);
+-void cfg80211_cqm_config_free(struct wireless_dev *wdev)
+-{
+-      kfree(wdev->cqm_config);
+-      wdev->cqm_config = NULL;
+-}
+-
+ static void _cfg80211_unregister_wdev(struct wireless_dev *wdev,
+                                     bool unregister_netdev)
+ {
+       struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
++      struct cfg80211_cqm_config *cqm_config;
+       unsigned int link_id;
+       ASSERT_RTNL();
+@@ -1224,7 +1219,10 @@ static void _cfg80211_unregister_wdev(struct wireless_dev *wdev,
+       kfree_sensitive(wdev->wext.keys);
+       wdev->wext.keys = NULL;
+ #endif
+-      cfg80211_cqm_config_free(wdev);
++      wiphy_work_cancel(wdev->wiphy, &wdev->cqm_rssi_work);
++      /* deleted from the list, so can't be found from nl80211 any more */
++      cqm_config = rcu_access_pointer(wdev->cqm_config);
++      kfree_rcu(cqm_config, rcu_head);
+       /*
+        * Ensure that all events have been processed and
+@@ -1376,6 +1374,8 @@ void cfg80211_init_wdev(struct wireless_dev *wdev)
+       wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
+ #endif
++      wiphy_work_init(&wdev->cqm_rssi_work, cfg80211_cqm_rssi_notify_work);
++
+       if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT)
+               wdev->ps = true;
+       else
+diff --git a/net/wireless/core.h b/net/wireless/core.h
+index 0481a8a539d5d..86fd79912254d 100644
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -293,12 +293,17 @@ struct cfg80211_beacon_registration {
+ };
+ struct cfg80211_cqm_config {
++      struct rcu_head rcu_head;
+       u32 rssi_hyst;
+       s32 last_rssi_event_value;
++      enum nl80211_cqm_rssi_threshold_event last_rssi_event_type;
+       int n_rssi_thresholds;
+       s32 rssi_thresholds[];
+ };
++void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy,
++                                 struct wiphy_work *work);
++
+ void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev);
+ /* free object */
+@@ -563,8 +568,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
+ #define CFG80211_DEV_WARN_ON(cond)    ({bool __r = (cond); __r; })
+ #endif
+-void cfg80211_cqm_config_free(struct wireless_dev *wdev);
+-
+ void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid);
+ void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev);
+ void cfg80211_pmsr_free_wk(struct work_struct *work);
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 12c7c89d5be1d..1d993a490ac4b 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -12565,7 +12565,8 @@ static int nl80211_set_cqm_txe(struct genl_info *info,
+ }
+ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
+-                                  struct net_device *dev)
++                                  struct net_device *dev,
++                                  struct cfg80211_cqm_config *cqm_config)
+ {
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       s32 last, low, high;
+@@ -12574,7 +12575,7 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
+       int err;
+       /* RSSI reporting disabled? */
+-      if (!wdev->cqm_config)
++      if (!cqm_config)
+               return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0);
+       /*
+@@ -12583,7 +12584,7 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
+        * connection is established and enough beacons received to calculate
+        * the average.
+        */
+-      if (!wdev->cqm_config->last_rssi_event_value &&
++      if (!cqm_config->last_rssi_event_value &&
+           wdev->links[0].client.current_bss &&
+           rdev->ops->get_station) {
+               struct station_info sinfo = {};
+@@ -12597,30 +12598,30 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
+               cfg80211_sinfo_release_content(&sinfo);
+               if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
+-                      wdev->cqm_config->last_rssi_event_value =
++                      cqm_config->last_rssi_event_value =
+                               (s8) sinfo.rx_beacon_signal_avg;
+       }
+-      last = wdev->cqm_config->last_rssi_event_value;
+-      hyst = wdev->cqm_config->rssi_hyst;
+-      n = wdev->cqm_config->n_rssi_thresholds;
++      last = cqm_config->last_rssi_event_value;
++      hyst = cqm_config->rssi_hyst;
++      n = cqm_config->n_rssi_thresholds;
+       for (i = 0; i < n; i++) {
+               i = array_index_nospec(i, n);
+-              if (last < wdev->cqm_config->rssi_thresholds[i])
++              if (last < cqm_config->rssi_thresholds[i])
+                       break;
+       }
+       low_index = i - 1;
+       if (low_index >= 0) {
+               low_index = array_index_nospec(low_index, n);
+-              low = wdev->cqm_config->rssi_thresholds[low_index] - hyst;
++              low = cqm_config->rssi_thresholds[low_index] - hyst;
+       } else {
+               low = S32_MIN;
+       }
+       if (i < n) {
+               i = array_index_nospec(i, n);
+-              high = wdev->cqm_config->rssi_thresholds[i] + hyst - 1;
++              high = cqm_config->rssi_thresholds[i] + hyst - 1;
+       } else {
+               high = S32_MAX;
+       }
+@@ -12633,6 +12634,7 @@ static int nl80211_set_cqm_rssi(struct genl_info *info,
+                               u32 hysteresis)
+ {
+       struct cfg80211_registered_device *rdev = info->user_ptr[0];
++      struct cfg80211_cqm_config *cqm_config = NULL, *old;
+       struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       int i, err;
+@@ -12650,10 +12652,6 @@ static int nl80211_set_cqm_rssi(struct genl_info *info,
+           wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
+               return -EOPNOTSUPP;
+-      wdev_lock(wdev);
+-      cfg80211_cqm_config_free(wdev);
+-      wdev_unlock(wdev);
+-
+       if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) {
+               if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */
+                       return rdev_set_cqm_rssi_config(rdev, dev, 0, 0);
+@@ -12670,9 +12668,10 @@ static int nl80211_set_cqm_rssi(struct genl_info *info,
+               n_thresholds = 0;
+       wdev_lock(wdev);
+-      if (n_thresholds) {
+-              struct cfg80211_cqm_config *cqm_config;
++      old = rcu_dereference_protected(wdev->cqm_config,
++                                      lockdep_is_held(&wdev->mtx));
++      if (n_thresholds) {
+               cqm_config = kzalloc(struct_size(cqm_config, rssi_thresholds,
+                                                n_thresholds),
+                                    GFP_KERNEL);
+@@ -12687,11 +12686,18 @@ static int nl80211_set_cqm_rssi(struct genl_info *info,
+                      flex_array_size(cqm_config, rssi_thresholds,
+                                      n_thresholds));
+-              wdev->cqm_config = cqm_config;
++              rcu_assign_pointer(wdev->cqm_config, cqm_config);
++      } else {
++              RCU_INIT_POINTER(wdev->cqm_config, NULL);
+       }
+-      err = cfg80211_cqm_rssi_update(rdev, dev);
+-
++      err = cfg80211_cqm_rssi_update(rdev, dev, cqm_config);
++      if (err) {
++              rcu_assign_pointer(wdev->cqm_config, old);
++              kfree_rcu(cqm_config, rcu_head);
++      } else {
++              kfree_rcu(old, rcu_head);
++      }
+ unlock:
+       wdev_unlock(wdev);
+@@ -18719,9 +18725,8 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
+                             enum nl80211_cqm_rssi_threshold_event rssi_event,
+                             s32 rssi_level, gfp_t gfp)
+ {
+-      struct sk_buff *msg;
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+-      struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
++      struct cfg80211_cqm_config *cqm_config;
+       trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level);
+@@ -18729,18 +18734,41 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
+                   rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
+               return;
+-      if (wdev->cqm_config) {
+-              wdev->cqm_config->last_rssi_event_value = rssi_level;
++      rcu_read_lock();
++      cqm_config = rcu_dereference(wdev->cqm_config);
++      if (cqm_config) {
++              cqm_config->last_rssi_event_value = rssi_level;
++              cqm_config->last_rssi_event_type = rssi_event;
++              wiphy_work_queue(wdev->wiphy, &wdev->cqm_rssi_work);
++      }
++      rcu_read_unlock();
++}
++EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
++
++void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy, struct wiphy_work *work)
++{
++      struct wireless_dev *wdev = container_of(work, struct wireless_dev,
++                                               cqm_rssi_work);
++      struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
++      enum nl80211_cqm_rssi_threshold_event rssi_event;
++      struct cfg80211_cqm_config *cqm_config;
++      struct sk_buff *msg;
++      s32 rssi_level;
+-              cfg80211_cqm_rssi_update(rdev, dev);
++      wdev_lock(wdev);
++      cqm_config = rcu_dereference_protected(wdev->cqm_config,
++                                             lockdep_is_held(&wdev->mtx));
++      if (!wdev->cqm_config)
++              goto unlock;
+-              if (rssi_level == 0)
+-                      rssi_level = wdev->cqm_config->last_rssi_event_value;
+-      }
++      cfg80211_cqm_rssi_update(rdev, wdev->netdev, cqm_config);
+-      msg = cfg80211_prepare_cqm(dev, NULL, gfp);
++      rssi_level = cqm_config->last_rssi_event_value;
++      rssi_event = cqm_config->last_rssi_event_type;
++
++      msg = cfg80211_prepare_cqm(wdev->netdev, NULL, GFP_KERNEL);
+       if (!msg)
+-              return;
++              goto unlock;
+       if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
+                       rssi_event))
+@@ -18750,14 +18778,15 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
+                                     rssi_level))
+               goto nla_put_failure;
+-      cfg80211_send_cqm(msg, gfp);
++      cfg80211_send_cqm(msg, GFP_KERNEL);
+-      return;
++      goto unlock;
+  nla_put_failure:
+       nlmsg_free(msg);
++ unlock:
++      wdev_unlock(wdev);
+ }
+-EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
+ void cfg80211_cqm_txe_notify(struct net_device *dev,
+                            const u8 *peer, u32 num_packets,
+-- 
+2.40.1
+
diff --git a/queue-6.1/wifi-cfg80211-hold-wiphy-lock-in-auto-disconnect.patch b/queue-6.1/wifi-cfg80211-hold-wiphy-lock-in-auto-disconnect.patch
new file mode 100644 (file)
index 0000000..d80797b
--- /dev/null
@@ -0,0 +1,76 @@
+From 529ae57eb2d26afdd940af0f8413082c8c08367f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 14:49:20 +0200
+Subject: wifi: cfg80211: hold wiphy lock in auto-disconnect
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit e9da6df7492a981b071bafd169fb4c35b45f5ebf ]
+
+Most code paths in cfg80211 already hold the wiphy lock,
+mostly by virtue of being called from nl80211, so make
+the auto-disconnect worker also hold it, aligning the
+locking promises between different parts of cfg80211.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Stable-dep-of: 37c20b2effe9 ("wifi: cfg80211: fix cqm_config access race")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/core.c | 6 ++----
+ net/wireless/sme.c  | 4 +++-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 609b79fe4a748..9ac7c54379cf3 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1162,10 +1162,6 @@ static void _cfg80211_unregister_wdev(struct wireless_dev *wdev,
+       kfree_sensitive(wdev->wext.keys);
+       wdev->wext.keys = NULL;
+ #endif
+-      /* only initialized if we have a netdev */
+-      if (wdev->netdev)
+-              flush_work(&wdev->disconnect_wk);
+-
+       cfg80211_cqm_config_free(wdev);
+       /*
+@@ -1439,6 +1435,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
+               cfg80211_leave(rdev, wdev);
+               cfg80211_remove_links(wdev);
+               wiphy_unlock(&rdev->wiphy);
++              /* since we just did cfg80211_leave() nothing to do there */
++              cancel_work_sync(&wdev->disconnect_wk);
+               break;
+       case NETDEV_DOWN:
+               wiphy_lock(&rdev->wiphy);
+diff --git a/net/wireless/sme.c b/net/wireless/sme.c
+index 6e87d2cd83456..b97834284baef 100644
+--- a/net/wireless/sme.c
++++ b/net/wireless/sme.c
+@@ -5,7 +5,7 @@
+  * (for nl80211's connect() and wext)
+  *
+  * Copyright 2009     Johannes Berg <johannes@sipsolutions.net>
+- * Copyright (C) 2009, 2020, 2022 Intel Corporation. All rights reserved.
++ * Copyright (C) 2009, 2020, 2022-2023 Intel Corporation. All rights reserved.
+  * Copyright 2017     Intel Deutschland GmbH
+  */
+@@ -1555,6 +1555,7 @@ void cfg80211_autodisconnect_wk(struct work_struct *work)
+               container_of(work, struct wireless_dev, disconnect_wk);
+       struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
++      wiphy_lock(wdev->wiphy);
+       wdev_lock(wdev);
+       if (wdev->conn_owner_nlportid) {
+@@ -1593,4 +1594,5 @@ void cfg80211_autodisconnect_wk(struct work_struct *work)
+       }
+       wdev_unlock(wdev);
++      wiphy_unlock(wdev->wiphy);
+ }
+-- 
+2.40.1
+
diff --git a/queue-6.1/wifi-cfg80211-move-wowlan-disable-under-locks.patch b/queue-6.1/wifi-cfg80211-move-wowlan-disable-under-locks.patch
new file mode 100644 (file)
index 0000000..69d401f
--- /dev/null
@@ -0,0 +1,51 @@
+From c319b0ed6daf30cd719f1a95c5181f395330ce6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 14:49:22 +0200
+Subject: wifi: cfg80211: move wowlan disable under locks
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit a993df0f9143e63eca38c96a30daf08db99a98a3 ]
+
+This is a driver callback, and the driver should be able
+to assume that it's called with the wiphy lock held. Move
+the call up so that's true, it has no other effect since
+the device is already unregistering and we cannot reach
+this function through other paths.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Stable-dep-of: 37c20b2effe9 ("wifi: cfg80211: fix cqm_config access race")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/core.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 9ac7c54379cf3..28ae86c62f805 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1049,6 +1049,10 @@ void wiphy_unregister(struct wiphy *wiphy)
+       cfg80211_rdev_list_generation++;
+       device_del(&rdev->wiphy.dev);
++#ifdef CONFIG_PM
++      if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup)
++              rdev_set_wakeup(rdev, false);
++#endif
+       wiphy_unlock(&rdev->wiphy);
+       rtnl_unlock();
+@@ -1064,10 +1068,6 @@ void wiphy_unregister(struct wiphy *wiphy)
+       flush_work(&rdev->mgmt_registrations_update_wk);
+       flush_work(&rdev->background_cac_abort_wk);
+-#ifdef CONFIG_PM
+-      if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup)
+-              rdev_set_wakeup(rdev, false);
+-#endif
+       cfg80211_rdev_free_wowlan(rdev);
+       cfg80211_rdev_free_coalesce(rdev);
+ }
+-- 
+2.40.1
+
diff --git a/queue-6.1/wifi-iwlwifi-dbg_ini-fix-structure-packing.patch b/queue-6.1/wifi-iwlwifi-dbg_ini-fix-structure-packing.patch
new file mode 100644 (file)
index 0000000..c4ba5ae
--- /dev/null
@@ -0,0 +1,50 @@
+From 18c35fa7d73ce7ea4182d5ecacbf278b9be9e30c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 11:03:34 +0200
+Subject: wifi: iwlwifi: dbg_ini: fix structure packing
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 424c82e8ad56756bb98b08268ffcf68d12d183eb ]
+
+The iwl_fw_ini_error_dump_range structure has conflicting alignment
+requirements for the inner union and the outer struct:
+
+In file included from drivers/net/wireless/intel/iwlwifi/fw/dbg.c:9:
+drivers/net/wireless/intel/iwlwifi/fw/error-dump.h:312:2: error: field  within 'struct iwl_fw_ini_error_dump_range' is less aligned than 'union iwl_fw_ini_error_dump_range::(anonymous at drivers/net/wireless/intel/iwlwifi/fw/error-dump.h:312:2)' and is usually due to 'struct iwl_fw_ini_error_dump_range' being packed, which can lead to unaligned accesses [-Werror,-Wunaligned-access]
+        union {
+
+As the original intention was apparently to make the entire structure
+unaligned, mark the innermost members the same way so the union
+becomes packed as well.
+
+Fixes: 973193554cae6 ("iwlwifi: dbg_ini: dump headers cleanup")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230616090343.2454061-1-arnd@kernel.org
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/fw/error-dump.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
+index c62576e442bdf..2d481849a9c23 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
+@@ -295,9 +295,9 @@ struct iwl_fw_ini_fifo_hdr {
+ struct iwl_fw_ini_error_dump_range {
+       __le32 range_data_size;
+       union {
+-              __le32 internal_base_addr;
+-              __le64 dram_base_addr;
+-              __le32 page_num;
++              __le32 internal_base_addr __packed;
++              __le64 dram_base_addr __packed;
++              __le32 page_num __packed;
+               struct iwl_fw_ini_fifo_hdr fifo_hdr;
+               struct iwl_cmd_header fw_pkt_hdr;
+       };
+-- 
+2.40.1
+
diff --git a/queue-6.1/wifi-iwlwifi-mvm-fix-a-memory-corruption-issue.patch b/queue-6.1/wifi-iwlwifi-mvm-fix-a-memory-corruption-issue.patch
new file mode 100644 (file)
index 0000000..59bc332
--- /dev/null
@@ -0,0 +1,63 @@
+From 1e77cf2616bd4f72edab7f67441982b252b8f8e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jul 2023 22:24:59 +0200
+Subject: wifi: iwlwifi: mvm: Fix a memory corruption issue
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 8ba438ef3cacc4808a63ed0ce24d4f0942cfe55d ]
+
+A few lines above, space is kzalloc()'ed for:
+       sizeof(struct iwl_nvm_data) +
+       sizeof(struct ieee80211_channel) +
+       sizeof(struct ieee80211_rate)
+
+'mvm->nvm_data' is a 'struct iwl_nvm_data', so it is fine.
+
+At the end of this structure, there is the 'channels' flex array.
+Each element is of type 'struct ieee80211_channel'.
+So only 1 element is allocated in this array.
+
+When doing:
+  mvm->nvm_data->bands[0].channels = mvm->nvm_data->channels;
+We point at the first element of the 'channels' flex array.
+So this is fine.
+
+However, when doing:
+  mvm->nvm_data->bands[0].bitrates =
+                       (void *)((u8 *)mvm->nvm_data->channels + 1);
+because of the "(u8 *)" cast, we add only 1 to the address of the beginning
+of the flex array.
+
+It is likely that we want point at the 'struct ieee80211_rate' allocated
+just after.
+
+Remove the spurious casting so that the pointer arithmetic works as
+expected.
+
+Fixes: 8ca151b568b6 ("iwlwifi: add the MVM driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/23f0ec986ef1529055f4f93dcb3940a6cf8d9a94.1690143750.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+index 887d0789c96c3..2e3c98eaa400c 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+@@ -796,7 +796,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm)
+               mvm->nvm_data->bands[0].n_channels = 1;
+               mvm->nvm_data->bands[0].n_bitrates = 1;
+               mvm->nvm_data->bands[0].bitrates =
+-                      (void *)((u8 *)mvm->nvm_data->channels + 1);
++                      (void *)(mvm->nvm_data->channels + 1);
+               mvm->nvm_data->bands[0].bitrates->hw_value = 10;
+       }
+-- 
+2.40.1
+
diff --git a/queue-6.1/wifi-mac80211-fix-potential-key-use-after-free.patch b/queue-6.1/wifi-mac80211-fix-potential-key-use-after-free.patch
new file mode 100644 (file)
index 0000000..0247d5c
--- /dev/null
@@ -0,0 +1,58 @@
+From f5f82238f8d774751dea488297257f5ab91b6764 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Sep 2023 08:34:15 +0200
+Subject: wifi: mac80211: fix potential key use-after-free
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 31db78a4923ef5e2008f2eed321811ca79e7f71b ]
+
+When ieee80211_key_link() is called by ieee80211_gtk_rekey_add()
+but returns 0 due to KRACK protection (identical key reinstall),
+ieee80211_gtk_rekey_add() will still return a pointer into the
+key, in a potential use-after-free. This normally doesn't happen
+since it's only called by iwlwifi in case of WoWLAN rekey offload
+which has its own KRACK protection, but still better to fix, do
+that by returning an error code and converting that to success on
+the cfg80211 boundary only, leaving the error for bad callers of
+ieee80211_gtk_rekey_add().
+
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Fixes: fdf7cb4185b6 ("mac80211: accept key reinstall without changing anything")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/cfg.c | 3 +++
+ net/mac80211/key.c | 2 +-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index cf3453b532d67..0167413d56972 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -566,6 +566,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
+       }
+       err = ieee80211_key_link(key, link, sta);
++      /* KRACK protection, shouldn't happen but just silently accept key */
++      if (err == -EALREADY)
++              err = 0;
+  out_unlock:
+       mutex_unlock(&local->sta_mtx);
+diff --git a/net/mac80211/key.c b/net/mac80211/key.c
+index e8f6c1e5eabfc..23bb24243c6e9 100644
+--- a/net/mac80211/key.c
++++ b/net/mac80211/key.c
+@@ -901,7 +901,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
+        */
+       if (ieee80211_key_identical(sdata, old_key, key)) {
+               ieee80211_key_free_unused(key);
+-              ret = 0;
++              ret = -EALREADY;
+               goto out;
+       }
+-- 
+2.40.1
+
diff --git a/queue-6.1/wifi-mt76-mt76x02-fix-mt76x0-external-lna-gain-handl.patch b/queue-6.1/wifi-mt76-mt76x02-fix-mt76x0-external-lna-gain-handl.patch
new file mode 100644 (file)
index 0000000..edc35e5
--- /dev/null
@@ -0,0 +1,78 @@
+From fefa6bff101e8caedac02461280e51e6976d351e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Sep 2023 21:47:47 +0200
+Subject: wifi: mt76: mt76x02: fix MT76x0 external LNA gain handling
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit 684e45e120b82deccaf8b85633905304a3bbf56d ]
+
+On MT76x0, LNA gain should be applied for both external and internal LNA.
+On MT76x2, LNA gain should be treated as 0 for external LNA.
+Move the LNA type based logic to mt76x2 in order to fix mt76x0.
+
+Fixes: 2daa67588f34 ("mt76x0: unify lna_gain parsing")
+Reported-by: Shiji Yang <yangshiji66@outlook.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230919194747.31647-1-nbd@nbd.name
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c |  7 -------
+ drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c  | 13 +++++++++++--
+ 2 files changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c
+index 0acabba2d1a50..5d402cf2951cb 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c
+@@ -131,15 +131,8 @@ u8 mt76x02_get_lna_gain(struct mt76x02_dev *dev,
+                       s8 *lna_2g, s8 *lna_5g,
+                       struct ieee80211_channel *chan)
+ {
+-      u16 val;
+       u8 lna;
+-      val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1);
+-      if (val & MT_EE_NIC_CONF_1_LNA_EXT_2G)
+-              *lna_2g = 0;
+-      if (val & MT_EE_NIC_CONF_1_LNA_EXT_5G)
+-              memset(lna_5g, 0, sizeof(s8) * 3);
+-
+       if (chan->band == NL80211_BAND_2GHZ)
+               lna = *lna_2g;
+       else if (chan->hw_value <= 64)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
+index c57e05a5c65e4..91807bf662dde 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
+@@ -256,7 +256,8 @@ void mt76x2_read_rx_gain(struct mt76x02_dev *dev)
+       struct ieee80211_channel *chan = dev->mphy.chandef.chan;
+       int channel = chan->hw_value;
+       s8 lna_5g[3], lna_2g;
+-      u8 lna;
++      bool use_lna;
++      u8 lna = 0;
+       u16 val;
+       if (chan->band == NL80211_BAND_2GHZ)
+@@ -275,7 +276,15 @@ void mt76x2_read_rx_gain(struct mt76x02_dev *dev)
+       dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16;
+       dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24;
+-      lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan);
++      val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1);
++      if (chan->band == NL80211_BAND_2GHZ)
++              use_lna = !(val & MT_EE_NIC_CONF_1_LNA_EXT_2G);
++      else
++              use_lna = !(val & MT_EE_NIC_CONF_1_LNA_EXT_5G);
++
++      if (use_lna)
++              lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan);
++
+       dev->cal.rx.lna_gain = mt76x02_sign_extend(lna, 8);
+ }
+ EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain);
+-- 
+2.40.1
+
diff --git a/queue-6.1/wifi-mwifiex-fix-oob-check-condition-in-mwifiex_proc.patch b/queue-6.1/wifi-mwifiex-fix-oob-check-condition-in-mwifiex_proc.patch
new file mode 100644 (file)
index 0000000..f240c95
--- /dev/null
@@ -0,0 +1,61 @@
+From c6a9b1821e0e82f5ed4c46fbe703342e8e290de7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Sep 2023 18:41:12 +0800
+Subject: wifi: mwifiex: Fix oob check condition in mwifiex_process_rx_packet
+
+From: Pin-yen Lin <treapking@chromium.org>
+
+[ Upstream commit aef7a0300047e7b4707ea0411dc9597cba108fc8 ]
+
+Only skip the code path trying to access the rfc1042 headers when the
+buffer is too small, so the driver can still process packets without
+rfc1042 headers.
+
+Fixes: 119585281617 ("wifi: mwifiex: Fix OOB and integer underflow when rx packets")
+Signed-off-by: Pin-yen Lin <treapking@chromium.org>
+Acked-by: Brian Norris <briannorris@chromium.org>
+Reviewed-by: Matthew Wang <matthewmwang@chromium.org>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230908104308.1546501-1-treapking@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/sta_rx.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/sta_rx.c b/drivers/net/wireless/marvell/mwifiex/sta_rx.c
+index 65420ad674167..257737137cd70 100644
+--- a/drivers/net/wireless/marvell/mwifiex/sta_rx.c
++++ b/drivers/net/wireless/marvell/mwifiex/sta_rx.c
+@@ -86,7 +86,8 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
+       rx_pkt_len = le16_to_cpu(local_rx_pd->rx_pkt_length);
+       rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_off;
+-      if (sizeof(*rx_pkt_hdr) + rx_pkt_off > skb->len) {
++      if (sizeof(rx_pkt_hdr->eth803_hdr) + sizeof(rfc1042_header) +
++          rx_pkt_off > skb->len) {
+               mwifiex_dbg(priv->adapter, ERROR,
+                           "wrong rx packet offset: len=%d, rx_pkt_off=%d\n",
+                           skb->len, rx_pkt_off);
+@@ -95,12 +96,13 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
+               return -1;
+       }
+-      if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
+-                   sizeof(bridge_tunnel_header))) ||
+-          (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
+-                   sizeof(rfc1042_header)) &&
+-           ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP &&
+-           ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX)) {
++      if (sizeof(*rx_pkt_hdr) + rx_pkt_off <= skb->len &&
++          ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
++                    sizeof(bridge_tunnel_header))) ||
++           (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
++                    sizeof(rfc1042_header)) &&
++            ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP &&
++            ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX))) {
+               /*
+                *  Replace the 803 header and rfc1042 header (llc/snap) with an
+                *    EthernetII header, keep the src/dst and snap_type
+-- 
+2.40.1
+