]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Sun, 27 Nov 2022 19:07:01 +0000 (14:07 -0500)
committerSasha Levin <sashal@kernel.org>
Sun, 27 Nov 2022 19:07:01 +0000 (14:07 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
80 files changed:
queue-5.15/9p-fd-fix-issue-of-list_del-corruption-in-p9_fd_canc.patch [new file with mode: 0644]
queue-5.15/af_key-fix-send_acquire-race-with-pfkey_register.patch [new file with mode: 0644]
queue-5.15/arcnet-fix-potential-memory-leak-in-com20020_probe.patch [new file with mode: 0644]
queue-5.15/arm-dts-am335x-pcm-953-define-fixed-regulators-in-ro.patch [new file with mode: 0644]
queue-5.15/arm-dts-at91-sam9g20ek-enable-udc-vbus-gpio-pinctrl.patch [new file with mode: 0644]
queue-5.15/arm-dts-imx6q-prti6q-fix-ref-tcxo-clock-frequency-pr.patch [new file with mode: 0644]
queue-5.15/arm-mxs-fix-memory-leak-in-mxs_machine_init.patch [new file with mode: 0644]
queue-5.15/asoc-hdac_hda-fix-hda-pcm-buffer-overflow-issue.patch [new file with mode: 0644]
queue-5.15/asoc-max98373-add-checks-for-devm_kcalloc.patch [new file with mode: 0644]
queue-5.15/asoc-sgtl5000-reset-the-chip_clk_ctrl-reg-on-remove.patch [new file with mode: 0644]
queue-5.15/asoc-soc-pcm-don-t-zero-tdm-masks-in-__soc_pcm_open.patch [new file with mode: 0644]
queue-5.15/bnx2x-fix-pci-device-refcount-leak-in-bnx2x_vf_is_pc.patch [new file with mode: 0644]
queue-5.15/bus-sunxi-rsb-remove-the-shutdown-callback.patch [new file with mode: 0644]
queue-5.15/bus-sunxi-rsb-support-atomic-transfers.patch [new file with mode: 0644]
queue-5.15/dccp-tcp-reset-saddr-on-failure-after-inet6-_hash_co.patch [new file with mode: 0644]
queue-5.15/dma-buf-fix-racing-conflict-of-dma_heap_add.patch [new file with mode: 0644]
queue-5.15/drivers-hv-vmbus-fix-double-free-in-the-error-path-o.patch [new file with mode: 0644]
queue-5.15/drivers-hv-vmbus-fix-possible-memory-leak-in-vmbus_d.patch [new file with mode: 0644]
queue-5.15/fs-do-not-update-freeing-inode-i_io_list.patch [new file with mode: 0644]
queue-5.15/iavf-do-not-restart-tx-queues-after-reset-task-failu.patch [new file with mode: 0644]
queue-5.15/iavf-fix-a-crash-during-reset-task.patch [new file with mode: 0644]
queue-5.15/iavf-fix-race-condition-between-iavf_shutdown-and-ia.patch [new file with mode: 0644]
queue-5.15/ipv4-fix-error-return-code-in-fib_table_insert.patch [new file with mode: 0644]
queue-5.15/macsec-fix-invalid-error-code-set.patch [new file with mode: 0644]
queue-5.15/net-dsa-sja1105-disallow-c45-transactions-on-the-bas.patch [new file with mode: 0644]
queue-5.15/net-enetc-cache-accesses-to-priv-si-hw.patch [new file with mode: 0644]
queue-5.15/net-enetc-manage-enetc_f_qbv-in-priv-active_offloads.patch [new file with mode: 0644]
queue-5.15/net-enetc-preserve-tx-ring-priority-across-reconfigu.patch [new file with mode: 0644]
queue-5.15/net-ethernet-mtk_eth_soc-fix-error-handling-in-mtk_o.patch [new file with mode: 0644]
queue-5.15/net-liquidio-simplify-if-expression.patch [new file with mode: 0644]
queue-5.15/net-mlx4-check-retval-of-mlx4_bitmap_init.patch [new file with mode: 0644]
queue-5.15/net-mlx5-do-not-query-pci-info-while-pci-disabled.patch [new file with mode: 0644]
queue-5.15/net-mlx5-fix-fw-tracer-timestamp-calculation.patch [new file with mode: 0644]
queue-5.15/net-mlx5-fix-handling-of-entry-refcount-when-command.patch [new file with mode: 0644]
queue-5.15/net-mvpp2-fix-possible-invalid-pointer-dereference.patch [new file with mode: 0644]
queue-5.15/net-pch_gbe-fix-pci-device-refcount-leak-while-modul.patch [new file with mode: 0644]
queue-5.15/net-pch_gbe-fix-potential-memleak-in-pch_gbe_tx_queu.patch [new file with mode: 0644]
queue-5.15/net-qla3xxx-fix-potential-memleak-in-ql3xxx_send.patch [new file with mode: 0644]
queue-5.15/net-sched-allow-act_ct-to-be-built-without-nf_nat.patch [new file with mode: 0644]
queue-5.15/net-sparx5-fix-error-handling-in-sparx5_port_open.patch [new file with mode: 0644]
queue-5.15/net-thunderx-fix-the-acpi-memory-leak.patch [new file with mode: 0644]
queue-5.15/net-wwan-iosm-use-acpi_free-but-not-kfree-in-ipc_pci.patch [new file with mode: 0644]
queue-5.15/netfilter-conntrack-fix-data-races-around-ct-mark.patch [new file with mode: 0644]
queue-5.15/netfilter-flowtable_offload-add-missing-locking.patch [new file with mode: 0644]
queue-5.15/netfilter-ipset-regression-in-ip_set_hash_ip.c.patch [new file with mode: 0644]
queue-5.15/netfilter-ipset-restore-allowing-64-clashing-element.patch [new file with mode: 0644]
queue-5.15/netfilter-nf_tables-do-not-set-up-extensions-for-end.patch [new file with mode: 0644]
queue-5.15/nfc-nci-fix-memory-leak-in-nci_rx_data_packet.patch [new file with mode: 0644]
queue-5.15/nfc-nci-fix-race-with-opening-and-closing.patch [new file with mode: 0644]
queue-5.15/nfc-st-nci-fix-incorrect-sizing-calculations-in-evt_.patch [new file with mode: 0644]
queue-5.15/nfc-st-nci-fix-incorrect-validating-logic-in-evt_tra.patch [new file with mode: 0644]
queue-5.15/nfc-st-nci-fix-memory-leaks-in-evt_transaction.patch [new file with mode: 0644]
queue-5.15/nfp-add-port-from-netdev-validation-for-eeprom-acces.patch [new file with mode: 0644]
queue-5.15/nfp-fill-splittable-of-devlink_port_attrs-correctly.patch [new file with mode: 0644]
queue-5.15/octeontx2-af-debugsfs-fix-pci-device-refcount-leak.patch [new file with mode: 0644]
queue-5.15/octeontx2-af-fix-reference-count-issue-in-rvu_sdp_in.patch [new file with mode: 0644]
queue-5.15/octeontx2-pf-add-check-for-devm_kcalloc.patch [new file with mode: 0644]
queue-5.15/regulator-core-fix-kobject-release-warning-and-memor.patch [new file with mode: 0644]
queue-5.15/regulator-core-fix-uaf-in-destroy_regulator.patch [new file with mode: 0644]
queue-5.15/regulator-twl6030-re-add-twl6032_subclass.patch [new file with mode: 0644]
queue-5.15/rxrpc-allow-list-of-in-use-local-udp-endpoints-to-be.patch [new file with mode: 0644]
queue-5.15/rxrpc-fix-race-between-conn-bundle-lookup-and-bundle.patch [new file with mode: 0644]
queue-5.15/rxrpc-use-refcount_t-rather-than-atomic_t.patch [new file with mode: 0644]
queue-5.15/s390-crashdump-fix-tod-programmable-field-size.patch [new file with mode: 0644]
queue-5.15/s390-dasd-fix-no-record-found-for-raw_track_access.patch [new file with mode: 0644]
queue-5.15/scsi-storvsc-fix-handling-of-srb_status-and-capacity.patch [new file with mode: 0644]
queue-5.15/selftests-mptcp-fix-mibit-vs-mbit-mix-up.patch [new file with mode: 0644]
queue-5.15/selftests-mptcp-more-stable-simult_flows-tests.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/sfc-fix-potential-memleak-in-__ef100_hard_start_xmit.patch [new file with mode: 0644]
queue-5.15/spi-dw-dma-decrease-reference-count-in-dw_spi_dma_in.patch [new file with mode: 0644]
queue-5.15/tee-optee-fix-possible-memory-leak-in-optee_register.patch [new file with mode: 0644]
queue-5.15/tipc-add-an-extra-conn_get-in-tipc_conn_alloc.patch [new file with mode: 0644]
queue-5.15/tipc-check-skb_linearize-return-value-in-tipc_disc_r.patch [new file with mode: 0644]
queue-5.15/tipc-set-con-sock-in-tipc_conn_alloc.patch [new file with mode: 0644]
queue-5.15/x86-hyperv-restore-vp-assist-page-after-cpu-offlinin.patch [new file with mode: 0644]
queue-5.15/xfrm-fix-disable_policy-on-ipv4-early-demux.patch [new file with mode: 0644]
queue-5.15/xfrm-fix-ignored-return-value-in-xfrm6_init.patch [new file with mode: 0644]
queue-5.15/xfrm-fix-oops-in-__xfrm_state_delete.patch [new file with mode: 0644]
queue-5.15/xfrm-replay-fix-esn-wrap-around-for-gso.patch [new file with mode: 0644]

diff --git a/queue-5.15/9p-fd-fix-issue-of-list_del-corruption-in-p9_fd_canc.patch b/queue-5.15/9p-fd-fix-issue-of-list_del-corruption-in-p9_fd_canc.patch
new file mode 100644 (file)
index 0000000..217ed53
--- /dev/null
@@ -0,0 +1,75 @@
+From c3bba090ad52c6dac1fd0a006b81f9e1c089ccc5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Nov 2022 20:26:06 +0800
+Subject: 9p/fd: fix issue of list_del corruption in p9_fd_cancel()
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit 11c10956515b8ec44cf4f2a7b9d8bf8b9dc05ec4 ]
+
+Syz reported the following issue:
+kernel BUG at lib/list_debug.c:53!
+invalid opcode: 0000 [#1] PREEMPT SMP KASAN
+RIP: 0010:__list_del_entry_valid.cold+0x5c/0x72
+Call Trace:
+<TASK>
+p9_fd_cancel+0xb1/0x270
+p9_client_rpc+0x8ea/0xba0
+p9_client_create+0x9c0/0xed0
+v9fs_session_init+0x1e0/0x1620
+v9fs_mount+0xba/0xb80
+legacy_get_tree+0x103/0x200
+vfs_get_tree+0x89/0x2d0
+path_mount+0x4c0/0x1ac0
+__x64_sys_mount+0x33b/0x430
+do_syscall_64+0x35/0x80
+entry_SYSCALL_64_after_hwframe+0x46/0xb0
+</TASK>
+
+The process is as follows:
+Thread A:                       Thread B:
+p9_poll_workfn()                p9_client_create()
+...                                 ...
+    p9_conn_cancel()                p9_fd_cancel()
+        list_del()                      ...
+        ...                             list_del()  //list_del
+                                                      corruption
+There is no lock protection when deleting list in p9_conn_cancel(). After
+deleting list in Thread A, thread B will delete the same list again. It
+will cause issue of list_del corruption.
+
+Setting req->status to REQ_STATUS_ERROR under lock prevents other
+cleanup paths from trying to manipulate req_list.
+The other thread can safely check req->status because it still holds a
+reference to req at this point.
+
+Link: https://lkml.kernel.org/r/20221110122606.383352-1-shaozhengchao@huawei.com
+Fixes: 52f1c45dde91 ("9p: trans_fd/p9_conn_cancel: drop client lock earlier")
+Reported-by: syzbot+9b69b8d10ab4a7d88056@syzkaller.appspotmail.com
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+[Dominique: add description of the fix in commit message]
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/9p/trans_fd.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index a8c1f742148c..31f2026514f3 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -204,9 +204,11 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
+       list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
+               list_move(&req->req_list, &cancel_list);
++              req->status = REQ_STATUS_ERROR;
+       }
+       list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
+               list_move(&req->req_list, &cancel_list);
++              req->status = REQ_STATUS_ERROR;
+       }
+       spin_unlock(&m->req_lock);
+-- 
+2.35.1
+
diff --git a/queue-5.15/af_key-fix-send_acquire-race-with-pfkey_register.patch b/queue-5.15/af_key-fix-send_acquire-race-with-pfkey_register.patch
new file mode 100644 (file)
index 0000000..a70712a
--- /dev/null
@@ -0,0 +1,147 @@
+From 2e8a017dc5cc90126051674f4dad6a702a4722e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Oct 2022 14:06:48 +0800
+Subject: af_key: Fix send_acquire race with pfkey_register
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 7f57f8165cb6d2c206e2b9ada53b9e2d6d8af42f ]
+
+The function pfkey_send_acquire may race with pfkey_register
+(which could even be in a different name space).  This may result
+in a buffer overrun.
+
+Allocating the maximum amount of memory that could be used prevents
+this.
+
+Reported-by: syzbot+1e9af9185d8850e2c2fa@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/key/af_key.c | 32 ++++++++++++++++++++++----------
+ 1 file changed, 22 insertions(+), 10 deletions(-)
+
+diff --git a/net/key/af_key.c b/net/key/af_key.c
+index 53cca9019158..a654bd4bc437 100644
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -2905,7 +2905,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t)
+                       break;
+               if (!aalg->pfkey_supported)
+                       continue;
+-              if (aalg_tmpl_set(t, aalg) && aalg->available)
++              if (aalg_tmpl_set(t, aalg))
+                       sz += sizeof(struct sadb_comb);
+       }
+       return sz + sizeof(struct sadb_prop);
+@@ -2923,7 +2923,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
+               if (!ealg->pfkey_supported)
+                       continue;
+-              if (!(ealg_tmpl_set(t, ealg) && ealg->available))
++              if (!(ealg_tmpl_set(t, ealg)))
+                       continue;
+               for (k = 1; ; k++) {
+@@ -2934,16 +2934,17 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
+                       if (!aalg->pfkey_supported)
+                               continue;
+-                      if (aalg_tmpl_set(t, aalg) && aalg->available)
++                      if (aalg_tmpl_set(t, aalg))
+                               sz += sizeof(struct sadb_comb);
+               }
+       }
+       return sz + sizeof(struct sadb_prop);
+ }
+-static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
++static int dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+ {
+       struct sadb_prop *p;
++      int sz = 0;
+       int i;
+       p = skb_put(skb, sizeof(struct sadb_prop));
+@@ -2971,13 +2972,17 @@ static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+                       c->sadb_comb_soft_addtime = 20*60*60;
+                       c->sadb_comb_hard_usetime = 8*60*60;
+                       c->sadb_comb_soft_usetime = 7*60*60;
++                      sz += sizeof(*c);
+               }
+       }
++
++      return sz + sizeof(*p);
+ }
+-static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
++static int dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+ {
+       struct sadb_prop *p;
++      int sz = 0;
+       int i, k;
+       p = skb_put(skb, sizeof(struct sadb_prop));
+@@ -3019,8 +3024,11 @@ static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+                       c->sadb_comb_soft_addtime = 20*60*60;
+                       c->sadb_comb_hard_usetime = 8*60*60;
+                       c->sadb_comb_soft_usetime = 7*60*60;
++                      sz += sizeof(*c);
+               }
+       }
++
++      return sz + sizeof(*p);
+ }
+ static int key_notify_policy_expire(struct xfrm_policy *xp, const struct km_event *c)
+@@ -3150,6 +3158,7 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
+       struct sadb_x_sec_ctx *sec_ctx;
+       struct xfrm_sec_ctx *xfrm_ctx;
+       int ctx_size = 0;
++      int alg_size = 0;
+       sockaddr_size = pfkey_sockaddr_size(x->props.family);
+       if (!sockaddr_size)
+@@ -3161,16 +3170,16 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
+               sizeof(struct sadb_x_policy);
+       if (x->id.proto == IPPROTO_AH)
+-              size += count_ah_combs(t);
++              alg_size = count_ah_combs(t);
+       else if (x->id.proto == IPPROTO_ESP)
+-              size += count_esp_combs(t);
++              alg_size = count_esp_combs(t);
+       if ((xfrm_ctx = x->security)) {
+               ctx_size = PFKEY_ALIGN8(xfrm_ctx->ctx_len);
+               size +=  sizeof(struct sadb_x_sec_ctx) + ctx_size;
+       }
+-      skb =  alloc_skb(size + 16, GFP_ATOMIC);
++      skb =  alloc_skb(size + alg_size + 16, GFP_ATOMIC);
+       if (skb == NULL)
+               return -ENOMEM;
+@@ -3224,10 +3233,13 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
+       pol->sadb_x_policy_priority = xp->priority;
+       /* Set sadb_comb's. */
++      alg_size = 0;
+       if (x->id.proto == IPPROTO_AH)
+-              dump_ah_combs(skb, t);
++              alg_size = dump_ah_combs(skb, t);
+       else if (x->id.proto == IPPROTO_ESP)
+-              dump_esp_combs(skb, t);
++              alg_size = dump_esp_combs(skb, t);
++
++      hdr->sadb_msg_len += alg_size / 8;
+       /* security context */
+       if (xfrm_ctx) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/arcnet-fix-potential-memory-leak-in-com20020_probe.patch b/queue-5.15/arcnet-fix-potential-memory-leak-in-com20020_probe.patch
new file mode 100644 (file)
index 0000000..76255cd
--- /dev/null
@@ -0,0 +1,61 @@
+From 7e0fd95d3a1db31711adc9e3f86d27a92b82ff7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Nov 2022 14:24:38 +0800
+Subject: arcnet: fix potential memory leak in com20020_probe()
+
+From: Wang Hai <wanghai38@huawei.com>
+
+[ Upstream commit 1c40cde6b5171d9c8dfc69be00464fd1c75e210b ]
+
+In com20020_probe(), if com20020_config() fails, dev and info
+will not be freed, which will lead to a memory leak.
+
+This patch adds freeing dev and info after com20020_config()
+fails to fix this bug.
+
+Compile tested only.
+
+Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions")
+Signed-off-by: Wang Hai <wanghai38@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/arcnet/com20020_cs.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/arcnet/com20020_cs.c b/drivers/net/arcnet/com20020_cs.c
+index b88a109b3b15..26ee263d8f3a 100644
+--- a/drivers/net/arcnet/com20020_cs.c
++++ b/drivers/net/arcnet/com20020_cs.c
+@@ -113,6 +113,7 @@ static int com20020_probe(struct pcmcia_device *p_dev)
+       struct com20020_dev *info;
+       struct net_device *dev;
+       struct arcnet_local *lp;
++      int ret = -ENOMEM;
+       dev_dbg(&p_dev->dev, "com20020_attach()\n");
+@@ -142,12 +143,18 @@ static int com20020_probe(struct pcmcia_device *p_dev)
+       info->dev = dev;
+       p_dev->priv = info;
+-      return com20020_config(p_dev);
++      ret = com20020_config(p_dev);
++      if (ret)
++              goto fail_config;
++
++      return 0;
++fail_config:
++      free_arcdev(dev);
+ fail_alloc_dev:
+       kfree(info);
+ fail_alloc_info:
+-      return -ENOMEM;
++      return ret;
+ } /* com20020_attach */
+ static void com20020_detach(struct pcmcia_device *link)
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-am335x-pcm-953-define-fixed-regulators-in-ro.patch b/queue-5.15/arm-dts-am335x-pcm-953-define-fixed-regulators-in-ro.patch
new file mode 100644 (file)
index 0000000..db19b17
--- /dev/null
@@ -0,0 +1,66 @@
+From 86090bf033e2ef40e1e3bca0b9f118f19bf04c29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Oct 2022 16:31:15 +0200
+Subject: ARM: dts: am335x-pcm-953: Define fixed regulators in root node
+
+From: Dominik Haller <d.haller@phytec.de>
+
+[ Upstream commit 8950f345a67d8046d2472dd6ea81fa18ef5b4844 ]
+
+Remove the regulators node and define fixed regulators in the root node.
+Prevents the sdhci-omap driver from waiting in probe deferral forever
+because of the missing vmmc-supply and keeps am335x-pcm-953 consistent with
+the other Phytec AM335 boards.
+
+Fixes: bb07a829ec38 ("ARM: dts: Add support for phyCORE-AM335x PCM-953 carrier board")
+Signed-off-by: Dominik Haller <d.haller@phytec.de>
+Message-Id: <20221011143115.248003-1-d.haller@phytec.de>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/am335x-pcm-953.dtsi | 28 +++++++++++++--------------
+ 1 file changed, 13 insertions(+), 15 deletions(-)
+
+diff --git a/arch/arm/boot/dts/am335x-pcm-953.dtsi b/arch/arm/boot/dts/am335x-pcm-953.dtsi
+index 124026fa0d09..f207499461b3 100644
+--- a/arch/arm/boot/dts/am335x-pcm-953.dtsi
++++ b/arch/arm/boot/dts/am335x-pcm-953.dtsi
+@@ -12,22 +12,20 @@ / {
+       compatible = "phytec,am335x-pcm-953", "phytec,am335x-phycore-som", "ti,am33xx";
+       /* Power */
+-      regulators {
+-              vcc3v3: fixedregulator@1 {
+-                      compatible = "regulator-fixed";
+-                      regulator-name = "vcc3v3";
+-                      regulator-min-microvolt = <3300000>;
+-                      regulator-max-microvolt = <3300000>;
+-                      regulator-boot-on;
+-              };
++      vcc3v3: fixedregulator1 {
++              compatible = "regulator-fixed";
++              regulator-name = "vcc3v3";
++              regulator-min-microvolt = <3300000>;
++              regulator-max-microvolt = <3300000>;
++              regulator-boot-on;
++      };
+-              vcc1v8: fixedregulator@2 {
+-                      compatible = "regulator-fixed";
+-                      regulator-name = "vcc1v8";
+-                      regulator-min-microvolt = <1800000>;
+-                      regulator-max-microvolt = <1800000>;
+-                      regulator-boot-on;
+-              };
++      vcc1v8: fixedregulator2 {
++              compatible = "regulator-fixed";
++              regulator-name = "vcc1v8";
++              regulator-min-microvolt = <1800000>;
++              regulator-max-microvolt = <1800000>;
++              regulator-boot-on;
+       };
+       /* User IO */
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-at91-sam9g20ek-enable-udc-vbus-gpio-pinctrl.patch b/queue-5.15/arm-dts-at91-sam9g20ek-enable-udc-vbus-gpio-pinctrl.patch
new file mode 100644 (file)
index 0000000..0227a51
--- /dev/null
@@ -0,0 +1,57 @@
+From f9f1ba39ac4945d39ff6b6cdd205bab226319f12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 19:59:23 +0100
+Subject: ARM: dts: at91: sam9g20ek: enable udc vbus gpio pinctrl
+
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+
+[ Upstream commit 40a2226e8bfacb79dd154dea68febeead9d847e9 ]
+
+We set the PIOC to GPIO mode. This way the pin becomes an
+input signal will be usable by the controller. Without
+this change the udc on the 9g20ek does not work.
+
+Cc: nicolas.ferre@microchip.com
+Cc: ludovic.desroches@microchip.com
+Cc: alexandre.belloni@bootlin.com
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: kernel@pengutronix.de
+Fixes: 5cb4e73575e3 ("ARM: at91: add at91sam9g20ek boards dt support")
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20221114185923.1023249-3-m.grzeschik@pengutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+index ca03685f0f08..4783e657b4cb 100644
+--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
++++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+@@ -39,6 +39,13 @@ pinctrl_pck0_as_mck: pck0_as_mck {
+                               };
++                              usb1 {
++                                      pinctrl_usb1_vbus_gpio: usb1_vbus_gpio {
++                                              atmel,pins =
++                                                      <AT91_PIOC 5 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;   /* PC5 GPIO */
++                                      };
++                              };
++
+                               mmc0_slot1 {
+                                       pinctrl_board_mmc0_slot1: mmc0_slot1-board {
+                                               atmel,pins =
+@@ -84,6 +91,8 @@ macb0: ethernet@fffc4000 {
+                       };
+                       usb1: gadget@fffa4000 {
++                              pinctrl-0 = <&pinctrl_usb1_vbus_gpio>;
++                              pinctrl-names = "default";
+                               atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
+                               status = "okay";
+                       };
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-imx6q-prti6q-fix-ref-tcxo-clock-frequency-pr.patch b/queue-5.15/arm-dts-imx6q-prti6q-fix-ref-tcxo-clock-frequency-pr.patch
new file mode 100644 (file)
index 0000000..f3774c9
--- /dev/null
@@ -0,0 +1,43 @@
+From 226a5d4de6ec70c64a149a8dbdb6c96f26d5c3f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 10:41:02 -0300
+Subject: ARM: dts: imx6q-prti6q: Fix ref/tcxo-clock-frequency properties
+
+From: Fabio Estevam <festevam@denx.de>
+
+[ Upstream commit e68be7b39f21d8a9291a5a3019787cd3ca999dd7 ]
+
+make dtbs_check gives the following errors:
+
+ref-clock-frequency: size (9) error for type uint32
+tcxo-clock-frequency: size (9) error for type uint32
+
+Fix it by passing the frequencies inside < > as documented in
+Documentation/devicetree/bindings/net/wireless/ti,wlcore.yaml.
+
+Signed-off-by: Fabio Estevam <festevam@denx.de>
+Fixes: 0d446a505592 ("ARM: dts: add Protonic PRTI6Q board")
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6q-prti6q.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/imx6q-prti6q.dts b/arch/arm/boot/dts/imx6q-prti6q.dts
+index b4605edfd2ab..d8fa83effd63 100644
+--- a/arch/arm/boot/dts/imx6q-prti6q.dts
++++ b/arch/arm/boot/dts/imx6q-prti6q.dts
+@@ -364,8 +364,8 @@ wifi {
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_wifi>;
+               interrupts-extended = <&gpio1 30 IRQ_TYPE_LEVEL_HIGH>;
+-              ref-clock-frequency = "38400000";
+-              tcxo-clock-frequency = "19200000";
++              ref-clock-frequency = <38400000>;
++              tcxo-clock-frequency = <19200000>;
+       };
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-mxs-fix-memory-leak-in-mxs_machine_init.patch b/queue-5.15/arm-mxs-fix-memory-leak-in-mxs_machine_init.patch
new file mode 100644 (file)
index 0000000..36c0eb7
--- /dev/null
@@ -0,0 +1,40 @@
+From 7cc1550cedfd8e7f405aa75f3542873f37489c05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 06:20:11 +0000
+Subject: ARM: mxs: fix memory leak in mxs_machine_init()
+
+From: Zheng Yongjun <zhengyongjun3@huawei.com>
+
+[ Upstream commit f31e3c204d1844b8680a442a48868af5ac3d5481 ]
+
+If of_property_read_string() failed, 'soc_dev_attr' should be
+freed before return. Otherwise there is a memory leak.
+
+Fixes: 2046338dcbc6 ("ARM: mxs: Use soc bus infrastructure")
+Signed-off-by: Zheng Yongjun <zhengyongjun3@huawei.com>
+Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-mxs/mach-mxs.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
+index 25c9d184fa4c..1c57ac401649 100644
+--- a/arch/arm/mach-mxs/mach-mxs.c
++++ b/arch/arm/mach-mxs/mach-mxs.c
+@@ -393,8 +393,10 @@ static void __init mxs_machine_init(void)
+       root = of_find_node_by_path("/");
+       ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
+-      if (ret)
++      if (ret) {
++              kfree(soc_dev_attr);
+               return;
++      }
+       soc_dev_attr->family = "Freescale MXS Family";
+       soc_dev_attr->soc_id = mxs_get_soc_id();
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-hdac_hda-fix-hda-pcm-buffer-overflow-issue.patch b/queue-5.15/asoc-hdac_hda-fix-hda-pcm-buffer-overflow-issue.patch
new file mode 100644 (file)
index 0000000..98f1e35
--- /dev/null
@@ -0,0 +1,66 @@
+From dd4093322691e318c03715dde66e19ac397b5bf1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Nov 2022 07:40:23 +0800
+Subject: ASoC: hdac_hda: fix hda pcm buffer overflow issue
+
+From: Junxiao Chang <junxiao.chang@intel.com>
+
+[ Upstream commit 37882100cd0629d830db430a8cee0b724fe1fea3 ]
+
+When KASAN is enabled, below log might be dumped with Intel EHL hardware:
+[   48.583597] ==================================================================
+[   48.585921] BUG: KASAN: slab-out-of-bounds in hdac_hda_dai_hw_params+0x20a/0x22b [snd_soc_hdac_hda]
+[   48.587995] Write of size 4 at addr ffff888103489708 by task pulseaudio/759
+
+[   48.589237] CPU: 2 PID: 759 Comm: pulseaudio Tainted: G     U      E     5.15.71-intel-ese-standard-lts #9
+[   48.591272] Hardware name: Intel Corporation Elkhart Lake Embedded Platform/ElkhartLake LPDDR4x T3 CRB, BIOS EHLSFWI1.R00.4251.A01.2206130432 06/13/2022
+[   48.593010] Call Trace:
+[   48.593648]  <TASK>
+[   48.593852]  dump_stack_lvl+0x34/0x48
+[   48.594404]  print_address_description.constprop.0+0x1f/0x140
+[   48.595174]  ? hdac_hda_dai_hw_params+0x20a/0x22b [snd_soc_hdac_hda]
+[   48.595868]  ? hdac_hda_dai_hw_params+0x20a/0x22b [snd_soc_hdac_hda]
+[   48.596519]  kasan_report.cold+0x7f/0x11b
+[   48.597003]  ? hdac_hda_dai_hw_params+0x20a/0x22b [snd_soc_hdac_hda]
+[   48.597885]  hdac_hda_dai_hw_params+0x20a/0x22b [snd_soc_hdac_hda]
+
+HDAC_LAST_DAI_ID is last index id, pcm buffer array size should
+be +1 to avoid out of bound access.
+
+Fixes: 608b8c36c371 ("ASoC: hdac_hda: add support for HDMI/DP as a HDA codec")
+Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Signed-off-by: Junxiao Chang <junxiao.chang@intel.com>
+Signed-off-by: Furong Zhou <furong.zhou@intel.com>
+Link: https://lore.kernel.org/r/20221109234023.3111035-1-junxiao.chang@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/hdac_hda.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/hdac_hda.h b/sound/soc/codecs/hdac_hda.h
+index d0efc5e254ae..da0ed74758b0 100644
+--- a/sound/soc/codecs/hdac_hda.h
++++ b/sound/soc/codecs/hdac_hda.h
+@@ -14,7 +14,7 @@ enum {
+       HDAC_HDMI_1_DAI_ID,
+       HDAC_HDMI_2_DAI_ID,
+       HDAC_HDMI_3_DAI_ID,
+-      HDAC_LAST_DAI_ID = HDAC_HDMI_3_DAI_ID,
++      HDAC_DAI_ID_NUM
+ };
+ struct hdac_hda_pcm {
+@@ -24,7 +24,7 @@ struct hdac_hda_pcm {
+ struct hdac_hda_priv {
+       struct hda_codec codec;
+-      struct hdac_hda_pcm pcm[HDAC_LAST_DAI_ID];
++      struct hdac_hda_pcm pcm[HDAC_DAI_ID_NUM];
+       bool need_display_power;
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-max98373-add-checks-for-devm_kcalloc.patch b/queue-5.15/asoc-max98373-add-checks-for-devm_kcalloc.patch
new file mode 100644 (file)
index 0000000..732923c
--- /dev/null
@@ -0,0 +1,40 @@
+From 853896dcfd7950ef0375f74449569308f8a9ddf5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 16:25:08 +0800
+Subject: ASoC: max98373: Add checks for devm_kcalloc
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 60591bbf6d5eb44f275eb733943b7757325c1b60 ]
+
+As the devm_kcalloc may return NULL pointer,
+it should be better to check the return value
+in order to avoid NULL poineter dereference.
+
+Fixes: 349dd23931d1 ("ASoC: max98373: don't access volatile registers in bias level off")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20221116082508.17418-1-jiasheng@iscas.ac.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/max98373-i2c.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/sound/soc/codecs/max98373-i2c.c b/sound/soc/codecs/max98373-i2c.c
+index ddb6436835d7..68497a4521dd 100644
+--- a/sound/soc/codecs/max98373-i2c.c
++++ b/sound/soc/codecs/max98373-i2c.c
+@@ -551,6 +551,10 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
+       max98373->cache = devm_kcalloc(&i2c->dev, max98373->cache_num,
+                                      sizeof(*max98373->cache),
+                                      GFP_KERNEL);
++      if (!max98373->cache) {
++              ret = -ENOMEM;
++              return ret;
++      }
+       for (i = 0; i < max98373->cache_num; i++)
+               max98373->cache[i].reg = max98373_i2c_cache_reg[i];
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-sgtl5000-reset-the-chip_clk_ctrl-reg-on-remove.patch b/queue-5.15/asoc-sgtl5000-reset-the-chip_clk_ctrl-reg-on-remove.patch
new file mode 100644 (file)
index 0000000..cdc5f12
--- /dev/null
@@ -0,0 +1,48 @@
+From 4e4ae9a2d1e8e68f63c4be48c6c3e14b5ab29a26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Nov 2022 14:06:12 -0500
+Subject: ASoC: sgtl5000: Reset the CHIP_CLK_CTRL reg on remove
+
+From: Detlev Casanova <detlev.casanova@collabora.com>
+
+[ Upstream commit 0bb8e9b36b5b7f2e77892981ff6c27ee831d8026 ]
+
+Since commit bf2aebccddef ("ASoC: sgtl5000: Fix noise on shutdown/remove"),
+the device power control registers are reset when the driver is
+removed/shutdown.
+
+This is an issue when the device is configured to use the PLL clock. The
+device will stop responding if it is still configured to use the PLL
+clock but the PLL clock is powered down.
+
+When rebooting linux, the probe function will show:
+sgtl5000 0-000a: Error reading chip id -11
+
+Make sure that the CHIP_CLK_CTRL is reset to its default value before
+powering down the device.
+
+Fixes: bf2aebccddef ("ASoC: sgtl5000: Fix noise on shutdown/remove")
+Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
+Reviewed-by: Fabio Estevam <festevam@gmail.com>
+Link: https://lore.kernel.org/r/20221110190612.1341469-1-detlev.casanova@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/sgtl5000.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
+index dc56e6c6b668..3c5a4fe2fad6 100644
+--- a/sound/soc/codecs/sgtl5000.c
++++ b/sound/soc/codecs/sgtl5000.c
+@@ -1797,6 +1797,7 @@ static int sgtl5000_i2c_remove(struct i2c_client *client)
+ {
+       struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
++      regmap_write(sgtl5000->regmap, SGTL5000_CHIP_CLK_CTRL, SGTL5000_CHIP_CLK_CTRL_DEFAULT);
+       regmap_write(sgtl5000->regmap, SGTL5000_CHIP_DIG_POWER, SGTL5000_DIG_POWER_DEFAULT);
+       regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, SGTL5000_ANA_POWER_DEFAULT);
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-soc-pcm-don-t-zero-tdm-masks-in-__soc_pcm_open.patch b/queue-5.15/asoc-soc-pcm-don-t-zero-tdm-masks-in-__soc_pcm_open.patch
new file mode 100644 (file)
index 0000000..6f5b6fe
--- /dev/null
@@ -0,0 +1,47 @@
+From 87d791009cdb32c0912374febfe2c82c848c35db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 13:22:13 +0000
+Subject: ASoC: soc-pcm: Don't zero TDM masks in __soc_pcm_open()
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 39bd801d6908900e9ab0cdc2655150f95ddd4f1a ]
+
+The DAI tx_mask and rx_mask are set by snd_soc_dai_set_tdm_slot()
+and used by later code that depends on the TDM settings. So
+__soc_pcm_open() should not be obliterating those mask values.
+
+The code in __soc_pcm_hw_params() uses these masks to calculate the
+active channels so that only the AIF_IN/AIF_OUT widgets for the
+active TDM slots are enabled. The zeroing of the masks in
+__soc_pcm_open() disables this functionality so all AIF widgets
+were enabled even for channels that are not assigned to a TDM slot.
+
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Fixes: 2e5894d73789 ("ASoC: pcm: Add support for DAI multicodec")
+Link: https://lore.kernel.org/r/20221104132213.121847-1-rf@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/soc-pcm.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index 48f71bb81a2f..f6dc71e8ea87 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -759,11 +759,6 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
+               ret = snd_soc_dai_startup(dai, substream);
+               if (ret < 0)
+                       goto err;
+-
+-              if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+-                      dai->tx_mask = 0;
+-              else
+-                      dai->rx_mask = 0;
+       }
+       /* Dynamic PCM DAI links compat checks use dynamic capabilities */
+-- 
+2.35.1
+
diff --git a/queue-5.15/bnx2x-fix-pci-device-refcount-leak-in-bnx2x_vf_is_pc.patch b/queue-5.15/bnx2x-fix-pci-device-refcount-leak-in-bnx2x_vf_is_pc.patch
new file mode 100644 (file)
index 0000000..eadb9e3
--- /dev/null
@@ -0,0 +1,58 @@
+From 454108f58d664111bfaf6d61e041b26f199fe16f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Nov 2022 15:02:02 +0800
+Subject: bnx2x: fix pci device refcount leak in bnx2x_vf_is_pcie_pending()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 3637a29ccbb6461b7268c5c5db525935d510afc6 ]
+
+As comment of pci_get_domain_bus_and_slot() says, it returns
+a pci device with refcount increment, when finish using it,
+the caller must decrement the reference count by calling
+pci_dev_put(). Call pci_dev_put() before returning from
+bnx2x_vf_is_pcie_pending() to avoid refcount leak.
+
+Fixes: b56e9670ffa4 ("bnx2x: Prepare device and initialize VF database")
+Suggested-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Link: https://lore.kernel.org/r/20221119070202.1407648-1-yangyingliang@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+index 561395731450..a9f202bbada1 100644
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+@@ -795,16 +795,20 @@ static void bnx2x_vf_enable_traffic(struct bnx2x *bp, struct bnx2x_virtf *vf)
+ static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid)
+ {
+-      struct pci_dev *dev;
+       struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid);
++      struct pci_dev *dev;
++      bool pending;
+       if (!vf)
+               return false;
+       dev = pci_get_domain_bus_and_slot(vf->domain, vf->bus, vf->devfn);
+-      if (dev)
+-              return bnx2x_is_pcie_pending(dev);
+-      return false;
++      if (!dev)
++              return false;
++      pending = bnx2x_is_pcie_pending(dev);
++      pci_dev_put(dev);
++
++      return pending;
+ }
+ int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid)
+-- 
+2.35.1
+
diff --git a/queue-5.15/bus-sunxi-rsb-remove-the-shutdown-callback.patch b/queue-5.15/bus-sunxi-rsb-remove-the-shutdown-callback.patch
new file mode 100644 (file)
index 0000000..8f9490a
--- /dev/null
@@ -0,0 +1,55 @@
+From a590925e4fd23b970b9dd2108f9693be228aeefc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Nov 2022 19:57:47 -0600
+Subject: bus: sunxi-rsb: Remove the shutdown callback
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit 5f4696ddca4b8a0bbbc36bd46829f97aab5a4552 ]
+
+Shutting down the RSB controller prevents communicating with a PMIC
+inside pm_power_off(), since that gets called after device_shutdown(),
+so it breaks system poweroff on some boards.
+
+Reported-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
+Tested-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
+Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Fixes: 843107498f91 ("bus: sunxi-rsb: Implement suspend/resume/shutdown callbacks")
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Link: https://lore.kernel.org/r/20221114015749.28490-2-samuel@sholland.org
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/sunxi-rsb.c | 9 ---------
+ 1 file changed, 9 deletions(-)
+
+diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c
+index 60b082fe2ed0..9c209492b267 100644
+--- a/drivers/bus/sunxi-rsb.c
++++ b/drivers/bus/sunxi-rsb.c
+@@ -816,14 +816,6 @@ static int sunxi_rsb_remove(struct platform_device *pdev)
+       return 0;
+ }
+-static void sunxi_rsb_shutdown(struct platform_device *pdev)
+-{
+-      struct sunxi_rsb *rsb = platform_get_drvdata(pdev);
+-
+-      pm_runtime_disable(&pdev->dev);
+-      sunxi_rsb_hw_exit(rsb);
+-}
+-
+ static const struct dev_pm_ops sunxi_rsb_dev_pm_ops = {
+       SET_RUNTIME_PM_OPS(sunxi_rsb_runtime_suspend,
+                          sunxi_rsb_runtime_resume, NULL)
+@@ -839,7 +831,6 @@ MODULE_DEVICE_TABLE(of, sunxi_rsb_of_match_table);
+ static struct platform_driver sunxi_rsb_driver = {
+       .probe = sunxi_rsb_probe,
+       .remove = sunxi_rsb_remove,
+-      .shutdown = sunxi_rsb_shutdown,
+       .driver = {
+               .name = RSB_CTRL_NAME,
+               .of_match_table = sunxi_rsb_of_match_table,
+-- 
+2.35.1
+
diff --git a/queue-5.15/bus-sunxi-rsb-support-atomic-transfers.patch b/queue-5.15/bus-sunxi-rsb-support-atomic-transfers.patch
new file mode 100644 (file)
index 0000000..573f010
--- /dev/null
@@ -0,0 +1,92 @@
+From bbfc524e0048be383b0c319f71de0e12e567282f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Nov 2022 19:57:48 -0600
+Subject: bus: sunxi-rsb: Support atomic transfers
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit 077686da0e2162c4ea5ae0df205849c2a7a84479 ]
+
+When communicating with a PMIC during system poweroff (pm_power_off()),
+IRQs are disabled and we are in a RCU read-side critical section, so we
+cannot use wait_for_completion_io_timeout(). Instead, poll the status
+register for transfer completion.
+
+Fixes: d787dcdb9c8f ("bus: sunxi-rsb: Add driver for Allwinner Reduced Serial Bus")
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Link: https://lore.kernel.org/r/20221114015749.28490-3-samuel@sholland.org
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/sunxi-rsb.c | 29 +++++++++++++++++++++--------
+ 1 file changed, 21 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c
+index 9c209492b267..20ed77f2b949 100644
+--- a/drivers/bus/sunxi-rsb.c
++++ b/drivers/bus/sunxi-rsb.c
+@@ -271,6 +271,9 @@ EXPORT_SYMBOL_GPL(sunxi_rsb_driver_register);
+ /* common code that starts a transfer */
+ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
+ {
++      u32 int_mask, status;
++      bool timeout;
++
+       if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) {
+               dev_dbg(rsb->dev, "RSB transfer still in progress\n");
+               return -EBUSY;
+@@ -278,13 +281,23 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
+       reinit_completion(&rsb->complete);
+-      writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER,
+-             rsb->regs + RSB_INTE);
++      int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER;
++      writel(int_mask, rsb->regs + RSB_INTE);
+       writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB,
+              rsb->regs + RSB_CTRL);
+-      if (!wait_for_completion_io_timeout(&rsb->complete,
+-                                          msecs_to_jiffies(100))) {
++      if (irqs_disabled()) {
++              timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS,
++                                                  status, (status & int_mask),
++                                                  10, 100000);
++              writel(status, rsb->regs + RSB_INTS);
++      } else {
++              timeout = !wait_for_completion_io_timeout(&rsb->complete,
++                                                        msecs_to_jiffies(100));
++              status = rsb->status;
++      }
++
++      if (timeout) {
+               dev_dbg(rsb->dev, "RSB timeout\n");
+               /* abort the transfer */
+@@ -296,18 +309,18 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
+               return -ETIMEDOUT;
+       }
+-      if (rsb->status & RSB_INTS_LOAD_BSY) {
++      if (status & RSB_INTS_LOAD_BSY) {
+               dev_dbg(rsb->dev, "RSB busy\n");
+               return -EBUSY;
+       }
+-      if (rsb->status & RSB_INTS_TRANS_ERR) {
+-              if (rsb->status & RSB_INTS_TRANS_ERR_ACK) {
++      if (status & RSB_INTS_TRANS_ERR) {
++              if (status & RSB_INTS_TRANS_ERR_ACK) {
+                       dev_dbg(rsb->dev, "RSB slave nack\n");
+                       return -EINVAL;
+               }
+-              if (rsb->status & RSB_INTS_TRANS_ERR_DATA) {
++              if (status & RSB_INTS_TRANS_ERR_DATA) {
+                       dev_dbg(rsb->dev, "RSB transfer data error\n");
+                       return -EIO;
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.15/dccp-tcp-reset-saddr-on-failure-after-inet6-_hash_co.patch b/queue-5.15/dccp-tcp-reset-saddr-on-failure-after-inet6-_hash_co.patch
new file mode 100644 (file)
index 0000000..4f64294
--- /dev/null
@@ -0,0 +1,113 @@
+From 426789f8f0344909bd7580795539321c2a3fea64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 17:49:11 -0800
+Subject: dccp/tcp: Reset saddr on failure after inet6?_hash_connect().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 77934dc6db0d2b111a8f2759e9ad2fb67f5cffa5 ]
+
+When connect() is called on a socket bound to the wildcard address,
+we change the socket's saddr to a local address.  If the socket
+fails to connect() to the destination, we have to reset the saddr.
+
+However, when an error occurs after inet_hash6?_connect() in
+(dccp|tcp)_v[46]_conect(), we forget to reset saddr and leave
+the socket bound to the address.
+
+From the user's point of view, whether saddr is reset or not varies
+with errno.  Let's fix this inconsistent behaviour.
+
+Note that after this patch, the repro [0] will trigger the WARN_ON()
+in inet_csk_get_port() again, but this patch is not buggy and rather
+fixes a bug papering over the bhash2's bug for which we need another
+fix.
+
+For the record, the repro causes -EADDRNOTAVAIL in inet_hash6_connect()
+by this sequence:
+
+  s1 = socket()
+  s1.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
+  s1.bind(('127.0.0.1', 10000))
+  s1.sendto(b'hello', MSG_FASTOPEN, (('127.0.0.1', 10000)))
+  # or s1.connect(('127.0.0.1', 10000))
+
+  s2 = socket()
+  s2.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
+  s2.bind(('0.0.0.0', 10000))
+  s2.connect(('127.0.0.1', 10000))  # -EADDRNOTAVAIL
+
+  s2.listen(32)  # WARN_ON(inet_csk(sk)->icsk_bind2_hash != tb2);
+
+[0]: https://syzkaller.appspot.com/bug?extid=015d756bbd1f8b5c8f09
+
+Fixes: 3df80d9320bc ("[DCCP]: Introduce DCCPv6")
+Fixes: 7c657876b63c ("[DCCP]: Initial implementation")
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Acked-by: Joanne Koong <joannelkoong@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dccp/ipv4.c     | 2 ++
+ net/dccp/ipv6.c     | 2 ++
+ net/ipv4/tcp_ipv4.c | 2 ++
+ net/ipv6/tcp_ipv6.c | 2 ++
+ 4 files changed, 8 insertions(+)
+
+diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
+index 0ea29270d7e5..5bcfa1e9a941 100644
+--- a/net/dccp/ipv4.c
++++ b/net/dccp/ipv4.c
+@@ -137,6 +137,8 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+        * This unhashes the socket and releases the local port, if necessary.
+        */
+       dccp_set_state(sk, DCCP_CLOSED);
++      if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++              inet_reset_saddr(sk);
+       ip_rt_put(rt);
+       sk->sk_route_caps = 0;
+       inet->inet_dport = 0;
+diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
+index fa663518fa0e..071620622e1e 100644
+--- a/net/dccp/ipv6.c
++++ b/net/dccp/ipv6.c
+@@ -967,6 +967,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
+ late_failure:
+       dccp_set_state(sk, DCCP_CLOSED);
++      if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++              inet_reset_saddr(sk);
+       __sk_dst_reset(sk);
+ failure:
+       inet->inet_dport = 0;
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index 42d4af632495..0e1fbad17dbe 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -324,6 +324,8 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+        * if necessary.
+        */
+       tcp_set_state(sk, TCP_CLOSE);
++      if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++              inet_reset_saddr(sk);
+       ip_rt_put(rt);
+       sk->sk_route_caps = 0;
+       inet->inet_dport = 0;
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index 51f4d330e820..93b3e7c247ce 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -339,6 +339,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
+ late_failure:
+       tcp_set_state(sk, TCP_CLOSE);
++      if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++              inet_reset_saddr(sk);
+ failure:
+       inet->inet_dport = 0;
+       sk->sk_route_caps = 0;
+-- 
+2.35.1
+
diff --git a/queue-5.15/dma-buf-fix-racing-conflict-of-dma_heap_add.patch b/queue-5.15/dma-buf-fix-racing-conflict-of-dma_heap_add.patch
new file mode 100644 (file)
index 0000000..ec0dcf9
--- /dev/null
@@ -0,0 +1,94 @@
+From 1d0e7066a80030dcb306d2c4e0fef30aa073d547 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Nov 2022 00:05:36 +0800
+Subject: dma-buf: fix racing conflict of dma_heap_add()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dawei Li <set_pte_at@outlook.com>
+
+[ Upstream commit 432e25902b9651622578c6248e549297d03caf66 ]
+
+Racing conflict could be:
+task A                 task B
+list_for_each_entry
+strcmp(h->name))
+                       list_for_each_entry
+                       strcmp(h->name)
+kzalloc                kzalloc
+......                 .....
+device_create          device_create
+list_add
+                       list_add
+
+The root cause is that task B has no idea about the fact someone
+else(A) has inserted heap with same name when it calls list_add,
+so a potential collision occurs.
+
+Fixes: c02a81fba74f ("dma-buf: Add dma-buf heaps framework")
+Signed-off-by: Dawei Li <set_pte_at@outlook.com>
+Acked-by: Andrew Davis <afd@ti.com>
+Acked-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/TYCP286MB2323873BBDF88020781FB986CA3B9@TYCP286MB2323.JPNP286.PROD.OUTLOOK.COM
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma-buf/dma-heap.c | 28 +++++++++++++++-------------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
+index 8f5848aa144f..59d158873f4c 100644
+--- a/drivers/dma-buf/dma-heap.c
++++ b/drivers/dma-buf/dma-heap.c
+@@ -233,18 +233,6 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
+               return ERR_PTR(-EINVAL);
+       }
+-      /* check the name is unique */
+-      mutex_lock(&heap_list_lock);
+-      list_for_each_entry(h, &heap_list, list) {
+-              if (!strcmp(h->name, exp_info->name)) {
+-                      mutex_unlock(&heap_list_lock);
+-                      pr_err("dma_heap: Already registered heap named %s\n",
+-                             exp_info->name);
+-                      return ERR_PTR(-EINVAL);
+-              }
+-      }
+-      mutex_unlock(&heap_list_lock);
+-
+       heap = kzalloc(sizeof(*heap), GFP_KERNEL);
+       if (!heap)
+               return ERR_PTR(-ENOMEM);
+@@ -283,13 +271,27 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
+               err_ret = ERR_CAST(dev_ret);
+               goto err2;
+       }
+-      /* Add heap to the list */
++
+       mutex_lock(&heap_list_lock);
++      /* check the name is unique */
++      list_for_each_entry(h, &heap_list, list) {
++              if (!strcmp(h->name, exp_info->name)) {
++                      mutex_unlock(&heap_list_lock);
++                      pr_err("dma_heap: Already registered heap named %s\n",
++                             exp_info->name);
++                      err_ret = ERR_PTR(-EINVAL);
++                      goto err3;
++              }
++      }
++
++      /* Add heap to the list */
+       list_add(&heap->list, &heap_list);
+       mutex_unlock(&heap_list_lock);
+       return heap;
++err3:
++      device_destroy(dma_heap_class, heap->heap_devt);
+ err2:
+       cdev_del(&heap->heap_cdev);
+ err1:
+-- 
+2.35.1
+
diff --git a/queue-5.15/drivers-hv-vmbus-fix-double-free-in-the-error-path-o.patch b/queue-5.15/drivers-hv-vmbus-fix-double-free-in-the-error-path-o.patch
new file mode 100644 (file)
index 0000000..85a276a
--- /dev/null
@@ -0,0 +1,53 @@
+From 657fe66c0e8a6f4cae022985a8a88e87ed646a0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Nov 2022 16:11:34 +0800
+Subject: Drivers: hv: vmbus: fix double free in the error path of
+ vmbus_add_channel_work()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit f92a4b50f0bd7fd52391dc4bb9a309085d278f91 ]
+
+In the error path of vmbus_device_register(), device_unregister()
+is called, which calls vmbus_device_release().  The latter frees
+the struct hv_device that was passed in to vmbus_device_register().
+So remove the kfree() in vmbus_add_channel_work() to avoid a double
+free.
+
+Fixes: c2e5df616e1a ("vmbus: add per-channel sysfs info")
+Suggested-by: Michael Kelley <mikelley@microsoft.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/20221119081135.1564691-2-yangyingliang@huawei.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/channel_mgmt.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index 07003019263a..d8dc5cc5e3a8 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -531,13 +531,17 @@ static void vmbus_add_channel_work(struct work_struct *work)
+        * Add the new device to the bus. This will kick off device-driver
+        * binding which eventually invokes the device driver's AddDevice()
+        * method.
++       *
++       * If vmbus_device_register() fails, the 'device_obj' is freed in
++       * vmbus_device_release() as called by device_unregister() in the
++       * error path of vmbus_device_register(). In the outside error
++       * path, there's no need to free it.
+        */
+       ret = vmbus_device_register(newchannel->device_obj);
+       if (ret != 0) {
+               pr_err("unable to add child device object (relid %d)\n",
+                       newchannel->offermsg.child_relid);
+-              kfree(newchannel->device_obj);
+               goto err_deq_chan;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/drivers-hv-vmbus-fix-possible-memory-leak-in-vmbus_d.patch b/queue-5.15/drivers-hv-vmbus-fix-possible-memory-leak-in-vmbus_d.patch
new file mode 100644 (file)
index 0000000..504a7d4
--- /dev/null
@@ -0,0 +1,41 @@
+From ce7ef71d232ded7c223de2e598f0c11cb49e6ed5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Nov 2022 16:11:35 +0800
+Subject: Drivers: hv: vmbus: fix possible memory leak in
+ vmbus_device_register()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 25c94b051592c010abe92c85b0485f1faedc83f3 ]
+
+If device_register() returns error in vmbus_device_register(),
+the name allocated by dev_set_name() must be freed. As comment
+of device_register() says, it should use put_device() to give
+up the reference in the error path. So fix this by calling
+put_device(), then the name can be freed in kobject_cleanup().
+
+Fixes: 09d50ff8a233 ("Staging: hv: make the Hyper-V virtual bus code build")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/20221119081135.1564691-3-yangyingliang@huawei.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/vmbus_drv.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index ecfc299834e1..b906a3a7941c 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -2109,6 +2109,7 @@ int vmbus_device_register(struct hv_device *child_device_obj)
+       ret = device_register(&child_device_obj->device);
+       if (ret) {
+               pr_err("Unable to register child device\n");
++              put_device(&child_device_obj->device);
+               return ret;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/fs-do-not-update-freeing-inode-i_io_list.patch b/queue-5.15/fs-do-not-update-freeing-inode-i_io_list.patch
new file mode 100644 (file)
index 0000000..e692f68
--- /dev/null
@@ -0,0 +1,84 @@
+From eb690857b72ef6d06fd76cee6527446266934ba4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 20:20:01 +0000
+Subject: fs: do not update freeing inode i_io_list
+
+From: Svyatoslav Feldsherov <feldsherov@google.com>
+
+[ Upstream commit 4e3c51f4e805291b057d12f5dda5aeb50a538dc4 ]
+
+After commit cbfecb927f42 ("fs: record I_DIRTY_TIME even if inode
+already has I_DIRTY_INODE") writeback_single_inode can push inode with
+I_DIRTY_TIME set to b_dirty_time list. In case of freeing inode with
+I_DIRTY_TIME set this can happen after deletion of inode from i_io_list
+at evict. Stack trace is following.
+
+evict
+fat_evict_inode
+fat_truncate_blocks
+fat_flush_inodes
+writeback_inode
+sync_inode_metadata(inode, sync=0)
+writeback_single_inode(inode, wbc) <- wbc->sync_mode == WB_SYNC_NONE
+
+This will lead to use after free in flusher thread.
+
+Similar issue can be triggered if writeback_single_inode in the
+stack trace update inode->i_io_list. Add explicit check to avoid it.
+
+Fixes: cbfecb927f42 ("fs: record I_DIRTY_TIME even if inode already has I_DIRTY_INODE")
+Reported-by: syzbot+6ba92bd00d5093f7e371@syzkaller.appspotmail.com
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Svyatoslav Feldsherov <feldsherov@google.com>
+Link: https://lore.kernel.org/r/20221115202001.324188-1-feldsherov@google.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fs-writeback.c | 30 +++++++++++++++++++-----------
+ 1 file changed, 19 insertions(+), 11 deletions(-)
+
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index 2a27f0256fa3..f4a5a0c2858a 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -1739,18 +1739,26 @@ static int writeback_single_inode(struct inode *inode,
+       wb = inode_to_wb_and_lock_list(inode);
+       spin_lock(&inode->i_lock);
+       /*
+-       * If the inode is now fully clean, then it can be safely removed from
+-       * its writeback list (if any).  Otherwise the flusher threads are
+-       * responsible for the writeback lists.
++       * If the inode is freeing, its i_io_list shoudn't be updated
++       * as it can be finally deleted at this moment.
+        */
+-      if (!(inode->i_state & I_DIRTY_ALL))
+-              inode_cgwb_move_to_attached(inode, wb);
+-      else if (!(inode->i_state & I_SYNC_QUEUED)) {
+-              if ((inode->i_state & I_DIRTY))
+-                      redirty_tail_locked(inode, wb);
+-              else if (inode->i_state & I_DIRTY_TIME) {
+-                      inode->dirtied_when = jiffies;
+-                      inode_io_list_move_locked(inode, wb, &wb->b_dirty_time);
++      if (!(inode->i_state & I_FREEING)) {
++              /*
++               * If the inode is now fully clean, then it can be safely
++               * removed from its writeback list (if any). Otherwise the
++               * flusher threads are responsible for the writeback lists.
++               */
++              if (!(inode->i_state & I_DIRTY_ALL))
++                      inode_cgwb_move_to_attached(inode, wb);
++              else if (!(inode->i_state & I_SYNC_QUEUED)) {
++                      if ((inode->i_state & I_DIRTY))
++                              redirty_tail_locked(inode, wb);
++                      else if (inode->i_state & I_DIRTY_TIME) {
++                              inode->dirtied_when = jiffies;
++                              inode_io_list_move_locked(inode,
++                                                        wb,
++                                                        &wb->b_dirty_time);
++                      }
+               }
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/iavf-do-not-restart-tx-queues-after-reset-task-failu.patch b/queue-5.15/iavf-do-not-restart-tx-queues-after-reset-task-failu.patch
new file mode 100644 (file)
index 0000000..3d0a0e0
--- /dev/null
@@ -0,0 +1,149 @@
+From 68793f1fd45d1ab21eee9bc662311f9fed97c64c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 11:25:02 +0100
+Subject: iavf: Do not restart Tx queues after reset task failure
+
+From: Ivan Vecera <ivecera@redhat.com>
+
+[ Upstream commit 08f1c147b7265245d67321585c68a27e990e0c4b ]
+
+After commit aa626da947e9 ("iavf: Detach device during reset task")
+the device is detached during reset task and re-attached at its end.
+The problem occurs when reset task fails because Tx queues are
+restarted during device re-attach and this leads later to a crash.
+
+To resolve this issue properly close the net device in cause of
+failure in reset task to avoid restarting of tx queues at the end.
+Also replace the hacky manipulation with IFF_UP flag by device close
+that clears properly both IFF_UP and __LINK_STATE_START flags.
+In these case iavf_close() does not do anything because the adapter
+state is already __IAVF_DOWN.
+
+Reproducer:
+1) Run some Tx traffic (e.g. iperf3) over iavf interface
+2) Set VF trusted / untrusted in loop
+
+[root@host ~]# cat repro.sh
+
+PF=enp65s0f0
+IF=${PF}v0
+
+ip link set up $IF
+ip addr add 192.168.0.2/24 dev $IF
+sleep 1
+
+iperf3 -c 192.168.0.1 -t 600 --logfile /dev/null &
+sleep 2
+
+while :; do
+        ip link set $PF vf 0 trust on
+        ip link set $PF vf 0 trust off
+done
+[root@host ~]# ./repro.sh
+
+Result:
+[ 2006.650969] iavf 0000:41:01.0: Failed to init adminq: -53
+[ 2006.675662] ice 0000:41:00.0: VF 0 is now trusted
+[ 2006.689997] iavf 0000:41:01.0: Reset task did not complete, VF disabled
+[ 2006.696611] iavf 0000:41:01.0: failed to allocate resources during reinit
+[ 2006.703209] ice 0000:41:00.0: VF 0 is now untrusted
+[ 2006.737011] ice 0000:41:00.0: VF 0 is now trusted
+[ 2006.764536] ice 0000:41:00.0: VF 0 is now untrusted
+[ 2006.768919] BUG: kernel NULL pointer dereference, address: 0000000000000b4a
+[ 2006.776358] #PF: supervisor read access in kernel mode
+[ 2006.781488] #PF: error_code(0x0000) - not-present page
+[ 2006.786620] PGD 0 P4D 0
+[ 2006.789152] Oops: 0000 [#1] PREEMPT SMP NOPTI
+[ 2006.792903] ice 0000:41:00.0: VF 0 is now trusted
+[ 2006.793501] CPU: 4 PID: 0 Comm: swapper/4 Kdump: loaded Not tainted 6.1.0-rc3+ #2
+[ 2006.805668] Hardware name: Abacus electric, s.r.o. - servis@abacus.cz Super Server/H12SSW-iN, BIOS 2.4 04/13/2022
+[ 2006.815915] RIP: 0010:iavf_xmit_frame_ring+0x96/0xf70 [iavf]
+[ 2006.821028] ice 0000:41:00.0: VF 0 is now untrusted
+[ 2006.821572] Code: 48 83 c1 04 48 c1 e1 04 48 01 f9 48 83 c0 10 6b 50 f8 55 c1 ea 14 45 8d 64 14 01 48 39 c8 75 eb 41 83 fc 07 0f 8f e9 08 00 00 <0f> b7 45 4a 0f b7 55 48 41 8d 74 24 05 31 c9 66 39 d0 0f 86 da 00
+[ 2006.845181] RSP: 0018:ffffb253004bc9e8 EFLAGS: 00010293
+[ 2006.850397] RAX: ffff9d154de45b00 RBX: ffff9d15497d52e8 RCX: ffff9d154de45b00
+[ 2006.856327] ice 0000:41:00.0: VF 0 is now trusted
+[ 2006.857523] RDX: 0000000000000000 RSI: 00000000000005a8 RDI: ffff9d154de45ac0
+[ 2006.857525] RBP: 0000000000000b00 R08: ffff9d159cb010ac R09: 0000000000000001
+[ 2006.857526] R10: ffff9d154de45940 R11: 0000000000000000 R12: 0000000000000002
+[ 2006.883600] R13: ffff9d1770838dc0 R14: 0000000000000000 R15: ffffffffc07b8380
+[ 2006.885840] ice 0000:41:00.0: VF 0 is now untrusted
+[ 2006.890725] FS:  0000000000000000(0000) GS:ffff9d248e900000(0000) knlGS:0000000000000000
+[ 2006.890727] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 2006.909419] CR2: 0000000000000b4a CR3: 0000000c39c10002 CR4: 0000000000770ee0
+[ 2006.916543] PKRU: 55555554
+[ 2006.918254] ice 0000:41:00.0: VF 0 is now trusted
+[ 2006.919248] Call Trace:
+[ 2006.919250]  <IRQ>
+[ 2006.919252]  dev_hard_start_xmit+0x9e/0x1f0
+[ 2006.932587]  sch_direct_xmit+0xa0/0x370
+[ 2006.936424]  __dev_queue_xmit+0x7af/0xd00
+[ 2006.940429]  ip_finish_output2+0x26c/0x540
+[ 2006.944519]  ip_output+0x71/0x110
+[ 2006.947831]  ? __ip_finish_output+0x2b0/0x2b0
+[ 2006.952180]  __ip_queue_xmit+0x16d/0x400
+[ 2006.952721] ice 0000:41:00.0: VF 0 is now untrusted
+[ 2006.956098]  __tcp_transmit_skb+0xa96/0xbf0
+[ 2006.965148]  __tcp_retransmit_skb+0x174/0x860
+[ 2006.969499]  ? cubictcp_cwnd_event+0x40/0x40
+[ 2006.973769]  tcp_retransmit_skb+0x14/0xb0
+...
+
+Fixes: aa626da947e9 ("iavf: Detach device during reset task")
+Cc: Jacob Keller <jacob.e.keller@intel.com>
+Cc: Patryk Piotrowski <patryk.piotrowski@intel.com>
+Cc: SlawomirX Laba <slawomirx.laba@intel.com>
+Signed-off-by: Ivan Vecera <ivecera@redhat.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 493d3c407d4f..d6aa1805c55b 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -2270,7 +2270,6 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
+       iavf_free_queues(adapter);
+       memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE);
+       iavf_shutdown_adminq(&adapter->hw);
+-      adapter->netdev->flags &= ~IFF_UP;
+       adapter->flags &= ~IAVF_FLAG_RESET_PENDING;
+       iavf_change_state(adapter, __IAVF_DOWN);
+       wake_up(&adapter->down_waitqueue);
+@@ -2369,6 +2368,11 @@ static void iavf_reset_task(struct work_struct *work)
+               iavf_disable_vf(adapter);
+               mutex_unlock(&adapter->client_lock);
+               mutex_unlock(&adapter->crit_lock);
++              if (netif_running(netdev)) {
++                      rtnl_lock();
++                      dev_close(netdev);
++                      rtnl_unlock();
++              }
+               return; /* Do not attempt to reinit. It's dead, Jim. */
+       }
+@@ -2504,6 +2508,16 @@ static void iavf_reset_task(struct work_struct *work)
+       mutex_unlock(&adapter->client_lock);
+       mutex_unlock(&adapter->crit_lock);
++
++      if (netif_running(netdev)) {
++              /* Close device to ensure that Tx queues will not be started
++               * during netif_device_attach() at the end of the reset task.
++               */
++              rtnl_lock();
++              dev_close(netdev);
++              rtnl_unlock();
++      }
++
+       dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
+ reset_finish:
+       rtnl_lock();
+-- 
+2.35.1
+
diff --git a/queue-5.15/iavf-fix-a-crash-during-reset-task.patch b/queue-5.15/iavf-fix-a-crash-during-reset-task.patch
new file mode 100644 (file)
index 0000000..df37192
--- /dev/null
@@ -0,0 +1,95 @@
+From 97b47c33f46d5bba1543bd6e941fe9fc72aa671c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Nov 2022 10:35:34 +0100
+Subject: iavf: Fix a crash during reset task
+
+From: Ivan Vecera <ivecera@redhat.com>
+
+[ Upstream commit c678669d6b13b77de3b99b97526aaf23c3088d0a ]
+
+Recent commit aa626da947e9 ("iavf: Detach device during reset task")
+removed netif_tx_stop_all_queues() with an assumption that Tx queues
+are already stopped by netif_device_detach() in the beginning of
+reset task. This assumption is incorrect because during reset
+task a potential link event can start Tx queues again.
+Revert this change to fix this issue.
+
+Reproducer:
+1. Run some Tx traffic (e.g. iperf3) over iavf interface
+2. Switch MTU of this interface in a loop
+
+[root@host ~]# cat repro.sh
+
+IF=enp2s0f0v0
+
+iperf3 -c 192.168.0.1 -t 600 --logfile /dev/null &
+sleep 2
+
+while :; do
+        for i in 1280 1500 2000 900 ; do
+                ip link set $IF mtu $i
+                sleep 2
+        done
+done
+[root@host ~]# ./repro.sh
+
+Result:
+[  306.199917] iavf 0000:02:02.0 enp2s0f0v0: NIC Link is Up Speed is 40 Gbps Full Duplex
+[  308.205944] iavf 0000:02:02.0 enp2s0f0v0: NIC Link is Up Speed is 40 Gbps Full Duplex
+[  310.103223] BUG: kernel NULL pointer dereference, address: 0000000000000008
+[  310.110179] #PF: supervisor write access in kernel mode
+[  310.115396] #PF: error_code(0x0002) - not-present page
+[  310.120526] PGD 0 P4D 0
+[  310.123057] Oops: 0002 [#1] PREEMPT SMP NOPTI
+[  310.127408] CPU: 24 PID: 183 Comm: kworker/u64:9 Kdump: loaded Not tainted 6.1.0-rc3+ #2
+[  310.135485] Hardware name: Abacus electric, s.r.o. - servis@abacus.cz Super Server/H12SSW-iN, BIOS 2.4 04/13/2022
+[  310.145728] Workqueue: iavf iavf_reset_task [iavf]
+[  310.150520] RIP: 0010:iavf_xmit_frame_ring+0xd1/0xf70 [iavf]
+[  310.156180] Code: d0 0f 86 da 00 00 00 83 e8 01 0f b7 fa 29 f8 01 c8 39 c6 0f 8f a0 08 00 00 48 8b 45 20 48 8d 14 92 bf 01 00 00 00 4c 8d 3c d0 <49> 89 5f 08 8b 43 70 66 41 89 7f 14 41 89 47 10 f6 83 82 00 00 00
+[  310.174918] RSP: 0018:ffffbb5f0082caa0 EFLAGS: 00010293
+[  310.180137] RAX: 0000000000000000 RBX: ffff92345471a6e8 RCX: 0000000000000200
+[  310.187259] RDX: 0000000000000000 RSI: 000000000000000d RDI: 0000000000000001
+[  310.194385] RBP: ffff92341d249000 R08: ffff92434987fcac R09: 0000000000000001
+[  310.201509] R10: 0000000011f683b9 R11: 0000000011f50641 R12: 0000000000000008
+[  310.208631] R13: ffff923447500000 R14: 0000000000000000 R15: 0000000000000000
+[  310.215756] FS:  0000000000000000(0000) GS:ffff92434ee00000(0000) knlGS:0000000000000000
+[  310.223835] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  310.229572] CR2: 0000000000000008 CR3: 0000000fbc210004 CR4: 0000000000770ee0
+[  310.236696] PKRU: 55555554
+[  310.239399] Call Trace:
+[  310.241844]  <IRQ>
+[  310.243855]  ? dst_alloc+0x5b/0xb0
+[  310.247260]  dev_hard_start_xmit+0x9e/0x1f0
+[  310.251439]  sch_direct_xmit+0xa0/0x370
+[  310.255276]  __qdisc_run+0x13e/0x580
+[  310.258848]  __dev_queue_xmit+0x431/0xd00
+[  310.262851]  ? selinux_ip_postroute+0x147/0x3f0
+[  310.267377]  ip_finish_output2+0x26c/0x540
+
+Fixes: aa626da947e9 ("iavf: Detach device during reset task")
+Cc: Jacob Keller <jacob.e.keller@intel.com>
+Cc: Patryk Piotrowski <patryk.piotrowski@intel.com>
+Cc: SlawomirX Laba <slawomirx.laba@intel.com>
+Signed-off-by: Ivan Vecera <ivecera@redhat.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 629ebdfa48b8..493d3c407d4f 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -2381,6 +2381,7 @@ static void iavf_reset_task(struct work_struct *work)
+       if (running) {
+               netif_carrier_off(netdev);
++              netif_tx_stop_all_queues(netdev);
+               adapter->link_up = false;
+               iavf_napi_disable_all(adapter);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/iavf-fix-race-condition-between-iavf_shutdown-and-ia.patch b/queue-5.15/iavf-fix-race-condition-between-iavf_shutdown-and-ia.patch
new file mode 100644 (file)
index 0000000..85a5868
--- /dev/null
@@ -0,0 +1,66 @@
+From 4086862343363828675eaae5cc52ec94b86da71d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Nov 2022 14:00:03 +0100
+Subject: iavf: Fix race condition between iavf_shutdown and iavf_remove
+
+From: Slawomir Laba <slawomirx.laba@intel.com>
+
+[ Upstream commit a8417330f8a57275ed934293e832982b6d882713 ]
+
+Fix a deadlock introduced by commit
+974578017fc1 ("iavf: Add waiting so the port is initialized in remove")
+due to race condition between iavf_shutdown and iavf_remove, where
+iavf_remove stucks forever in while loop since iavf_shutdown already
+set __IAVF_REMOVE adapter state.
+
+Fix this by checking if the __IAVF_IN_REMOVE_TASK has already been
+set and return if so.
+
+Fixes: 974578017fc1 ("iavf: Add waiting so the port is initialized in remove")
+Signed-off-by: Slawomir Laba <slawomirx.laba@intel.com>
+Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Tested-by: Marek Szlosek <marek.szlosek@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index d6aa1805c55b..4b2e99be7ef5 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -4189,23 +4189,21 @@ static int __maybe_unused iavf_resume(struct device *dev_d)
+ static void iavf_remove(struct pci_dev *pdev)
+ {
+       struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev);
+-      struct net_device *netdev = adapter->netdev;
+       struct iavf_fdir_fltr *fdir, *fdirtmp;
+       struct iavf_vlan_filter *vlf, *vlftmp;
++      struct iavf_cloud_filter *cf, *cftmp;
+       struct iavf_adv_rss *rss, *rsstmp;
+       struct iavf_mac_filter *f, *ftmp;
+-      struct iavf_cloud_filter *cf, *cftmp;
+-      struct iavf_hw *hw = &adapter->hw;
++      struct net_device *netdev;
++      struct iavf_hw *hw;
+       int err;
+-      /* When reboot/shutdown is in progress no need to do anything
+-       * as the adapter is already REMOVE state that was set during
+-       * iavf_shutdown() callback.
+-       */
+-      if (adapter->state == __IAVF_REMOVE)
++      netdev = adapter->netdev;
++      hw = &adapter->hw;
++
++      if (test_and_set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))
+               return;
+-      set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section);
+       /* Wait until port initialization is complete.
+        * There are flows where register/unregister netdev may race.
+        */
+-- 
+2.35.1
+
diff --git a/queue-5.15/ipv4-fix-error-return-code-in-fib_table_insert.patch b/queue-5.15/ipv4-fix-error-return-code-in-fib_table_insert.patch
new file mode 100644 (file)
index 0000000..7634733
--- /dev/null
@@ -0,0 +1,40 @@
+From 65bff21f6d4e5a134969c86de522b2cc800a169e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Nov 2022 15:28:38 +0800
+Subject: ipv4: Fix error return code in fib_table_insert()
+
+From: Ziyang Xuan <william.xuanziyang@huawei.com>
+
+[ Upstream commit 568fe84940ac0e4e0b2cd7751b8b4911f7b9c215 ]
+
+In fib_table_insert(), if the alias was already inserted, but node not
+exist, the error code should be set before return from error handling path.
+
+Fixes: a6c76c17df02 ("ipv4: Notify route after insertion to the routing table")
+Signed-off-by: Ziyang Xuan <william.xuanziyang@huawei.com>
+Link: https://lore.kernel.org/r/20221120072838.2167047-1-william.xuanziyang@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/fib_trie.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index 19c6e7b93d3d..52f9f69f57b3 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -1375,8 +1375,10 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
+       /* The alias was already inserted, so the node must exist. */
+       l = l ? l : fib_find_node(t, &tp, key);
+-      if (WARN_ON_ONCE(!l))
++      if (WARN_ON_ONCE(!l)) {
++              err = -ENOENT;
+               goto out_free_new_fa;
++      }
+       if (fib_find_alias(&l->leaf, new_fa->fa_slen, 0, 0, tb->tb_id, true) ==
+           new_fa) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/macsec-fix-invalid-error-code-set.patch b/queue-5.15/macsec-fix-invalid-error-code-set.patch
new file mode 100644 (file)
index 0000000..8645a53
--- /dev/null
@@ -0,0 +1,38 @@
+From dd7b3ddd383326e20d3fdd15754085321670d762 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 09:12:49 +0800
+Subject: macsec: Fix invalid error code set
+
+From: YueHaibing <yuehaibing@huawei.com>
+
+[ Upstream commit 7cef6b73fba96abef731a53501924fc3c4a0f947 ]
+
+'ret' is defined twice in macsec_changelink(), when it is set in macsec_is_offloaded
+case, it will be invalid before return.
+
+Fixes: 3cf3227a21d1 ("net: macsec: hardware offloading infrastructure")
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Reviewed-by: Saeed Mahameed <saeed@kernel.org>
+Reviewed-by: Antoine Tenart <atenart@kernel.org>
+Link: https://lore.kernel.org/r/20221118011249.48112-1-yuehaibing@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macsec.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index f1961d7f9db2..aa9d0dfeda5a 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -3808,7 +3808,6 @@ static int macsec_changelink(struct net_device *dev, struct nlattr *tb[],
+       if (macsec_is_offloaded(macsec)) {
+               const struct macsec_ops *ops;
+               struct macsec_context ctx;
+-              int ret;
+               ops = macsec_get_ops(netdev_priv(dev), &ctx);
+               if (!ops) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-dsa-sja1105-disallow-c45-transactions-on-the-bas.patch b/queue-5.15/net-dsa-sja1105-disallow-c45-transactions-on-the-bas.patch
new file mode 100644 (file)
index 0000000..a1230c2
--- /dev/null
@@ -0,0 +1,71 @@
+From ecff6accce6d8d1905404f5838d5b9c54f387c6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 12:06:53 +0200
+Subject: net: dsa: sja1105: disallow C45 transactions on the BASE-TX MDIO bus
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 24deec6b9e4a051635f75777844ffc184644fec9 ]
+
+You'd think people know that the internal 100BASE-TX PHY on the SJA1110
+responds only to clause 22 MDIO transactions, but they don't :)
+
+When a clause 45 transaction is attempted, sja1105_base_tx_mdio_read()
+and sja1105_base_tx_mdio_write() don't expect "reg" to contain bit 30
+set (MII_ADDR_C45) and pack this value into the SPI transaction buffer.
+
+But the field in the SPI buffer has a width smaller than 30 bits, so we
+see this confusing message from the packing() API rather than a proper
+rejection of C45 transactions:
+
+Call trace:
+ dump_stack+0x1c/0x38
+ sja1105_pack+0xbc/0xc0 [sja1105]
+ sja1105_xfer+0x114/0x2b0 [sja1105]
+ sja1105_xfer_u32+0x44/0xf4 [sja1105]
+ sja1105_base_tx_mdio_read+0x44/0x7c [sja1105]
+ mdiobus_read+0x44/0x80
+ get_phy_c45_ids+0x70/0x234
+ get_phy_device+0x68/0x15c
+ fwnode_mdiobus_register_phy+0x74/0x240
+ of_mdiobus_register+0x13c/0x380
+ sja1105_mdiobus_register+0x368/0x490 [sja1105]
+ sja1105_setup+0x94/0x119c [sja1105]
+Cannot store 401d2405 inside bits 24-4 (would truncate)
+
+Fixes: 5a8f09748ee7 ("net: dsa: sja1105: register the MDIO buses for 100base-T1 and 100base-TX")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.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/sja1105/sja1105_mdio.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c
+index 215dd17ca790..4059fcc8c832 100644
+--- a/drivers/net/dsa/sja1105/sja1105_mdio.c
++++ b/drivers/net/dsa/sja1105/sja1105_mdio.c
+@@ -256,6 +256,9 @@ static int sja1105_base_tx_mdio_read(struct mii_bus *bus, int phy, int reg)
+       u32 tmp;
+       int rc;
++      if (reg & MII_ADDR_C45)
++              return -EOPNOTSUPP;
++
+       rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg,
+                             &tmp, NULL);
+       if (rc < 0)
+@@ -272,6 +275,9 @@ static int sja1105_base_tx_mdio_write(struct mii_bus *bus, int phy, int reg,
+       const struct sja1105_regs *regs = priv->info->regs;
+       u32 tmp = val;
++      if (reg & MII_ADDR_C45)
++              return -EOPNOTSUPP;
++
+       return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg,
+                               &tmp, NULL);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-enetc-cache-accesses-to-priv-si-hw.patch b/queue-5.15/net-enetc-cache-accesses-to-priv-si-hw.patch
new file mode 100644 (file)
index 0000000..e9e6440
--- /dev/null
@@ -0,0 +1,377 @@
+From c79253ffb79dbca1713097c6eb42bf14bd2cf7a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Sep 2022 12:52:02 +0300
+Subject: net: enetc: cache accesses to &priv->si->hw
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 715bf2610f1d1adf3d4f9b7b3dd729984ec4270a ]
+
+The &priv->si->hw construct dereferences 2 pointers and makes lines
+longer than they need to be, in turn making the code harder to read.
+
+Replace &priv->si->hw accesses with a "hw" variable when there are 2 or
+more accesses within a function that dereference this. This includes
+loops, since &priv->si->hw is a loop invariant.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 290b5fe096e7 ("net: enetc: preserve TX ring priority across reconfiguration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc.c  | 28 +++++----
+ drivers/net/ethernet/freescale/enetc/enetc.h  |  9 +--
+ .../net/ethernet/freescale/enetc/enetc_qos.c  | 60 +++++++++----------
+ 3 files changed, 49 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index 77d765809c1e..0ced688bf9ba 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -1831,13 +1831,14 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
+ static void enetc_setup_bdrs(struct enetc_ndev_priv *priv)
+ {
++      struct enetc_hw *hw = &priv->si->hw;
+       int i;
+       for (i = 0; i < priv->num_tx_rings; i++)
+-              enetc_setup_txbdr(&priv->si->hw, priv->tx_ring[i]);
++              enetc_setup_txbdr(hw, priv->tx_ring[i]);
+       for (i = 0; i < priv->num_rx_rings; i++)
+-              enetc_setup_rxbdr(&priv->si->hw, priv->rx_ring[i]);
++              enetc_setup_rxbdr(hw, priv->rx_ring[i]);
+ }
+ static void enetc_clear_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
+@@ -1870,13 +1871,14 @@ static void enetc_clear_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
+ static void enetc_clear_bdrs(struct enetc_ndev_priv *priv)
+ {
++      struct enetc_hw *hw = &priv->si->hw;
+       int i;
+       for (i = 0; i < priv->num_tx_rings; i++)
+-              enetc_clear_txbdr(&priv->si->hw, priv->tx_ring[i]);
++              enetc_clear_txbdr(hw, priv->tx_ring[i]);
+       for (i = 0; i < priv->num_rx_rings; i++)
+-              enetc_clear_rxbdr(&priv->si->hw, priv->rx_ring[i]);
++              enetc_clear_rxbdr(hw, priv->rx_ring[i]);
+       udelay(1);
+ }
+@@ -1884,13 +1886,13 @@ static void enetc_clear_bdrs(struct enetc_ndev_priv *priv)
+ static int enetc_setup_irqs(struct enetc_ndev_priv *priv)
+ {
+       struct pci_dev *pdev = priv->si->pdev;
++      struct enetc_hw *hw = &priv->si->hw;
+       int i, j, err;
+       for (i = 0; i < priv->bdr_int_num; i++) {
+               int irq = pci_irq_vector(pdev, ENETC_BDR_INT_BASE_IDX + i);
+               struct enetc_int_vector *v = priv->int_vector[i];
+               int entry = ENETC_BDR_INT_BASE_IDX + i;
+-              struct enetc_hw *hw = &priv->si->hw;
+               snprintf(v->name, sizeof(v->name), "%s-rxtx%d",
+                        priv->ndev->name, i);
+@@ -1978,13 +1980,14 @@ static void enetc_setup_interrupts(struct enetc_ndev_priv *priv)
+ static void enetc_clear_interrupts(struct enetc_ndev_priv *priv)
+ {
++      struct enetc_hw *hw = &priv->si->hw;
+       int i;
+       for (i = 0; i < priv->num_tx_rings; i++)
+-              enetc_txbdr_wr(&priv->si->hw, i, ENETC_TBIER, 0);
++              enetc_txbdr_wr(hw, i, ENETC_TBIER, 0);
+       for (i = 0; i < priv->num_rx_rings; i++)
+-              enetc_rxbdr_wr(&priv->si->hw, i, ENETC_RBIER, 0);
++              enetc_rxbdr_wr(hw, i, ENETC_RBIER, 0);
+ }
+ static int enetc_phylink_connect(struct net_device *ndev)
+@@ -2151,6 +2154,7 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+ {
+       struct enetc_ndev_priv *priv = netdev_priv(ndev);
+       struct tc_mqprio_qopt *mqprio = type_data;
++      struct enetc_hw *hw = &priv->si->hw;
+       struct enetc_bdr *tx_ring;
+       int num_stack_tx_queues;
+       u8 num_tc;
+@@ -2167,7 +2171,7 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+               /* Reset all ring priorities to 0 */
+               for (i = 0; i < priv->num_tx_rings; i++) {
+                       tx_ring = priv->tx_ring[i];
+-                      enetc_set_bdr_prio(&priv->si->hw, tx_ring->index, 0);
++                      enetc_set_bdr_prio(hw, tx_ring->index, 0);
+               }
+               return 0;
+@@ -2186,7 +2190,7 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+        */
+       for (i = 0; i < num_tc; i++) {
+               tx_ring = priv->tx_ring[i];
+-              enetc_set_bdr_prio(&priv->si->hw, tx_ring->index, i);
++              enetc_set_bdr_prio(hw, tx_ring->index, i);
+       }
+       /* Reset the number of netdev queues based on the TC count */
+@@ -2296,19 +2300,21 @@ static int enetc_set_rss(struct net_device *ndev, int en)
+ static void enetc_enable_rxvlan(struct net_device *ndev, bool en)
+ {
+       struct enetc_ndev_priv *priv = netdev_priv(ndev);
++      struct enetc_hw *hw = &priv->si->hw;
+       int i;
+       for (i = 0; i < priv->num_rx_rings; i++)
+-              enetc_bdr_enable_rxvlan(&priv->si->hw, i, en);
++              enetc_bdr_enable_rxvlan(hw, i, en);
+ }
+ static void enetc_enable_txvlan(struct net_device *ndev, bool en)
+ {
+       struct enetc_ndev_priv *priv = netdev_priv(ndev);
++      struct enetc_hw *hw = &priv->si->hw;
+       int i;
+       for (i = 0; i < priv->num_tx_rings; i++)
+-              enetc_bdr_enable_txvlan(&priv->si->hw, i, en);
++              enetc_bdr_enable_txvlan(hw, i, en);
+ }
+ void enetc_set_features(struct net_device *ndev, netdev_features_t features)
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
+index f304cdb854ec..7ec807bd9828 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.h
++++ b/drivers/net/ethernet/freescale/enetc/enetc.h
+@@ -423,19 +423,20 @@ int enetc_set_psfp(struct net_device *ndev, bool en);
+ static inline void enetc_get_max_cap(struct enetc_ndev_priv *priv)
+ {
++      struct enetc_hw *hw = &priv->si->hw;
+       u32 reg;
+-      reg = enetc_port_rd(&priv->si->hw, ENETC_PSIDCAPR);
++      reg = enetc_port_rd(hw, ENETC_PSIDCAPR);
+       priv->psfp_cap.max_streamid = reg & ENETC_PSIDCAPR_MSK;
+       /* Port stream filter capability */
+-      reg = enetc_port_rd(&priv->si->hw, ENETC_PSFCAPR);
++      reg = enetc_port_rd(hw, ENETC_PSFCAPR);
+       priv->psfp_cap.max_psfp_filter = reg & ENETC_PSFCAPR_MSK;
+       /* Port stream gate capability */
+-      reg = enetc_port_rd(&priv->si->hw, ENETC_PSGCAPR);
++      reg = enetc_port_rd(hw, ENETC_PSGCAPR);
+       priv->psfp_cap.max_psfp_gate = (reg & ENETC_PSGCAPR_SGIT_MSK);
+       priv->psfp_cap.max_psfp_gatelist = (reg & ENETC_PSGCAPR_GCL_MSK) >> 16;
+       /* Port flow meter capability */
+-      reg = enetc_port_rd(&priv->si->hw, ENETC_PFMCAPR);
++      reg = enetc_port_rd(hw, ENETC_PFMCAPR);
+       priv->psfp_cap.max_psfp_meter = reg & ENETC_PFMCAPR_MSK;
+ }
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+index 9fd9abad34f8..6baf2619a51e 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+@@ -17,8 +17,9 @@ static u16 enetc_get_max_gcl_len(struct enetc_hw *hw)
+ void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed)
+ {
++      struct enetc_hw *hw = &priv->si->hw;
+       u32 old_speed = priv->speed;
+-      u32 pspeed;
++      u32 pspeed, tmp;
+       if (speed == old_speed)
+               return;
+@@ -39,10 +40,8 @@ void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed)
+       }
+       priv->speed = speed;
+-      enetc_port_wr(&priv->si->hw, ENETC_PMR,
+-                    (enetc_port_rd(&priv->si->hw, ENETC_PMR)
+-                    & (~ENETC_PMR_PSPEED_MASK))
+-                    | pspeed);
++      tmp = enetc_port_rd(hw, ENETC_PMR);
++      enetc_port_wr(hw, ENETC_PMR, (tmp & ~ENETC_PMR_PSPEED_MASK) | pspeed);
+ }
+ #define ENETC_QOS_ALIGN       64
+@@ -50,6 +49,7 @@ static int enetc_setup_taprio(struct net_device *ndev,
+                             struct tc_taprio_qopt_offload *admin_conf)
+ {
+       struct enetc_ndev_priv *priv = netdev_priv(ndev);
++      struct enetc_hw *hw = &priv->si->hw;
+       struct enetc_cbd cbd = {.cmd = 0};
+       struct tgs_gcl_conf *gcl_config;
+       struct tgs_gcl_data *gcl_data;
+@@ -62,15 +62,13 @@ static int enetc_setup_taprio(struct net_device *ndev,
+       int err;
+       int i;
+-      if (admin_conf->num_entries > enetc_get_max_gcl_len(&priv->si->hw))
++      if (admin_conf->num_entries > enetc_get_max_gcl_len(hw))
+               return -EINVAL;
+       gcl_len = admin_conf->num_entries;
+-      tge = enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET);
++      tge = enetc_rd(hw, ENETC_QBV_PTGCR_OFFSET);
+       if (!admin_conf->enable) {
+-              enetc_wr(&priv->si->hw,
+-                       ENETC_QBV_PTGCR_OFFSET,
+-                       tge & (~ENETC_QBV_TGE));
++              enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge & ~ENETC_QBV_TGE);
+               priv->active_offloads &= ~ENETC_F_QBV;
+@@ -127,14 +125,11 @@ static int enetc_setup_taprio(struct net_device *ndev,
+       cbd.cls = BDCR_CMD_PORT_GCL;
+       cbd.status_flags = 0;
+-      enetc_wr(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET,
+-               tge | ENETC_QBV_TGE);
++      enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge | ENETC_QBV_TGE);
+       err = enetc_send_cmd(priv->si, &cbd);
+       if (err)
+-              enetc_wr(&priv->si->hw,
+-                       ENETC_QBV_PTGCR_OFFSET,
+-                       tge & (~ENETC_QBV_TGE));
++              enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge & ~ENETC_QBV_TGE);
+       dma_free_coherent(&priv->si->pdev->dev, data_size + ENETC_QOS_ALIGN,
+                         tmp, dma);
+@@ -149,6 +144,7 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
+ {
+       struct tc_taprio_qopt_offload *taprio = type_data;
+       struct enetc_ndev_priv *priv = netdev_priv(ndev);
++      struct enetc_hw *hw = &priv->si->hw;
+       int err;
+       int i;
+@@ -158,16 +154,14 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
+                       return -EBUSY;
+       for (i = 0; i < priv->num_tx_rings; i++)
+-              enetc_set_bdr_prio(&priv->si->hw,
+-                                 priv->tx_ring[i]->index,
++              enetc_set_bdr_prio(hw, priv->tx_ring[i]->index,
+                                  taprio->enable ? i : 0);
+       err = enetc_setup_taprio(ndev, taprio);
+       if (err)
+               for (i = 0; i < priv->num_tx_rings; i++)
+-                      enetc_set_bdr_prio(&priv->si->hw,
+-                                         priv->tx_ring[i]->index,
++                      enetc_set_bdr_prio(hw, priv->tx_ring[i]->index,
+                                          taprio->enable ? 0 : i);
+       return err;
+@@ -189,7 +183,7 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+       struct tc_cbs_qopt_offload *cbs = type_data;
+       u32 port_transmit_rate = priv->speed;
+       u8 tc_nums = netdev_get_num_tc(ndev);
+-      struct enetc_si *si = priv->si;
++      struct enetc_hw *hw = &priv->si->hw;
+       u32 hi_credit_bit, hi_credit_reg;
+       u32 max_interference_size;
+       u32 port_frame_max_size;
+@@ -210,15 +204,15 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+                * lower than this TC have been disabled.
+                */
+               if (tc == prio_top &&
+-                  enetc_get_cbs_enable(&si->hw, prio_next)) {
++                  enetc_get_cbs_enable(hw, prio_next)) {
+                       dev_err(&ndev->dev,
+                               "Disable TC%d before disable TC%d\n",
+                               prio_next, tc);
+                       return -EINVAL;
+               }
+-              enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), 0);
+-              enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), 0);
++              enetc_port_wr(hw, ENETC_PTCCBSR1(tc), 0);
++              enetc_port_wr(hw, ENETC_PTCCBSR0(tc), 0);
+               return 0;
+       }
+@@ -235,13 +229,13 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+        * higher than this TC have been enabled.
+        */
+       if (tc == prio_next) {
+-              if (!enetc_get_cbs_enable(&si->hw, prio_top)) {
++              if (!enetc_get_cbs_enable(hw, prio_top)) {
+                       dev_err(&ndev->dev,
+                               "Enable TC%d first before enable TC%d\n",
+                               prio_top, prio_next);
+                       return -EINVAL;
+               }
+-              bw_sum += enetc_get_cbs_bw(&si->hw, prio_top);
++              bw_sum += enetc_get_cbs_bw(hw, prio_top);
+       }
+       if (bw_sum + bw >= 100) {
+@@ -250,7 +244,7 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+               return -EINVAL;
+       }
+-      enetc_port_rd(&si->hw, ENETC_PTCMSDUR(tc));
++      enetc_port_rd(hw, ENETC_PTCMSDUR(tc));
+       /* For top prio TC, the max_interfrence_size is maxSizedFrame.
+        *
+@@ -270,8 +264,8 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+               u32 m0, ma, r0, ra;
+               m0 = port_frame_max_size * 8;
+-              ma = enetc_port_rd(&si->hw, ENETC_PTCMSDUR(prio_top)) * 8;
+-              ra = enetc_get_cbs_bw(&si->hw, prio_top) *
++              ma = enetc_port_rd(hw, ENETC_PTCMSDUR(prio_top)) * 8;
++              ra = enetc_get_cbs_bw(hw, prio_top) *
+                       port_transmit_rate * 10000ULL;
+               r0 = port_transmit_rate * 1000000ULL;
+               max_interference_size = m0 + ma +
+@@ -291,10 +285,10 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+       hi_credit_reg = (u32)div_u64((ENETC_CLK * 100ULL) * hi_credit_bit,
+                                    port_transmit_rate * 1000000ULL);
+-      enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), hi_credit_reg);
++      enetc_port_wr(hw, ENETC_PTCCBSR1(tc), hi_credit_reg);
+       /* Set bw register and enable this traffic class */
+-      enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), bw | ENETC_CBSE);
++      enetc_port_wr(hw, ENETC_PTCCBSR0(tc), bw | ENETC_CBSE);
+       return 0;
+ }
+@@ -304,6 +298,7 @@ int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data)
+       struct enetc_ndev_priv *priv = netdev_priv(ndev);
+       struct tc_etf_qopt_offload *qopt = type_data;
+       u8 tc_nums = netdev_get_num_tc(ndev);
++      struct enetc_hw *hw = &priv->si->hw;
+       int tc;
+       if (!tc_nums)
+@@ -319,12 +314,11 @@ int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data)
+               return -EBUSY;
+       /* TSD and Qbv are mutually exclusive in hardware */
+-      if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE)
++      if (enetc_rd(hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE)
+               return -EBUSY;
+       priv->tx_ring[tc]->tsd_enable = qopt->enable;
+-      enetc_port_wr(&priv->si->hw, ENETC_PTCTSDR(tc),
+-                    qopt->enable ? ENETC_TSDE : 0);
++      enetc_port_wr(hw, ENETC_PTCTSDR(tc), qopt->enable ? ENETC_TSDE : 0);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-enetc-manage-enetc_f_qbv-in-priv-active_offloads.patch b/queue-5.15/net-enetc-manage-enetc_f_qbv-in-priv-active_offloads.patch
new file mode 100644 (file)
index 0000000..4fd71fd
--- /dev/null
@@ -0,0 +1,88 @@
+From 80cdf44a5054e76c955e12725d2877615737d753 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 May 2022 19:36:14 +0300
+Subject: net: enetc: manage ENETC_F_QBV in priv->active_offloads only when
+ enabled
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 32bf8e1f6fb9f6dc334b2b98dffc2e5dcd51e513 ]
+
+Future work in this driver would like to look at priv->active_offloads &
+ENETC_F_QBV to determine whether a tc-taprio qdisc offload was
+installed, but this does not produce the intended effect.
+
+All the other flags in priv->active_offloads are managed dynamically,
+except ENETC_F_QBV which is set statically based on the probed SI capability.
+
+This change makes priv->active_offloads & ENETC_F_QBV really track the
+presence of a tc-taprio schedule on the port.
+
+Some existing users, like the enetc_sched_speed_set() call from
+phylink_mac_link_up(), are best kept using the old logic: the tc-taprio
+offload does not re-trigger another link mode resolve, so the scheduler
+needs to be functional from the get go, as long as Qbv is supported at
+all on the port. So to preserve functionality there, look at the static
+station interface capability from pf->si->hw_features instead.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Claudiu Manoil <claudiu.manoil@nxp.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 290b5fe096e7 ("net: enetc: preserve TX ring priority across reconfiguration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc_pf.c  | 6 ++----
+ drivers/net/ethernet/freescale/enetc/enetc_qos.c | 6 ++++++
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+index 3615357cc60f..5efb079ef25f 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+@@ -800,9 +800,6 @@ static void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
+       ndev->priv_flags |= IFF_UNICAST_FLT;
+-      if (si->hw_features & ENETC_SI_F_QBV)
+-              priv->active_offloads |= ENETC_F_QBV;
+-
+       if (si->hw_features & ENETC_SI_F_PSFP && !enetc_psfp_enable(priv)) {
+               priv->active_offloads |= ENETC_F_QCI;
+               ndev->features |= NETIF_F_HW_TC;
+@@ -1053,7 +1050,8 @@ static void enetc_pl_mac_link_up(struct phylink_config *config,
+       int idx;
+       priv = netdev_priv(pf->si->ndev);
+-      if (priv->active_offloads & ENETC_F_QBV)
++
++      if (pf->si->hw_features & ENETC_SI_F_QBV)
+               enetc_sched_speed_set(priv, speed);
+       if (!phylink_autoneg_inband(mode) &&
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+index 6b236e0fd806..9fd9abad34f8 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+@@ -71,6 +71,9 @@ static int enetc_setup_taprio(struct net_device *ndev,
+               enetc_wr(&priv->si->hw,
+                        ENETC_QBV_PTGCR_OFFSET,
+                        tge & (~ENETC_QBV_TGE));
++
++              priv->active_offloads &= ~ENETC_F_QBV;
++
+               return 0;
+       }
+@@ -136,6 +139,9 @@ static int enetc_setup_taprio(struct net_device *ndev,
+       dma_free_coherent(&priv->si->pdev->dev, data_size + ENETC_QOS_ALIGN,
+                         tmp, dma);
++      if (!err)
++              priv->active_offloads |= ENETC_F_QBV;
++
+       return err;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-enetc-preserve-tx-ring-priority-across-reconfigu.patch b/queue-5.15/net-enetc-preserve-tx-ring-priority-across-reconfigu.patch
new file mode 100644 (file)
index 0000000..c51e008
--- /dev/null
@@ -0,0 +1,126 @@
+From 028cad909de915af4d79c430cd335c10dae6e617 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 15:09:36 +0200
+Subject: net: enetc: preserve TX ring priority across reconfiguration
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 290b5fe096e7dd0aad730d1af4f7f2d9fea43e11 ]
+
+In the blamed commit, a rudimentary reallocation procedure for RX buffer
+descriptors was implemented, for the situation when their format changes
+between normal (no PTP) and extended (PTP).
+
+enetc_hwtstamp_set() calls enetc_close() and enetc_open() in a sequence,
+and this sequence loses information which was previously configured in
+the TX BDR Mode Register, specifically via the enetc_set_bdr_prio() call.
+The TX ring priority is configured by tc-mqprio and tc-taprio, and
+affects important things for TSN such as the TX time of packets. The
+issue manifests itself most visibly by the fact that isochron --txtime
+reports premature packet transmissions when PTP is first enabled on an
+enetc interface.
+
+Save the TX ring priority in a new field in struct enetc_bdr (occupies a
+2 byte hole on arm64) in order to make this survive a ring reconfiguration.
+
+Fixes: 434cebabd3a2 ("enetc: Add dynamic allocation of extended Rx BD rings")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Alexander Lobakin <alexandr.lobakin@intel.com>
+Link: https://lore.kernel.org/r/20221122130936.1704151-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc.c  |  8 ++++---
+ drivers/net/ethernet/freescale/enetc/enetc.h  |  1 +
+ .../net/ethernet/freescale/enetc/enetc_qos.c  | 21 ++++++++++++-------
+ 3 files changed, 19 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index 0ced688bf9ba..222a250fba84 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -1768,7 +1768,7 @@ static void enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
+       /* enable Tx ints by setting pkt thr to 1 */
+       enetc_txbdr_wr(hw, idx, ENETC_TBICR0, ENETC_TBICR0_ICEN | 0x1);
+-      tbmr = ENETC_TBMR_EN;
++      tbmr = ENETC_TBMR_EN | ENETC_TBMR_SET_PRIO(tx_ring->prio);
+       if (tx_ring->ndev->features & NETIF_F_HW_VLAN_CTAG_TX)
+               tbmr |= ENETC_TBMR_VIH;
+@@ -2171,7 +2171,8 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+               /* Reset all ring priorities to 0 */
+               for (i = 0; i < priv->num_tx_rings; i++) {
+                       tx_ring = priv->tx_ring[i];
+-                      enetc_set_bdr_prio(hw, tx_ring->index, 0);
++                      tx_ring->prio = 0;
++                      enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
+               }
+               return 0;
+@@ -2190,7 +2191,8 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+        */
+       for (i = 0; i < num_tc; i++) {
+               tx_ring = priv->tx_ring[i];
+-              enetc_set_bdr_prio(hw, tx_ring->index, i);
++              tx_ring->prio = i;
++              enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
+       }
+       /* Reset the number of netdev queues based on the TC count */
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
+index 7ec807bd9828..a3b936375c56 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.h
++++ b/drivers/net/ethernet/freescale/enetc/enetc.h
+@@ -91,6 +91,7 @@ struct enetc_bdr {
+               void __iomem *rcir;
+       };
+       u16 index;
++      u16 prio;
+       int bd_count; /* # of BDs */
+       int next_to_use;
+       int next_to_clean;
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+index 6baf2619a51e..ba51fb381f0c 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+@@ -145,6 +145,7 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
+       struct tc_taprio_qopt_offload *taprio = type_data;
+       struct enetc_ndev_priv *priv = netdev_priv(ndev);
+       struct enetc_hw *hw = &priv->si->hw;
++      struct enetc_bdr *tx_ring;
+       int err;
+       int i;
+@@ -153,16 +154,20 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
+               if (priv->tx_ring[i]->tsd_enable)
+                       return -EBUSY;
+-      for (i = 0; i < priv->num_tx_rings; i++)
+-              enetc_set_bdr_prio(hw, priv->tx_ring[i]->index,
+-                                 taprio->enable ? i : 0);
++      for (i = 0; i < priv->num_tx_rings; i++) {
++              tx_ring = priv->tx_ring[i];
++              tx_ring->prio = taprio->enable ? i : 0;
++              enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
++      }
+       err = enetc_setup_taprio(ndev, taprio);
+-
+-      if (err)
+-              for (i = 0; i < priv->num_tx_rings; i++)
+-                      enetc_set_bdr_prio(hw, priv->tx_ring[i]->index,
+-                                         taprio->enable ? 0 : i);
++      if (err) {
++              for (i = 0; i < priv->num_tx_rings; i++) {
++                      tx_ring = priv->tx_ring[i];
++                      tx_ring->prio = taprio->enable ? 0 : i;
++                      enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
++              }
++      }
+       return err;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-ethernet-mtk_eth_soc-fix-error-handling-in-mtk_o.patch b/queue-5.15/net-ethernet-mtk_eth_soc-fix-error-handling-in-mtk_o.patch
new file mode 100644 (file)
index 0000000..14bc393
--- /dev/null
@@ -0,0 +1,42 @@
+From d148404025b5fe07d603ca5fed1bc27db5e92bf6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 19:13:56 +0800
+Subject: net: ethernet: mtk_eth_soc: fix error handling in mtk_open()
+
+From: Liu Jian <liujian56@huawei.com>
+
+[ Upstream commit f70074140524c59a0935947b06dd6cb6e1ea642d ]
+
+If mtk_start_dma() fails, invoke phylink_disconnect_phy() to perform
+cleanup. phylink_disconnect_phy() contains the put_device action. If
+phylink_disconnect_phy is not performed, the Kref of netdev will leak.
+
+Fixes: b8fc9f30821e ("net: ethernet: mediatek: Add basic PHYLINK support")
+Signed-off-by: Liu Jian <liujian56@huawei.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://lore.kernel.org/r/20221117111356.161547-1-liujian56@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 8601ef26c260..cc6a5b2f24e3 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -2327,8 +2327,10 @@ static int mtk_open(struct net_device *dev)
+               int err;
+               err = mtk_start_dma(eth);
+-              if (err)
++              if (err) {
++                      phylink_disconnect_phy(mac->phylink);
+                       return err;
++              }
+               if (eth->soc->offload_version && mtk_ppe_start(&eth->ppe) == 0)
+                       gdm_config = MTK_GDMA_TO_PPE;
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-liquidio-simplify-if-expression.patch b/queue-5.15/net-liquidio-simplify-if-expression.patch
new file mode 100644 (file)
index 0000000..49dc3f6
--- /dev/null
@@ -0,0 +1,50 @@
+From f715565f30c8842b1c0c8036cf5f2a338eb5b3bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 19:34:39 +0200
+Subject: net: liquidio: simplify if expression
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit 733d4bbf9514890eb53ebe75827bf1fb4fd25ebe ]
+
+Fix the warning reported by kbuild:
+
+cocci warnings: (new ones prefixed by >>)
+>> drivers/net/ethernet/cavium/liquidio/lio_main.c:1797:54-56: WARNING !A || A && B is equivalent to !A || B
+   drivers/net/ethernet/cavium/liquidio/lio_main.c:1827:54-56: WARNING !A || A && B is equivalent to !A || B
+
+Fixes: 8979f428a4af ("net: liquidio: release resources when liquidio driver open failed")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Reviewed-by: Saeed Mahameed <saeed@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cavium/liquidio/lio_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
+index 7bd97d98afeb..ae68821dd56d 100644
+--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
++++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
+@@ -1798,7 +1798,7 @@ static int liquidio_open(struct net_device *netdev)
+       ifstate_set(lio, LIO_IFSTATE_RUNNING);
+-      if (!OCTEON_CN23XX_PF(oct) || (OCTEON_CN23XX_PF(oct) && !oct->msix_on)) {
++      if (!OCTEON_CN23XX_PF(oct) || !oct->msix_on) {
+               ret = setup_tx_poll_fn(netdev);
+               if (ret)
+                       goto err_poll;
+@@ -1828,7 +1828,7 @@ static int liquidio_open(struct net_device *netdev)
+       return 0;
+ err_rx_ctrl:
+-      if (!OCTEON_CN23XX_PF(oct) || (OCTEON_CN23XX_PF(oct) && !oct->msix_on))
++      if (!OCTEON_CN23XX_PF(oct) || !oct->msix_on)
+               cleanup_tx_poll_fn(netdev);
+ err_poll:
+       if (lio->ptp_clock) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-mlx4-check-retval-of-mlx4_bitmap_init.patch b/queue-5.15/net-mlx4-check-retval-of-mlx4_bitmap_init.patch
new file mode 100644 (file)
index 0000000..24b787c
--- /dev/null
@@ -0,0 +1,43 @@
+From a843add3d4547abe367b4017104d0fe31945a054 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 18:28:06 +0300
+Subject: net/mlx4: Check retval of mlx4_bitmap_init
+
+From: Peter Kosyh <pkosyh@yandex.ru>
+
+[ Upstream commit 594c61ffc77de0a197934aa0f1df9285c68801c6 ]
+
+If mlx4_bitmap_init fails, mlx4_bitmap_alloc_range will dereference
+the NULL pointer (bitmap->table).
+
+Make sure, that mlx4_bitmap_alloc_range called in no error case.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: d57febe1a478 ("net/mlx4: Add A0 hybrid steering")
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Peter Kosyh <pkosyh@yandex.ru>
+Link: https://lore.kernel.org/r/20221117152806.278072-1-pkosyh@yandex.ru
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx4/qp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
+index b149e601f673..48cfaa7eaf50 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
++++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
+@@ -697,7 +697,8 @@ static int mlx4_create_zones(struct mlx4_dev *dev,
+                       err = mlx4_bitmap_init(*bitmap + k, 1,
+                                              MLX4_QP_TABLE_RAW_ETH_SIZE - 1, 0,
+                                              0);
+-                      mlx4_bitmap_alloc_range(*bitmap + k, 1, 1, 0);
++                      if (!err)
++                              mlx4_bitmap_alloc_range(*bitmap + k, 1, 1, 0);
+               }
+               if (err)
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-mlx5-do-not-query-pci-info-while-pci-disabled.patch b/queue-5.15/net-mlx5-do-not-query-pci-info-while-pci-disabled.patch
new file mode 100644 (file)
index 0000000..c96a6f1
--- /dev/null
@@ -0,0 +1,60 @@
+From 98d3db4477a1d4102eed01734dd30fee19bbc8ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Jul 2022 09:49:07 +0300
+Subject: net/mlx5: Do not query pci info while pci disabled
+
+From: Roy Novich <royno@nvidia.com>
+
+[ Upstream commit 394164f9d5a3020a7fd719d228386d48d544ec67 ]
+
+The driver should not interact with PCI while PCI is disabled. Trying to
+do so may result in being unable to get vital signs during PCI reset,
+driver gets timed out and fails to recover.
+
+Fixes: fad1783a6d66 ("net/mlx5: Print more info on pci error handlers")
+Signed-off-by: Roy Novich <royno@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Aya Levin <ayal@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/main.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index d092261e96c3..19c11d33f4b6 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1608,7 +1608,8 @@ static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev,
+       res = state == pci_channel_io_perm_failure ?
+               PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
+-      mlx5_pci_trace(dev, "Exit, result = %d, %s\n",  res, result2str(res));
++      mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Exit, result = %d, %s\n",
++                     __func__, dev->state, dev->pci_status, res, result2str(res));
+       return res;
+ }
+@@ -1647,7 +1648,8 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
+       struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
+       int err;
+-      mlx5_pci_trace(dev, "Enter\n");
++      mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Enter\n",
++                     __func__, dev->state, dev->pci_status);
+       err = mlx5_pci_enable_device(dev);
+       if (err) {
+@@ -1669,7 +1671,8 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
+       res = PCI_ERS_RESULT_RECOVERED;
+ out:
+-      mlx5_pci_trace(dev, "Exit, err = %d, result = %d, %s\n", err, res, result2str(res));
++      mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Exit, err = %d, result = %d, %s\n",
++                     __func__, dev->state, dev->pci_status, err, res, result2str(res));
+       return res;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-mlx5-fix-fw-tracer-timestamp-calculation.patch b/queue-5.15/net-mlx5-fix-fw-tracer-timestamp-calculation.patch
new file mode 100644 (file)
index 0000000..4de25ca
--- /dev/null
@@ -0,0 +1,38 @@
+From 617956ecb5acc7d6f3872c9b794294542be7e4ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Oct 2022 12:25:59 +0300
+Subject: net/mlx5: Fix FW tracer timestamp calculation
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 61db3d7b99a367416e489ccf764cc5f9b00d62a1 ]
+
+Fix a bug in calculation of FW tracer timestamp. Decreasing one in the
+calculation should effect only bits 52_7 and not effect bits 6_0 of the
+timestamp, otherwise bits 6_0 are always set in this calculation.
+
+Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Feras Daoud <ferasda@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index ea46152816f9..326e0b170e36 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -638,7 +638,7 @@ static void mlx5_tracer_handle_timestamp_trace(struct mlx5_fw_tracer *tracer,
+                       trace_timestamp = (timestamp_event.timestamp & MASK_52_7) |
+                                         (str_frmt->timestamp & MASK_6_0);
+               else
+-                      trace_timestamp = ((timestamp_event.timestamp & MASK_52_7) - 1) |
++                      trace_timestamp = ((timestamp_event.timestamp - 1) & MASK_52_7) |
+                                         (str_frmt->timestamp & MASK_6_0);
+               mlx5_tracer_print_trace(str_frmt, dev, trace_timestamp);
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-mlx5-fix-handling-of-entry-refcount-when-command.patch b/queue-5.15/net-mlx5-fix-handling-of-entry-refcount-when-command.patch
new file mode 100644 (file)
index 0000000..647eff8
--- /dev/null
@@ -0,0 +1,62 @@
+From 38d746cf7a968809d386119b373a05cf9f6aafbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 09:07:20 +0200
+Subject: net/mlx5: Fix handling of entry refcount when command is not issued
+ to FW
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit aaf2e65cac7f2e1ae729c2fbc849091df9699f96 ]
+
+In case command interface is down, or the command is not allowed, driver
+did not increment the entry refcount, but might have decrement as part
+of forced completion handling.
+
+Fix that by always increment and decrement the refcount to make it
+symmetric for all flows.
+
+Fixes: 50b2412b7e78 ("net/mlx5: Avoid possible free of command entry while timeout comp handler")
+Signed-off-by: Eran Ben Elisha <eranbe@nvidia.com>
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reported-by: Jack Wang <jinpu.wang@ionos.com>
+Tested-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index 98ca5d1ed45d..85190f2f4d50 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -971,6 +971,7 @@ static void cmd_work_handler(struct work_struct *work)
+               cmd_ent_get(ent);
+       set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state);
++      cmd_ent_get(ent); /* for the _real_ FW event on completion */
+       /* Skip sending command to fw if internal error */
+       if (mlx5_cmd_is_down(dev) || !opcode_allowed(&dev->cmd, ent->op)) {
+               u8 status = 0;
+@@ -984,7 +985,6 @@ static void cmd_work_handler(struct work_struct *work)
+               return;
+       }
+-      cmd_ent_get(ent); /* for the _real_ FW event on completion */
+       /* ring doorbell after the descriptor is valid */
+       mlx5_core_dbg(dev, "writing 0x%x to command doorbell\n", 1 << ent->idx);
+       wmb();
+@@ -1598,8 +1598,8 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
+                               cmd_ent_put(ent); /* timeout work was canceled */
+                       if (!forced || /* Real FW completion */
+-                          pci_channel_offline(dev->pdev) || /* FW is inaccessible */
+-                          dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
++                           mlx5_cmd_is_down(dev) || /* No real FW completion is expected */
++                           !opcode_allowed(cmd, ent->op))
+                               cmd_ent_put(ent);
+                       ent->ts2 = ktime_get_ns();
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-mvpp2-fix-possible-invalid-pointer-dereference.patch b/queue-5.15/net-mvpp2-fix-possible-invalid-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..2fa24d6
--- /dev/null
@@ -0,0 +1,51 @@
+From b109a97a3aecb18d87f7bf5ea6bc78f0ede24d28 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 16:40:32 +0800
+Subject: net: mvpp2: fix possible invalid pointer dereference
+
+From: Hui Tang <tanghui20@huawei.com>
+
+[ Upstream commit cbe867685386af1f0a2648f5279f6e4c74bfd17f ]
+
+It will cause invalid pointer dereference to priv->cm3_base behind,
+if PTR_ERR(priv->cm3_base) in mvpp2_get_sram().
+
+Fixes: e54ad1e01c00 ("net: mvpp2: add CM3 SRAM memory map")
+Signed-off-by: Hui Tang <tanghui20@huawei.com>
+Link: https://lore.kernel.org/r/20221117084032.101144-1-tanghui20@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index ae586f8895fc..524913c28f3b 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -7356,6 +7356,7 @@ static int mvpp2_get_sram(struct platform_device *pdev,
+                         struct mvpp2 *priv)
+ {
+       struct resource *res;
++      void __iomem *base;
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+       if (!res) {
+@@ -7366,9 +7367,12 @@ static int mvpp2_get_sram(struct platform_device *pdev,
+               return 0;
+       }
+-      priv->cm3_base = devm_ioremap_resource(&pdev->dev, res);
++      base = devm_ioremap_resource(&pdev->dev, res);
++      if (IS_ERR(base))
++              return PTR_ERR(base);
+-      return PTR_ERR_OR_ZERO(priv->cm3_base);
++      priv->cm3_base = base;
++      return 0;
+ }
+ static int mvpp2_probe(struct platform_device *pdev)
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-pch_gbe-fix-pci-device-refcount-leak-while-modul.patch b/queue-5.15/net-pch_gbe-fix-pci-device-refcount-leak-while-modul.patch
new file mode 100644 (file)
index 0000000..466bada
--- /dev/null
@@ -0,0 +1,60 @@
+From 469c377b03120a0f8239969eba0550ab2e2df2ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 21:51:48 +0800
+Subject: net: pch_gbe: fix pci device refcount leak while module exiting
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 5619537284f1017e9f6c7500b02b859b3830a06d ]
+
+As comment of pci_get_domain_bus_and_slot() says, it returns
+a pci device with refcount increment, when finish using it,
+the caller must decrement the reference count by calling
+pci_dev_put().
+
+In pch_gbe_probe(), pci_get_domain_bus_and_slot() is called,
+so in error path in probe() and remove() function, pci_dev_put()
+should be called to avoid refcount leak. Compile tested only.
+
+Fixes: 1a0bdadb4e36 ("net/pch_gbe: supports eg20t ptp clock")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221117135148.301014-1-yangyingliang@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+index 5a42ef6ca762..d555b4cc6049 100644
+--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
++++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+@@ -2465,6 +2465,7 @@ static void pch_gbe_remove(struct pci_dev *pdev)
+       unregister_netdev(netdev);
+       pch_gbe_phy_hw_reset(&adapter->hw);
++      pci_dev_put(adapter->ptp_pdev);
+       free_netdev(netdev);
+ }
+@@ -2540,7 +2541,7 @@ static int pch_gbe_probe(struct pci_dev *pdev,
+       /* setup the private structure */
+       ret = pch_gbe_sw_init(adapter);
+       if (ret)
+-              goto err_free_netdev;
++              goto err_put_dev;
+       /* Initialize PHY */
+       ret = pch_gbe_init_phy(adapter);
+@@ -2598,6 +2599,8 @@ static int pch_gbe_probe(struct pci_dev *pdev,
+ err_free_adapter:
+       pch_gbe_phy_hw_reset(&adapter->hw);
++err_put_dev:
++      pci_dev_put(adapter->ptp_pdev);
+ err_free_netdev:
+       free_netdev(netdev);
+       return ret;
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-pch_gbe-fix-potential-memleak-in-pch_gbe_tx_queu.patch b/queue-5.15/net-pch_gbe-fix-potential-memleak-in-pch_gbe_tx_queu.patch
new file mode 100644 (file)
index 0000000..af86608
--- /dev/null
@@ -0,0 +1,38 @@
+From 9f3e07dcce2dec69e0b3887c90026e6e6291d07b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 14:55:27 +0800
+Subject: net: pch_gbe: fix potential memleak in pch_gbe_tx_queue()
+
+From: Wang Hai <wanghai38@huawei.com>
+
+[ Upstream commit 2360f9b8c4e81d242d4cbf99d630a2fffa681fab ]
+
+In pch_gbe_xmit_frame(), NETDEV_TX_OK will be returned whether
+pch_gbe_tx_queue() sends data successfully or not, so pch_gbe_tx_queue()
+needs to free skb before returning. But pch_gbe_tx_queue() returns without
+freeing skb in case of dma_map_single() fails. Add dev_kfree_skb_any()
+to fix it.
+
+Fixes: 77555ee72282 ("net: Add Gigabit Ethernet driver of Topcliff PCH")
+Signed-off-by: Wang Hai <wanghai38@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+index ec3e558f890e..5a42ef6ca762 100644
+--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
++++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+@@ -1148,6 +1148,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
+               buffer_info->dma = 0;
+               buffer_info->time_stamp = 0;
+               tx_ring->next_to_use = ring_num;
++              dev_kfree_skb_any(skb);
+               return;
+       }
+       buffer_info->mapped = true;
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-qla3xxx-fix-potential-memleak-in-ql3xxx_send.patch b/queue-5.15/net-qla3xxx-fix-potential-memleak-in-ql3xxx_send.patch
new file mode 100644 (file)
index 0000000..c8637d1
--- /dev/null
@@ -0,0 +1,36 @@
+From dd456ac301e2cff4e1defc529f0bf3a25824a528 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 16:50:38 +0800
+Subject: net/qla3xxx: fix potential memleak in ql3xxx_send()
+
+From: Zhang Changzhong <zhangchangzhong@huawei.com>
+
+[ Upstream commit 62a7311fb96c61d281da9852dbee4712fc8c3277 ]
+
+The ql3xxx_send() returns NETDEV_TX_OK without freeing skb in error
+handling case, add dev_kfree_skb_any() to fix it.
+
+Fixes: bd36b0ac5d06 ("qla3xxx: Add support for Qlogic 4032 chip.")
+Signed-off-by: Zhang Changzhong <zhangchangzhong@huawei.com>
+Link: https://lore.kernel.org/r/1668675039-21138-1-git-send-email-zhangchangzhong@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qlogic/qla3xxx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
+index 40d14d80f6f1..29837e533cee 100644
+--- a/drivers/net/ethernet/qlogic/qla3xxx.c
++++ b/drivers/net/ethernet/qlogic/qla3xxx.c
+@@ -2469,6 +2469,7 @@ static netdev_tx_t ql3xxx_send(struct sk_buff *skb,
+                                            skb_shinfo(skb)->nr_frags);
+       if (tx_cb->seg_count == -1) {
+               netdev_err(ndev, "%s: invalid segment count!\n", __func__);
++              dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-sched-allow-act_ct-to-be-built-without-nf_nat.patch b/queue-5.15/net-sched-allow-act_ct-to-be-built-without-nf_nat.patch
new file mode 100644 (file)
index 0000000..71b58c0
--- /dev/null
@@ -0,0 +1,40 @@
+From d77d2d9f438e47554d1f9d0d3bac30fc268c5bc1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 16:33:03 -0500
+Subject: net: sched: allow act_ct to be built without NF_NAT
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 8427fd100c7b7793650e212a81e42f1cf124613d ]
+
+In commit f11fe1dae1c4 ("net/sched: Make NET_ACT_CT depends on NF_NAT"),
+it fixed the build failure when NF_NAT is m and NET_ACT_CT is y by
+adding depends on NF_NAT for NET_ACT_CT. However, it would also cause
+NET_ACT_CT cannot be built without NF_NAT, which is not expected. This
+patch fixes it by changing to use "(!NF_NAT || NF_NAT)" as the depend.
+
+Fixes: f11fe1dae1c4 ("net/sched: Make NET_ACT_CT depends on NF_NAT")
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Link: https://lore.kernel.org/r/b6386f28d1ba34721795fb776a91cbdabb203447.1668807183.git.lucien.xin@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sched/Kconfig b/net/sched/Kconfig
+index 1e8ab4749c6c..4662a6ce8a7e 100644
+--- a/net/sched/Kconfig
++++ b/net/sched/Kconfig
+@@ -976,7 +976,7 @@ config NET_ACT_TUNNEL_KEY
+ config NET_ACT_CT
+       tristate "connection tracking tc action"
+-      depends on NET_CLS_ACT && NF_CONNTRACK && NF_NAT && NF_FLOW_TABLE
++      depends on NET_CLS_ACT && NF_CONNTRACK && (!NF_NAT || NF_NAT) && NF_FLOW_TABLE
+       help
+         Say Y here to allow sending the packets to conntrack module.
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-sparx5-fix-error-handling-in-sparx5_port_open.patch b/queue-5.15/net-sparx5-fix-error-handling-in-sparx5_port_open.patch
new file mode 100644 (file)
index 0000000..ccc5a09
--- /dev/null
@@ -0,0 +1,63 @@
+From 807bd6d4e9320881f3fb4e347e6955b8e46fdd9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 20:59:18 +0800
+Subject: net: sparx5: fix error handling in sparx5_port_open()
+
+From: Liu Jian <liujian56@huawei.com>
+
+[ Upstream commit 4305fe232b8aa59af3761adc9fe6b6aa40913960 ]
+
+If phylink_of_phy_connect() fails, the port should be disabled.
+If sparx5_serdes_set()/phy_power_on() fails, the port should be
+disabled and the phylink should be stopped and disconnected.
+
+Fixes: 946e7fd5053a ("net: sparx5: add port module support")
+Fixes: f3cad2611a77 ("net: sparx5: add hostmode with phylink support")
+Signed-off-by: Liu Jian <liujian56@huawei.com>
+Tested-by: Bjarni Jonasson <bjarni.jonasson@microchip.com>
+Reviewed-by: Steen Hegelund <steen.hegelund@microchip.com>
+Link: https://lore.kernel.org/r/20221117125918.203997-1-liujian56@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/microchip/sparx5/sparx5_netdev.c  | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
+index cb68eaaac881..5c7b21ce64ed 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
+@@ -83,7 +83,7 @@ static int sparx5_port_open(struct net_device *ndev)
+       err = phylink_of_phy_connect(port->phylink, port->of_node, 0);
+       if (err) {
+               netdev_err(ndev, "Could not attach to PHY\n");
+-              return err;
++              goto err_connect;
+       }
+       phylink_start(port->phylink);
+@@ -95,10 +95,20 @@ static int sparx5_port_open(struct net_device *ndev)
+                       err = sparx5_serdes_set(port->sparx5, port, &port->conf);
+               else
+                       err = phy_power_on(port->serdes);
+-              if (err)
++              if (err) {
+                       netdev_err(ndev, "%s failed\n", __func__);
++                      goto out_power;
++              }
+       }
++      return 0;
++
++out_power:
++      phylink_stop(port->phylink);
++      phylink_disconnect_phy(port->phylink);
++err_connect:
++      sparx5_port_enable(port, false);
++
+       return err;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-thunderx-fix-the-acpi-memory-leak.patch b/queue-5.15/net-thunderx-fix-the-acpi-memory-leak.patch
new file mode 100644 (file)
index 0000000..14bd247
--- /dev/null
@@ -0,0 +1,41 @@
+From 6923fb8e03fc899ba9d067cff3c6ce6d3f1ba15d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 16:22:36 +0800
+Subject: net: thunderx: Fix the ACPI memory leak
+
+From: Yu Liao <liaoyu15@huawei.com>
+
+[ Upstream commit 661e5ebbafd26d9d2e3c749f5cf591e55c7364f5 ]
+
+The ACPI buffer memory (string.pointer) should be freed as the buffer is
+not used after returning from bgx_acpi_match_id(), free it to prevent
+memory leak.
+
+Fixes: 46b903a01c05 ("net, thunder, bgx: Add support to get MAC address from ACPI.")
+Signed-off-by: Yu Liao <liaoyu15@huawei.com>
+Link: https://lore.kernel.org/r/20221123082237.1220521-1-liaoyu15@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+index c36fed9c3d73..daaffae1a89f 100644
+--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
++++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+@@ -1435,8 +1435,10 @@ static acpi_status bgx_acpi_match_id(acpi_handle handle, u32 lvl,
+               return AE_OK;
+       }
+-      if (strncmp(string.pointer, bgx_sel, 4))
++      if (strncmp(string.pointer, bgx_sel, 4)) {
++              kfree(string.pointer);
+               return AE_OK;
++      }
+       acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+                           bgx_acpi_register_phy, NULL, bgx, NULL);
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-wwan-iosm-use-acpi_free-but-not-kfree-in-ipc_pci.patch b/queue-5.15/net-wwan-iosm-use-acpi_free-but-not-kfree-in-ipc_pci.patch
new file mode 100644 (file)
index 0000000..89cbe8e
--- /dev/null
@@ -0,0 +1,39 @@
+From 67a3468b4259b8ebf1fc51e9cc41497fdd599977 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 14:24:47 +0800
+Subject: net: wwan: iosm: use ACPI_FREE() but not kfree() in
+ ipc_pcie_read_bios_cfg()
+
+From: Wang ShaoBo <bobo.shaobowang@huawei.com>
+
+[ Upstream commit e541dd7763fc34aec2f93f652a396cc2e7b92d8d ]
+
+acpi_evaluate_dsm() should be coupled with ACPI_FREE() to free the ACPI
+memory, because we need to track the allocation of acpi_object when
+ACPI_DBG_TRACK_ALLOCATIONS enabled, so use ACPI_FREE() instead of kfree().
+
+Fixes: d38a648d2d6c ("net: wwan: iosm: fix memory leak in ipc_pcie_read_bios_cfg")
+Signed-off-by: Wang ShaoBo <bobo.shaobowang@huawei.com>
+Link: https://lore.kernel.org/r/20221118062447.2324881-1-bobo.shaobowang@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wwan/iosm/iosm_ipc_pcie.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_pcie.c b/drivers/net/wwan/iosm/iosm_ipc_pcie.c
+index 01df23835be0..8b4222b137d1 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_pcie.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_pcie.c
+@@ -249,7 +249,7 @@ static enum ipc_pcie_sleep_state ipc_pcie_read_bios_cfg(struct device *dev)
+       if (object->integer.value == 3)
+               sleep_state = IPC_PCIE_D3L2;
+-      kfree(object);
++      ACPI_FREE(object);
+ default_ret:
+       return sleep_state;
+-- 
+2.35.1
+
diff --git a/queue-5.15/netfilter-conntrack-fix-data-races-around-ct-mark.patch b/queue-5.15/netfilter-conntrack-fix-data-races-around-ct-mark.patch
new file mode 100644 (file)
index 0000000..aa4aa5b
--- /dev/null
@@ -0,0 +1,369 @@
+From d654971326aa400343bc5bf1b2897b9460a02efa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 12:39:07 -0700
+Subject: netfilter: conntrack: Fix data-races around ct mark
+
+From: Daniel Xu <dxu@dxuuu.xyz>
+
+[ Upstream commit 52d1aa8b8249ff477aaa38b6f74a8ced780d079c ]
+
+nf_conn:mark can be read from and written to in parallel. Use
+READ_ONCE()/WRITE_ONCE() for reads and writes to prevent unwanted
+compiler optimizations.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/flow_dissector.c               |  2 +-
+ net/ipv4/netfilter/ipt_CLUSTERIP.c      |  4 ++--
+ net/netfilter/nf_conntrack_core.c       |  2 +-
+ net/netfilter/nf_conntrack_netlink.c    | 24 ++++++++++++++----------
+ net/netfilter/nf_conntrack_standalone.c |  2 +-
+ net/netfilter/nft_ct.c                  |  6 +++---
+ net/netfilter/xt_connmark.c             | 18 ++++++++++--------
+ net/openvswitch/conntrack.c             |  8 ++++----
+ net/sched/act_connmark.c                |  4 ++--
+ net/sched/act_ct.c                      |  8 ++++----
+ net/sched/act_ctinfo.c                  |  6 +++---
+ 11 files changed, 45 insertions(+), 39 deletions(-)
+
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
+index 1c34e2266578..1d230f041386 100644
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -270,7 +270,7 @@ skb_flow_dissect_ct(const struct sk_buff *skb,
+       key->ct_zone = ct->zone.id;
+ #endif
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+-      key->ct_mark = ct->mark;
++      key->ct_mark = READ_ONCE(ct->mark);
+ #endif
+       cl = nf_ct_labels_find(ct);
+diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
+index b518f20c9a24..34737b1d6526 100644
+--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
++++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
+@@ -435,7 +435,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
+       switch (ctinfo) {
+       case IP_CT_NEW:
+-              ct->mark = hash;
++              WRITE_ONCE(ct->mark, hash);
+               break;
+       case IP_CT_RELATED:
+       case IP_CT_RELATED_REPLY:
+@@ -452,7 +452,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ #ifdef DEBUG
+       nf_ct_dump_tuple_ip(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+ #endif
+-      pr_debug("hash=%u ct_hash=%u ", hash, ct->mark);
++      pr_debug("hash=%u ct_hash=%u ", hash, READ_ONCE(ct->mark));
+       if (!clusterip_responsible(cipinfo->config, hash)) {
+               pr_debug("not responsible\n");
+               return NF_DROP;
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 9da5ee6c50cd..43ea8cfd374b 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -1735,7 +1735,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
+                       }
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-                      ct->mark = exp->master->mark;
++                      ct->mark = READ_ONCE(exp->master->mark);
+ #endif
+ #ifdef CONFIG_NF_CONNTRACK_SECMARK
+                       ct->secmark = exp->master->secmark;
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index ef0a78aa9ba9..1727a4c4764f 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -322,9 +322,9 @@ ctnetlink_dump_timestamp(struct sk_buff *skb, const struct nf_conn *ct)
+ }
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
++static int ctnetlink_dump_mark(struct sk_buff *skb, u32 mark)
+ {
+-      if (nla_put_be32(skb, CTA_MARK, htonl(ct->mark)))
++      if (nla_put_be32(skb, CTA_MARK, htonl(mark)))
+               goto nla_put_failure;
+       return 0;
+@@ -537,7 +537,7 @@ static int ctnetlink_dump_extinfo(struct sk_buff *skb,
+ static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
+ {
+       if (ctnetlink_dump_status(skb, ct) < 0 ||
+-          ctnetlink_dump_mark(skb, ct) < 0 ||
++          ctnetlink_dump_mark(skb, READ_ONCE(ct->mark)) < 0 ||
+           ctnetlink_dump_secctx(skb, ct) < 0 ||
+           ctnetlink_dump_id(skb, ct) < 0 ||
+           ctnetlink_dump_use(skb, ct) < 0 ||
+@@ -716,6 +716,7 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+       struct sk_buff *skb;
+       unsigned int type;
+       unsigned int flags = 0, group;
++      u32 mark;
+       int err;
+       if (events & (1 << IPCT_DESTROY)) {
+@@ -820,8 +821,9 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+       }
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-      if ((events & (1 << IPCT_MARK) || ct->mark)
+-          && ctnetlink_dump_mark(skb, ct) < 0)
++      mark = READ_ONCE(ct->mark);
++      if ((events & (1 << IPCT_MARK) || mark) &&
++          ctnetlink_dump_mark(skb, mark) < 0)
+               goto nla_put_failure;
+ #endif
+       nlmsg_end(skb, nlh);
+@@ -1148,7 +1150,7 @@ static int ctnetlink_filter_match(struct nf_conn *ct, void *data)
+       }
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-      if ((ct->mark & filter->mark.mask) != filter->mark.val)
++      if ((READ_ONCE(ct->mark) & filter->mark.mask) != filter->mark.val)
+               goto ignore_entry;
+ #endif
+       status = (u32)READ_ONCE(ct->status);
+@@ -2016,9 +2018,9 @@ static void ctnetlink_change_mark(struct nf_conn *ct,
+               mask = ~ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
+       mark = ntohl(nla_get_be32(cda[CTA_MARK]));
+-      newmark = (ct->mark & mask) ^ mark;
+-      if (newmark != ct->mark)
+-              ct->mark = newmark;
++      newmark = (READ_ONCE(ct->mark) & mask) ^ mark;
++      if (newmark != READ_ONCE(ct->mark))
++              WRITE_ONCE(ct->mark, newmark);
+ }
+ #endif
+@@ -2690,6 +2692,7 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ {
+       const struct nf_conntrack_zone *zone;
+       struct nlattr *nest_parms;
++      u32 mark;
+       zone = nf_ct_zone(ct);
+@@ -2751,7 +2754,8 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+               goto nla_put_failure;
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-      if (ct->mark && ctnetlink_dump_mark(skb, ct) < 0)
++      mark = READ_ONCE(ct->mark);
++      if (mark && ctnetlink_dump_mark(skb, mark) < 0)
+               goto nla_put_failure;
+ #endif
+       if (ctnetlink_dump_labels(skb, ct) < 0)
+diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
+index 55aa55b252b2..4d85368203e0 100644
+--- a/net/netfilter/nf_conntrack_standalone.c
++++ b/net/netfilter/nf_conntrack_standalone.c
+@@ -363,7 +363,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
+               goto release;
+ #if defined(CONFIG_NF_CONNTRACK_MARK)
+-      seq_printf(s, "mark=%u ", ct->mark);
++      seq_printf(s, "mark=%u ", READ_ONCE(ct->mark));
+ #endif
+       ct_show_secctx(s, ct);
+diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
+index 9c7472af9e4a..bd468e955a21 100644
+--- a/net/netfilter/nft_ct.c
++++ b/net/netfilter/nft_ct.c
+@@ -97,7 +97,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
+               return;
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+       case NFT_CT_MARK:
+-              *dest = ct->mark;
++              *dest = READ_ONCE(ct->mark);
+               return;
+ #endif
+ #ifdef CONFIG_NF_CONNTRACK_SECMARK
+@@ -296,8 +296,8 @@ static void nft_ct_set_eval(const struct nft_expr *expr,
+       switch (priv->key) {
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+       case NFT_CT_MARK:
+-              if (ct->mark != value) {
+-                      ct->mark = value;
++              if (READ_ONCE(ct->mark) != value) {
++                      WRITE_ONCE(ct->mark, value);
+                       nf_conntrack_event_cache(IPCT_MARK, ct);
+               }
+               break;
+diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
+index e5ebc0810675..ad3c033db64e 100644
+--- a/net/netfilter/xt_connmark.c
++++ b/net/netfilter/xt_connmark.c
+@@ -30,6 +30,7 @@ connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
+       u_int32_t new_targetmark;
+       struct nf_conn *ct;
+       u_int32_t newmark;
++      u_int32_t oldmark;
+       ct = nf_ct_get(skb, &ctinfo);
+       if (ct == NULL)
+@@ -37,14 +38,15 @@ connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
+       switch (info->mode) {
+       case XT_CONNMARK_SET:
+-              newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
++              oldmark = READ_ONCE(ct->mark);
++              newmark = (oldmark & ~info->ctmask) ^ info->ctmark;
+               if (info->shift_dir == D_SHIFT_RIGHT)
+                       newmark >>= info->shift_bits;
+               else
+                       newmark <<= info->shift_bits;
+-              if (ct->mark != newmark) {
+-                      ct->mark = newmark;
++              if (READ_ONCE(ct->mark) != newmark) {
++                      WRITE_ONCE(ct->mark, newmark);
+                       nf_conntrack_event_cache(IPCT_MARK, ct);
+               }
+               break;
+@@ -55,15 +57,15 @@ connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
+               else
+                       new_targetmark <<= info->shift_bits;
+-              newmark = (ct->mark & ~info->ctmask) ^
++              newmark = (READ_ONCE(ct->mark) & ~info->ctmask) ^
+                         new_targetmark;
+-              if (ct->mark != newmark) {
+-                      ct->mark = newmark;
++              if (READ_ONCE(ct->mark) != newmark) {
++                      WRITE_ONCE(ct->mark, newmark);
+                       nf_conntrack_event_cache(IPCT_MARK, ct);
+               }
+               break;
+       case XT_CONNMARK_RESTORE:
+-              new_targetmark = (ct->mark & info->ctmask);
++              new_targetmark = (READ_ONCE(ct->mark) & info->ctmask);
+               if (info->shift_dir == D_SHIFT_RIGHT)
+                       new_targetmark >>= info->shift_bits;
+               else
+@@ -126,7 +128,7 @@ connmark_mt(const struct sk_buff *skb, struct xt_action_param *par)
+       if (ct == NULL)
+               return false;
+-      return ((ct->mark & info->mask) == info->mark) ^ info->invert;
++      return ((READ_ONCE(ct->mark) & info->mask) == info->mark) ^ info->invert;
+ }
+ static int connmark_mt_check(const struct xt_mtchk_param *par)
+diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
+index dc86f03309c1..7106ce231a2d 100644
+--- a/net/openvswitch/conntrack.c
++++ b/net/openvswitch/conntrack.c
+@@ -150,7 +150,7 @@ static u8 ovs_ct_get_state(enum ip_conntrack_info ctinfo)
+ static u32 ovs_ct_get_mark(const struct nf_conn *ct)
+ {
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+-      return ct ? ct->mark : 0;
++      return ct ? READ_ONCE(ct->mark) : 0;
+ #else
+       return 0;
+ #endif
+@@ -338,9 +338,9 @@ static int ovs_ct_set_mark(struct nf_conn *ct, struct sw_flow_key *key,
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+       u32 new_mark;
+-      new_mark = ct_mark | (ct->mark & ~(mask));
+-      if (ct->mark != new_mark) {
+-              ct->mark = new_mark;
++      new_mark = ct_mark | (READ_ONCE(ct->mark) & ~(mask));
++      if (READ_ONCE(ct->mark) != new_mark) {
++              WRITE_ONCE(ct->mark, new_mark);
+               if (nf_ct_is_confirmed(ct))
+                       nf_conntrack_event_cache(IPCT_MARK, ct);
+               key->ct.mark = new_mark;
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 94e78ac7a748..032ef927d0eb 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -62,7 +62,7 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+       c = nf_ct_get(skb, &ctinfo);
+       if (c) {
+-              skb->mark = c->mark;
++              skb->mark = READ_ONCE(c->mark);
+               /* using overlimits stats to count how many packets marked */
+               ca->tcf_qstats.overlimits++;
+               goto out;
+@@ -82,7 +82,7 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+       c = nf_ct_tuplehash_to_ctrack(thash);
+       /* using overlimits stats to count how many packets marked */
+       ca->tcf_qstats.overlimits++;
+-      skb->mark = c->mark;
++      skb->mark = READ_ONCE(c->mark);
+       nf_ct_put(c);
+ out:
+diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
+index d85fdefe5730..81a2d6cbfb44 100644
+--- a/net/sched/act_ct.c
++++ b/net/sched/act_ct.c
+@@ -177,7 +177,7 @@ static void tcf_ct_flow_table_add_action_meta(struct nf_conn *ct,
+       entry = tcf_ct_flow_table_flow_action_get_next(action);
+       entry->id = FLOW_ACTION_CT_METADATA;
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+-      entry->ct_metadata.mark = ct->mark;
++      entry->ct_metadata.mark = READ_ONCE(ct->mark);
+ #endif
+       ctinfo = dir == IP_CT_DIR_ORIGINAL ? IP_CT_ESTABLISHED :
+                                            IP_CT_ESTABLISHED_REPLY;
+@@ -856,9 +856,9 @@ static void tcf_ct_act_set_mark(struct nf_conn *ct, u32 mark, u32 mask)
+       if (!mask)
+               return;
+-      new_mark = mark | (ct->mark & ~(mask));
+-      if (ct->mark != new_mark) {
+-              ct->mark = new_mark;
++      new_mark = mark | (READ_ONCE(ct->mark) & ~(mask));
++      if (READ_ONCE(ct->mark) != new_mark) {
++              WRITE_ONCE(ct->mark, new_mark);
+               if (nf_ct_is_confirmed(ct))
+                       nf_conntrack_event_cache(IPCT_MARK, ct);
+       }
+diff --git a/net/sched/act_ctinfo.c b/net/sched/act_ctinfo.c
+index 549374a2d008..2d75fe1223ac 100644
+--- a/net/sched/act_ctinfo.c
++++ b/net/sched/act_ctinfo.c
+@@ -33,7 +33,7 @@ static void tcf_ctinfo_dscp_set(struct nf_conn *ct, struct tcf_ctinfo *ca,
+ {
+       u8 dscp, newdscp;
+-      newdscp = (((ct->mark & cp->dscpmask) >> cp->dscpmaskshift) << 2) &
++      newdscp = (((READ_ONCE(ct->mark) & cp->dscpmask) >> cp->dscpmaskshift) << 2) &
+                    ~INET_ECN_MASK;
+       switch (proto) {
+@@ -73,7 +73,7 @@ static void tcf_ctinfo_cpmark_set(struct nf_conn *ct, struct tcf_ctinfo *ca,
+                                 struct sk_buff *skb)
+ {
+       ca->stats_cpmark_set++;
+-      skb->mark = ct->mark & cp->cpmarkmask;
++      skb->mark = READ_ONCE(ct->mark) & cp->cpmarkmask;
+ }
+ static int tcf_ctinfo_act(struct sk_buff *skb, const struct tc_action *a,
+@@ -131,7 +131,7 @@ static int tcf_ctinfo_act(struct sk_buff *skb, const struct tc_action *a,
+       }
+       if (cp->mode & CTINFO_MODE_DSCP)
+-              if (!cp->dscpstatemask || (ct->mark & cp->dscpstatemask))
++              if (!cp->dscpstatemask || (READ_ONCE(ct->mark) & cp->dscpstatemask))
+                       tcf_ctinfo_dscp_set(ct, ca, cp, skb, wlen, proto);
+       if (cp->mode & CTINFO_MODE_CPMARK)
+-- 
+2.35.1
+
diff --git a/queue-5.15/netfilter-flowtable_offload-add-missing-locking.patch b/queue-5.15/netfilter-flowtable_offload-add-missing-locking.patch
new file mode 100644 (file)
index 0000000..3a358ae
--- /dev/null
@@ -0,0 +1,55 @@
+From d5174f7eb29e644df140ed132a5aef57cd0de5ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 19:26:15 +0100
+Subject: netfilter: flowtable_offload: add missing locking
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit bcd9e3c1656d0f7dd9743598c65c3ae24efb38d0 ]
+
+nf_flow_table_block_setup and the driver TC_SETUP_FT call can modify the flow
+block cb list while they are being traversed elsewhere, causing a crash.
+Add a write lock around the calls to protect readers
+
+Fixes: c29f74e0df7a ("netfilter: nf_flow_table: hardware offload support")
+Reported-by: Chad Monroe <chad.monroe@smartrg.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_flow_table_offload.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
+index c4559fae8acd..66c9a6c2b9cf 100644
+--- a/net/netfilter/nf_flow_table_offload.c
++++ b/net/netfilter/nf_flow_table_offload.c
+@@ -1074,6 +1074,7 @@ static int nf_flow_table_block_setup(struct nf_flowtable *flowtable,
+       struct flow_block_cb *block_cb, *next;
+       int err = 0;
++      down_write(&flowtable->flow_block_lock);
+       switch (cmd) {
+       case FLOW_BLOCK_BIND:
+               list_splice(&bo->cb_list, &flowtable->flow_block.cb_list);
+@@ -1088,6 +1089,7 @@ static int nf_flow_table_block_setup(struct nf_flowtable *flowtable,
+               WARN_ON_ONCE(1);
+               err = -EOPNOTSUPP;
+       }
++      up_write(&flowtable->flow_block_lock);
+       return err;
+ }
+@@ -1144,7 +1146,9 @@ static int nf_flow_table_offload_cmd(struct flow_block_offload *bo,
+       nf_flow_table_block_offload_init(bo, dev_net(dev), cmd, flowtable,
+                                        extack);
++      down_write(&flowtable->flow_block_lock);
+       err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_FT, bo);
++      up_write(&flowtable->flow_block_lock);
+       if (err < 0)
+               return err;
+-- 
+2.35.1
+
diff --git a/queue-5.15/netfilter-ipset-regression-in-ip_set_hash_ip.c.patch b/queue-5.15/netfilter-ipset-regression-in-ip_set_hash_ip.c.patch
new file mode 100644 (file)
index 0000000..8154b89
--- /dev/null
@@ -0,0 +1,66 @@
+From 13b4749663f26566077703e2ce56ae0e9e9ddc32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Sep 2022 14:26:50 -0400
+Subject: netfilter: ipset: regression in ip_set_hash_ip.c
+
+From: Vishwanath Pai <vpai@akamai.com>
+
+[ Upstream commit c7aa1a76d4a0a3c401025b60c401412bbb60f8c6 ]
+
+This patch introduced a regression: commit 48596a8ddc46 ("netfilter:
+ipset: Fix adding an IPv4 range containing more than 2^31 addresses")
+
+The variable e.ip is passed to adtfn() function which finally adds the
+ip address to the set. The patch above refactored the for loop and moved
+e.ip = htonl(ip) to the end of the for loop.
+
+What this means is that if the value of "ip" changes between the first
+assignement of e.ip and the forloop, then e.ip is pointing to a
+different ip address than "ip".
+
+Test case:
+$ ipset create jdtest_tmp hash:ip family inet hashsize 2048 maxelem 100000
+$ ipset add jdtest_tmp 10.0.1.1/31
+ipset v6.21.1: Element cannot be added to the set: it's already added
+
+The value of ip gets updated inside the  "else if (tb[IPSET_ATTR_CIDR])"
+block but e.ip is still pointing to the old value.
+
+Fixes: 48596a8ddc46 ("netfilter: ipset: Fix adding an IPv4 range containing more than 2^31 addresses")
+Reviewed-by: Joshua Hunt <johunt@akamai.com>
+Signed-off-by: Vishwanath Pai <vpai@akamai.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipset/ip_set_hash_ip.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
+index dd30c03d5a23..75d556d71652 100644
+--- a/net/netfilter/ipset/ip_set_hash_ip.c
++++ b/net/netfilter/ipset/ip_set_hash_ip.c
+@@ -151,18 +151,16 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
+       if (((u64)ip_to - ip + 1) >> (32 - h->netmask) > IPSET_MAX_RANGE)
+               return -ERANGE;
+-      if (retried) {
++      if (retried)
+               ip = ntohl(h->next.ip);
+-              e.ip = htonl(ip);
+-      }
+       for (; ip <= ip_to;) {
++              e.ip = htonl(ip);
+               ret = adtfn(set, &e, &ext, &ext, flags);
+               if (ret && !ip_set_eexist(ret, flags))
+                       return ret;
+               ip += hosts;
+-              e.ip = htonl(ip);
+-              if (e.ip == 0)
++              if (ip == 0)
+                       return 0;
+               ret = 0;
+-- 
+2.35.1
+
diff --git a/queue-5.15/netfilter-ipset-restore-allowing-64-clashing-element.patch b/queue-5.15/netfilter-ipset-restore-allowing-64-clashing-element.patch
new file mode 100644 (file)
index 0000000..2a149de
--- /dev/null
@@ -0,0 +1,39 @@
+From c21cad70826ab7b049804662017e97dc7ad26c8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 20:18:58 +0100
+Subject: netfilter: ipset: restore allowing 64 clashing elements in
+ hash:net,iface
+
+From: Jozsef Kadlecsik <kadlec@netfilter.org>
+
+[ Upstream commit 6a66ce44a51bdfc47721f0c591137df2d4b21247 ]
+
+The commit 510841da1fcc ("netfilter: ipset: enforce documented limit to
+prevent allocating huge memory") was too strict and prevented to add up to
+64 clashing elements to a hash:net,iface type of set. This patch fixes the
+issue and now the type behaves as documented.
+
+Fixes: 510841da1fcc ("netfilter: ipset: enforce documented limit to prevent allocating huge memory")
+Signed-off-by: Jozsef Kadlecsik <kadlec@netfilter.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipset/ip_set_hash_gen.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
+index 3adc291d9ce1..7499192af586 100644
+--- a/net/netfilter/ipset/ip_set_hash_gen.h
++++ b/net/netfilter/ipset/ip_set_hash_gen.h
+@@ -916,7 +916,7 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
+ #ifdef IP_SET_HASH_WITH_MULTI
+               if (h->bucketsize >= AHASH_MAX_TUNED)
+                       goto set_full;
+-              else if (h->bucketsize < multi)
++              else if (h->bucketsize <= multi)
+                       h->bucketsize += AHASH_INIT_SIZE;
+ #endif
+               if (n->size >= AHASH_MAX(h)) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/netfilter-nf_tables-do-not-set-up-extensions-for-end.patch b/queue-5.15/netfilter-nf_tables-do-not-set-up-extensions-for-end.patch
new file mode 100644 (file)
index 0000000..9b537c2
--- /dev/null
@@ -0,0 +1,54 @@
+From 9fb84728dc1f8e883de6fc77e13edcebea42bc9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 11:31:54 +0100
+Subject: netfilter: nf_tables: do not set up extensions for end interval
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 33c7aba0b4ffd6d7cdab862a034eb582a5120a38 ]
+
+Elements with an end interval flag set on do not store extensions. The
+global set definition is currently setting on the timeout and stateful
+expression for end interval elements.
+
+This leads to skipping end interval elements from the set->ops->walk()
+path as the expired check bogusly reports true.
+
+Moreover, do not set up stateful expressions for elements with end
+interval flag set on since this is never used.
+
+Fixes: 65038428b2c6 ("netfilter: nf_tables: allow to specify stateful expression in set definition")
+Fixes: 8d8540c4f5e0 ("netfilter: nft_set_rbtree: add timeout support")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 227f03db7ee1..3fac57d66dda 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -5813,7 +5813,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+                                           &timeout);
+               if (err)
+                       return err;
+-      } else if (set->flags & NFT_SET_TIMEOUT) {
++      } else if (set->flags & NFT_SET_TIMEOUT &&
++                 !(flags & NFT_SET_ELEM_INTERVAL_END)) {
+               timeout = set->timeout;
+       }
+@@ -5879,7 +5880,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+                       err = -EOPNOTSUPP;
+                       goto err_set_elem_expr;
+               }
+-      } else if (set->num_exprs > 0) {
++      } else if (set->num_exprs > 0 &&
++                 !(flags & NFT_SET_ELEM_INTERVAL_END)) {
+               err = nft_set_elem_expr_clone(ctx, set, expr_array);
+               if (err < 0)
+                       goto err_set_elem_expr_clone;
+-- 
+2.35.1
+
diff --git a/queue-5.15/nfc-nci-fix-memory-leak-in-nci_rx_data_packet.patch b/queue-5.15/nfc-nci-fix-memory-leak-in-nci_rx_data_packet.patch
new file mode 100644 (file)
index 0000000..5b90934
--- /dev/null
@@ -0,0 +1,61 @@
+From 0ac2d62a6a9a07799d75533959f60974f08b64db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 16:24:19 +0800
+Subject: NFC: nci: fix memory leak in nci_rx_data_packet()
+
+From: Liu Shixin <liushixin2@huawei.com>
+
+[ Upstream commit 53270fb0fd77fe786d8c07a0793981d797836b93 ]
+
+Syzbot reported a memory leak about skb:
+
+unreferenced object 0xffff88810e144e00 (size 240):
+  comm "syz-executor284", pid 3701, jiffies 4294952403 (age 12.620s)
+  hex dump (first 32 bytes):
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+  backtrace:
+    [<ffffffff83ab79a9>] __alloc_skb+0x1f9/0x270 net/core/skbuff.c:497
+    [<ffffffff82a5cf64>] alloc_skb include/linux/skbuff.h:1267 [inline]
+    [<ffffffff82a5cf64>] virtual_ncidev_write+0x24/0xe0 drivers/nfc/virtual_ncidev.c:116
+    [<ffffffff815f6503>] do_loop_readv_writev fs/read_write.c:759 [inline]
+    [<ffffffff815f6503>] do_loop_readv_writev fs/read_write.c:743 [inline]
+    [<ffffffff815f6503>] do_iter_write+0x253/0x300 fs/read_write.c:863
+    [<ffffffff815f66ed>] vfs_writev+0xdd/0x240 fs/read_write.c:934
+    [<ffffffff815f68f6>] do_writev+0xa6/0x1c0 fs/read_write.c:977
+    [<ffffffff848802d5>] do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+    [<ffffffff848802d5>] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
+    [<ffffffff84a00087>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+In nci_rx_data_packet(), if we don't get a valid conn_info, we will return
+directly but forget to release the skb.
+
+Reported-by: syzbot+cdb9a427d1bc08815104@syzkaller.appspotmail.com
+Fixes: 4aeee6871e8c ("NFC: nci: Add dynamic logical connections support")
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+Link: https://lore.kernel.org/r/20221118082419.239475-1-liushixin2@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/nci/data.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c
+index aa5e712adf07..3d36ea5701f0 100644
+--- a/net/nfc/nci/data.c
++++ b/net/nfc/nci/data.c
+@@ -279,8 +279,10 @@ void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb)
+                nci_plen(skb->data));
+       conn_info = nci_get_conn_info_by_conn_id(ndev, nci_conn_id(skb->data));
+-      if (!conn_info)
++      if (!conn_info) {
++              kfree_skb(skb);
+               return;
++      }
+       /* strip the nci data header */
+       skb_pull(skb, NCI_DATA_HDR_SIZE);
+-- 
+2.35.1
+
diff --git a/queue-5.15/nfc-nci-fix-race-with-opening-and-closing.patch b/queue-5.15/nfc-nci-fix-race-with-opening-and-closing.patch
new file mode 100644 (file)
index 0000000..7c17943
--- /dev/null
@@ -0,0 +1,42 @@
+From c30287092d935aaf1f04e2bae9ea5173be0b323b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 21:02:49 +0800
+Subject: nfc/nci: fix race with opening and closing
+
+From: Lin Ma <linma@zju.edu.cn>
+
+[ Upstream commit 0ad6bded175e829c2ca261529c9dce39a32a042d ]
+
+Previously we leverage NCI_UNREG and the lock inside nci_close_device to
+prevent the race condition between opening a device and closing a
+device. However, it still has problem because a failed opening command
+will erase the NCI_UNREG flag and allow another opening command to
+bypass the status checking.
+
+This fix corrects that by making sure the NCI_UNREG is held.
+
+Reported-by: syzbot+43475bf3cfbd6e41f5b7@syzkaller.appspotmail.com
+Fixes: 48b71a9e66c2 ("NFC: add NCI_UNREG flag to eliminate the race")
+Signed-off-by: Lin Ma <linma@zju.edu.cn>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/nci/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
+index 189c9f428a3c..7b6cf9a44aea 100644
+--- a/net/nfc/nci/core.c
++++ b/net/nfc/nci/core.c
+@@ -542,7 +542,7 @@ static int nci_open_device(struct nci_dev *ndev)
+               skb_queue_purge(&ndev->tx_q);
+               ndev->ops->close(ndev);
+-              ndev->flags = 0;
++              ndev->flags &= BIT(NCI_UNREG);
+       }
+ done:
+-- 
+2.35.1
+
diff --git a/queue-5.15/nfc-st-nci-fix-incorrect-sizing-calculations-in-evt_.patch b/queue-5.15/nfc-st-nci-fix-incorrect-sizing-calculations-in-evt_.patch
new file mode 100644 (file)
index 0000000..06fbae9
--- /dev/null
@@ -0,0 +1,115 @@
+From 53307be2bb90185e4a573fb1a45becd78c9d32ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 18:42:46 -0600
+Subject: nfc: st-nci: fix incorrect sizing calculations in EVT_TRANSACTION
+
+From: Martin Faltesek <mfaltesek@google.com>
+
+[ Upstream commit 0254f31a7df3bb3b90c2d9dd2d4052f7b95eb287 ]
+
+The transaction buffer is allocated by using the size of the packet buf,
+and subtracting two which seems intended to remove the two tags which are
+not present in the target structure. This calculation leads to under
+counting memory because of differences between the packet contents and the
+target structure. The aid_len field is a u8 in the packet, but a u32 in
+the structure, resulting in at least 3 bytes always being under counted.
+Further, the aid data is a variable length field in the packet, but fixed
+in the structure, so if this field is less than the max, the difference is
+added to the under counting.
+
+To fix, perform validation checks progressively to safely reach the
+next field, to determine the size of both buffers and verify both tags.
+Once all validation checks pass, allocate the buffer and copy the data.
+This eliminates freeing memory on the error path, as validation checks are
+moved ahead of memory allocation.
+
+Reported-by: Denis Efremov <denis.e.efremov@oracle.com>
+Reviewed-by: Guenter Roeck <groeck@google.com>
+Fixes: 5d1ceb7f5e56 ("NFC: st21nfcb: Add HCI transaction event support")
+Signed-off-by: Martin Faltesek <mfaltesek@google.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/st-nci/se.c | 51 +++++++++++++++++++++++++++++------------
+ 1 file changed, 36 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/nfc/st-nci/se.c b/drivers/nfc/st-nci/se.c
+index a915cad909b4..04a2cea6d6b6 100644
+--- a/drivers/nfc/st-nci/se.c
++++ b/drivers/nfc/st-nci/se.c
+@@ -312,6 +312,8 @@ static int st_nci_hci_connectivity_event_received(struct nci_dev *ndev,
+       int r = 0;
+       struct device *dev = &ndev->nfc_dev->dev;
+       struct nfc_evt_transaction *transaction;
++      u32 aid_len;
++      u8 params_len;
+       pr_debug("connectivity gate event: %x\n", event);
+@@ -325,28 +327,47 @@ static int st_nci_hci_connectivity_event_received(struct nci_dev *ndev,
+                * Description  Tag     Length
+                * AID          81      5 to 16
+                * PARAMETERS   82      0 to 255
++               *
++               * The key differences are aid storage length is variably sized
++               * in the packet, but fixed in nfc_evt_transaction, and that
++               * the aid_len is u8 in the packet, but u32 in the structure,
++               * and the tags in the packet are not included in
++               * nfc_evt_transaction.
++               *
++               * size(b):  1          1       5-16 1             1           0-255
++               * offset:   0          1       2    aid_len + 2   aid_len + 3 aid_len + 4
++               * mem name: aid_tag(M) aid_len aid  params_tag(M) params_len  params
++               * example:  0x81       5-16    X    0x82          0-255       X
+                */
+-              if (skb->len < NFC_MIN_AID_LENGTH + 2 ||
+-                  skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
++              if (skb->len < 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
+                       return -EPROTO;
+-              transaction = devm_kzalloc(dev, skb->len - 2, GFP_KERNEL);
+-              if (!transaction)
+-                      return -ENOMEM;
++              aid_len = skb->data[1];
+-              transaction->aid_len = skb->data[1];
+-              memcpy(transaction->aid, &skb->data[2], transaction->aid_len);
++              if (skb->len < aid_len + 4 ||
++                  aid_len > sizeof(transaction->aid))
++                      return -EPROTO;
+-              /* Check next byte is PARAMETERS tag (82) */
+-              if (skb->data[transaction->aid_len + 2] !=
+-                  NFC_EVT_TRANSACTION_PARAMS_TAG) {
+-                      devm_kfree(dev, transaction);
++              params_len = skb->data[aid_len + 3];
++
++              /* Verify PARAMETERS tag is (82), and final check that there is
++               * enough space in the packet to read everything.
++               */
++              if (skb->data[aid_len + 2] != NFC_EVT_TRANSACTION_PARAMS_TAG ||
++                  skb->len < aid_len + 4 + params_len)
+                       return -EPROTO;
+-              }
+-              transaction->params_len = skb->data[transaction->aid_len + 3];
+-              memcpy(transaction->params, skb->data +
+-                     transaction->aid_len + 4, transaction->params_len);
++              transaction = devm_kzalloc(dev, sizeof(*transaction) +
++                                         params_len, GFP_KERNEL);
++              if (!transaction)
++                      return -ENOMEM;
++
++              transaction->aid_len = aid_len;
++              transaction->params_len = params_len;
++
++              memcpy(transaction->aid, &skb->data[2], aid_len);
++              memcpy(transaction->params, &skb->data[aid_len + 4],
++                     params_len);
+               r = nfc_se_transaction(ndev->nfc_dev, host, transaction);
+               break;
+-- 
+2.35.1
+
diff --git a/queue-5.15/nfc-st-nci-fix-incorrect-validating-logic-in-evt_tra.patch b/queue-5.15/nfc-st-nci-fix-incorrect-validating-logic-in-evt_tra.patch
new file mode 100644 (file)
index 0000000..f93971e
--- /dev/null
@@ -0,0 +1,41 @@
+From 0dd703d5509e7ef52542392ab3a91d8adf5c6fce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 18:42:44 -0600
+Subject: nfc: st-nci: fix incorrect validating logic in EVT_TRANSACTION
+
+From: Martin Faltesek <mfaltesek@google.com>
+
+[ Upstream commit c60c152230828825c06e62a8f1ce956d4b659266 ]
+
+The first validation check for EVT_TRANSACTION has two different checks
+tied together with logical AND. One is a check for minimum packet length,
+and the other is for a valid aid_tag. If either condition is true (fails),
+then an error should be triggered. The fix is to change && to ||.
+
+Reported-by: Denis Efremov <denis.e.efremov@oracle.com>
+Reviewed-by: Guenter Roeck <groeck@google.com>
+Fixes: 5d1ceb7f5e56 ("NFC: st21nfcb: Add HCI transaction event support")
+Signed-off-by: Martin Faltesek <mfaltesek@google.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/st-nci/se.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/st-nci/se.c b/drivers/nfc/st-nci/se.c
+index 5fd89f72969d..522b7a128f4c 100644
+--- a/drivers/nfc/st-nci/se.c
++++ b/drivers/nfc/st-nci/se.c
+@@ -326,7 +326,7 @@ static int st_nci_hci_connectivity_event_received(struct nci_dev *ndev,
+                * AID          81      5 to 16
+                * PARAMETERS   82      0 to 255
+                */
+-              if (skb->len < NFC_MIN_AID_LENGTH + 2 &&
++              if (skb->len < NFC_MIN_AID_LENGTH + 2 ||
+                   skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
+                       return -EPROTO;
+-- 
+2.35.1
+
diff --git a/queue-5.15/nfc-st-nci-fix-memory-leaks-in-evt_transaction.patch b/queue-5.15/nfc-st-nci-fix-memory-leaks-in-evt_transaction.patch
new file mode 100644 (file)
index 0000000..626f0c3
--- /dev/null
@@ -0,0 +1,42 @@
+From 02705914dc27328bcdf4bbaf61d99efa4b081543 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 18:42:45 -0600
+Subject: nfc: st-nci: fix memory leaks in EVT_TRANSACTION
+
+From: Martin Faltesek <mfaltesek@google.com>
+
+[ Upstream commit 440f2ae9c9f06e26f5dcea697a53717fc61a318c ]
+
+Error path does not free previously allocated memory. Add devm_kfree() to
+the failure path.
+
+Reported-by: Denis Efremov <denis.e.efremov@oracle.com>
+Reviewed-by: Guenter Roeck <groeck@google.com>
+Fixes: 5d1ceb7f5e56 ("NFC: st21nfcb: Add HCI transaction event support")
+Signed-off-by: Martin Faltesek <mfaltesek@google.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/st-nci/se.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/st-nci/se.c b/drivers/nfc/st-nci/se.c
+index 522b7a128f4c..a915cad909b4 100644
+--- a/drivers/nfc/st-nci/se.c
++++ b/drivers/nfc/st-nci/se.c
+@@ -339,8 +339,10 @@ static int st_nci_hci_connectivity_event_received(struct nci_dev *ndev,
+               /* Check next byte is PARAMETERS tag (82) */
+               if (skb->data[transaction->aid_len + 2] !=
+-                  NFC_EVT_TRANSACTION_PARAMS_TAG)
++                  NFC_EVT_TRANSACTION_PARAMS_TAG) {
++                      devm_kfree(dev, transaction);
+                       return -EPROTO;
++              }
+               transaction->params_len = skb->data[transaction->aid_len + 3];
+               memcpy(transaction->params, skb->data +
+-- 
+2.35.1
+
diff --git a/queue-5.15/nfp-add-port-from-netdev-validation-for-eeprom-acces.patch b/queue-5.15/nfp-add-port-from-netdev-validation-for-eeprom-acces.patch
new file mode 100644 (file)
index 0000000..543aa16
--- /dev/null
@@ -0,0 +1,45 @@
+From d8d5691b92ccfecf093adabd64d87681078cb554 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 16:37:44 +0100
+Subject: nfp: add port from netdev validation for EEPROM access
+
+From: Jaco Coetzee <jaco.coetzee@corigine.com>
+
+[ Upstream commit 0873016d46f6dfafd1bdf4d9b935b3331b226f7c ]
+
+Setting of the port flag `NFP_PORT_CHANGED`, introduced
+to ensure the correct reading of EEPROM data, causes a
+fatal kernel NULL pointer dereference in cases where
+the target netdev type cannot be determined.
+
+Add validation of port struct pointer before attempting
+to set the `NFP_PORT_CHANGED` flag. Return that operation
+is not supported if the netdev type cannot be determined.
+
+Fixes: 4ae97cae07e1 ("nfp: ethtool: fix the display error of `ethtool -m DEVNAME`")
+Signed-off-by: Jaco Coetzee <jaco.coetzee@corigine.com>
+Reviewed-by: Louis Peens <louis.peens@corigine.com>
+Signed-off-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+index 865865adfefc..d295942968f3 100644
+--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+@@ -1219,6 +1219,9 @@ nfp_port_get_module_info(struct net_device *netdev,
+       u8 data;
+       port = nfp_port_from_netdev(netdev);
++      if (!port)
++              return -EOPNOTSUPP;
++
+       /* update port state to get latest interface */
+       set_bit(NFP_PORT_CHANGED, &port->flags);
+       eth_port = nfp_port_get_eth_port(port);
+-- 
+2.35.1
+
diff --git a/queue-5.15/nfp-fill-splittable-of-devlink_port_attrs-correctly.patch b/queue-5.15/nfp-fill-splittable-of-devlink_port_attrs-correctly.patch
new file mode 100644 (file)
index 0000000..0c66b13
--- /dev/null
@@ -0,0 +1,48 @@
+From 4b6cffa538bd826edb837a3806a945fc5f13eca4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 16:37:43 +0100
+Subject: nfp: fill splittable of devlink_port_attrs correctly
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Diana Wang <na.wang@corigine.com>
+
+[ Upstream commit 4abd9600b9d15d3d92a9ac25cf200422a4c415ee ]
+
+The error is reflected in that it shows wrong splittable status of
+port when executing "devlink port show".
+The reason which leads the error is that the assigned operation of
+splittable is just a simple negation operation of split and it does
+not consider port lanes quantity. A splittable port should have
+several lanes that can be split(lanes quantity > 1).
+If without the judgement, it will show wrong message for some
+firmware, such as 2x25G, 2x10G.
+
+Fixes: a0f49b548652 ("devlink: Add a new devlink port split ability attribute and pass to netlink")
+Signed-off-by: Diana Wang <na.wang@corigine.com>
+Reviewed-by: Louis Peens <louis.peens@corigine.com>
+Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
+Signed-off-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/netronome/nfp/nfp_devlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+index bea978df7713..1647b6b180cc 100644
+--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
++++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+@@ -363,7 +363,7 @@ int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
+               return ret;
+       attrs.split = eth_port.is_split;
+-      attrs.splittable = !attrs.split;
++      attrs.splittable = eth_port.port_lanes > 1 && !attrs.split;
+       attrs.lanes = eth_port.port_lanes;
+       attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+       attrs.phys.port_number = eth_port.label_port;
+-- 
+2.35.1
+
diff --git a/queue-5.15/octeontx2-af-debugsfs-fix-pci-device-refcount-leak.patch b/queue-5.15/octeontx2-af-debugsfs-fix-pci-device-refcount-leak.patch
new file mode 100644 (file)
index 0000000..dccec8b
--- /dev/null
@@ -0,0 +1,52 @@
+From 82db153d019f27b880c7b6ee767f02ac18328072 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 20:46:58 +0800
+Subject: octeontx2-af: debugsfs: fix pci device refcount leak
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit d66608803aa2ffb9e475623343f69996305771ae ]
+
+As comment of pci_get_domain_bus_and_slot() says, it returns
+a pci device with refcount increment, when finish using it,
+the caller must decrement the reference count by calling
+pci_dev_put().
+
+So before returning from rvu_dbg_rvu_pf_cgx_map_display() or
+cgx_print_dmac_flt(), pci_dev_put() is called to avoid refcount
+leak.
+
+Fixes: dbc52debf95f ("octeontx2-af: Debugfs support for DMAC filters")
+Fixes: e2fb37303865 ("octeontx2-af: Display CGX, NIX and PF map in debugfs.")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221117124658.162409-1-yangyingliang@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+index f001579569a2..66d34699f160 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+@@ -441,6 +441,8 @@ static int rvu_dbg_rvu_pf_cgx_map_display(struct seq_file *filp, void *unused)
+               sprintf(lmac, "LMAC%d", lmac_id);
+               seq_printf(filp, "%s\t0x%x\t\tNIX%d\t\t%s\t%s\n",
+                          dev_name(&pdev->dev), pcifunc, blkid, cgx, lmac);
++
++              pci_dev_put(pdev);
+       }
+       return 0;
+ }
+@@ -2127,6 +2129,7 @@ static int cgx_print_dmac_flt(struct seq_file *s, int lmac_id)
+               }
+       }
++      pci_dev_put(pdev);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/octeontx2-af-fix-reference-count-issue-in-rvu_sdp_in.patch b/queue-5.15/octeontx2-af-fix-reference-count-issue-in-rvu_sdp_in.patch
new file mode 100644 (file)
index 0000000..ba58e58
--- /dev/null
@@ -0,0 +1,55 @@
+From 3d169094414408eee1c53546df1043467339b0ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 14:59:19 +0800
+Subject: octeontx2-af: Fix reference count issue in rvu_sdp_init()
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit ad17c2a3f11b0f6b122e7842d8f7d9a5fcc7ac63 ]
+
+pci_get_device() will decrease the reference count for the *from*
+parameter. So we don't need to call put_device() to decrease the
+reference. Let's remove the put_device() in the loop and only decrease
+the reference count of the returned 'pdev' for the last loop because it
+will not be passed to pci_get_device() as input parameter. We don't need
+to check if 'pdev' is NULL because it is already checked inside
+pci_dev_put(). Also add pci_dev_put() for the error path.
+
+Fixes: fe1939bb2340 ("octeontx2-af: Add SDP interface support")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Reviewed-by: Saeed Mahameed <saeed@kernel.org>
+Link: https://lore.kernel.org/r/20221123065919.31499-1-wangxiongfeng2@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
+index b04fb226f708..ae50d56258ec 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
+@@ -62,15 +62,18 @@ int rvu_sdp_init(struct rvu *rvu)
+               pfvf->sdp_info = devm_kzalloc(rvu->dev,
+                                             sizeof(struct sdp_node_info),
+                                             GFP_KERNEL);
+-              if (!pfvf->sdp_info)
++              if (!pfvf->sdp_info) {
++                      pci_dev_put(pdev);
+                       return -ENOMEM;
++              }
+               dev_info(rvu->dev, "SDP PF number:%d\n", sdp_pf_num[i]);
+-              put_device(&pdev->dev);
+               i++;
+       }
++      pci_dev_put(pdev);
++
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/octeontx2-pf-add-check-for-devm_kcalloc.patch b/queue-5.15/octeontx2-pf-add-check-for-devm_kcalloc.patch
new file mode 100644 (file)
index 0000000..e184039
--- /dev/null
@@ -0,0 +1,39 @@
+From 7bb183f667ecd9c0ab2e5ba85d53f0f2f2efec87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Nov 2022 13:54:49 +0800
+Subject: octeontx2-pf: Add check for devm_kcalloc
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit cd07eadd5147ffdae11b6fd28b77a3872f2a2484 ]
+
+As the devm_kcalloc may return NULL pointer,
+it should be better to add check for the return
+value, as same as the others.
+
+Fixes: e8e095b3b370 ("octeontx2-af: cn10k: Bandwidth profiles config support")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Link: https://lore.kernel.org/r/20221122055449.31247-1-jiasheng@iscas.ac.cn
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+index 603361c94786..09892703cfd4 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+@@ -4832,6 +4832,8 @@ static int nix_setup_ipolicers(struct rvu *rvu,
+               ipolicer->ref_count = devm_kcalloc(rvu->dev,
+                                                  ipolicer->band_prof.max,
+                                                  sizeof(u16), GFP_KERNEL);
++              if (!ipolicer->ref_count)
++                      return -ENOMEM;
+       }
+       /* Set policer timeunit to 2us ie  (19 + 1) * 100 nsec = 2us */
+-- 
+2.35.1
+
diff --git a/queue-5.15/regulator-core-fix-kobject-release-warning-and-memor.patch b/queue-5.15/regulator-core-fix-kobject-release-warning-and-memor.patch
new file mode 100644 (file)
index 0000000..6bb0cde
--- /dev/null
@@ -0,0 +1,75 @@
+From c5e5cd76b2f3244b38e02cb2a682f30202b31a39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 15:43:39 +0800
+Subject: regulator: core: fix kobject release warning and memory leak in
+ regulator_register()
+
+From: Zeng Heng <zengheng4@huawei.com>
+
+[ Upstream commit 5f4b204b6b8153923d5be8002c5f7082985d153f ]
+
+Here is a warning report about lack of registered release()
+from kobject lib:
+
+Device '(null)' does not have a release() function, it is broken and must be fixed.
+WARNING: CPU: 0 PID: 48430 at drivers/base/core.c:2332 device_release+0x104/0x120
+Call Trace:
+ kobject_put+0xdc/0x180
+ put_device+0x1b/0x30
+ regulator_register+0x651/0x1170
+ devm_regulator_register+0x4f/0xb0
+
+When regulator_register() returns fail and directly goto `clean` symbol,
+rdev->dev has not registered release() function yet (which is registered
+by regulator_class in the following), so rdev needs to be freed manually.
+If rdev->dev.of_node is not NULL, which means the of_node has gotten by
+regulator_of_get_init_data(), it needs to call of_node_put() to avoid
+refcount leak.
+
+Otherwise, only calling put_device() would lead memory leak of rdev
+in further:
+
+unreferenced object 0xffff88810d0b1000 (size 2048):
+  comm "107-i2c-rtq6752", pid 48430, jiffies 4342258431 (age 1341.780s)
+  backtrace:
+    kmalloc_trace+0x22/0x110
+    regulator_register+0x184/0x1170
+    devm_regulator_register+0x4f/0xb0
+
+When regulator_register() returns fail and goto `wash` symbol,
+rdev->dev has registered release() function, so directly call
+put_device() to cleanup everything.
+
+Fixes: d3c731564e09 ("regulator: plug of_node leak in regulator_register()'s error path")
+Signed-off-by: Zeng Heng <zengheng4@huawei.com>
+Link: https://lore.kernel.org/r/20221116074339.1024240-1-zengheng4@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/core.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index aa4d78b02483..fd61c5c54a07 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -5549,11 +5549,15 @@ regulator_register(const struct regulator_desc *regulator_desc,
+       mutex_lock(&regulator_list_mutex);
+       regulator_ena_gpio_free(rdev);
+       mutex_unlock(&regulator_list_mutex);
++      put_device(&rdev->dev);
++      rdev = NULL;
+ clean:
+       if (dangling_of_gpiod)
+               gpiod_put(config->ena_gpiod);
++      if (rdev && rdev->dev.of_node)
++              of_node_put(rdev->dev.of_node);
++      kfree(rdev);
+       kfree(config);
+-      put_device(&rdev->dev);
+ rinse:
+       if (dangling_cfg_gpiod)
+               gpiod_put(cfg->ena_gpiod);
+-- 
+2.35.1
+
diff --git a/queue-5.15/regulator-core-fix-uaf-in-destroy_regulator.patch b/queue-5.15/regulator-core-fix-uaf-in-destroy_regulator.patch
new file mode 100644 (file)
index 0000000..8fed65a
--- /dev/null
@@ -0,0 +1,132 @@
+From edf7bb7cec279dbd5c9fb35fd9fd93a5c5304d9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 11:37:06 +0800
+Subject: regulator: core: fix UAF in destroy_regulator()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 1f386d6894d0f1b7de8ef640c41622ddd698e7ab ]
+
+I got a UAF report as following:
+
+==================================================================
+BUG: KASAN: use-after-free in __lock_acquire+0x935/0x2060
+Read of size 8 at addr ffff88810e838220 by task python3/268
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x67/0x83
+ print_report+0x178/0x4b0
+ kasan_report+0x90/0x190
+ __lock_acquire+0x935/0x2060
+ lock_acquire+0x156/0x400
+ _raw_spin_lock+0x2a/0x40
+ lockref_get+0x11/0x30
+ simple_recursive_removal+0x41/0x440
+ debugfs_remove.part.12+0x32/0x50
+ debugfs_remove+0x29/0x30
+ _regulator_put.cold.54+0x3e/0x27f
+ regulator_put+0x1f/0x30
+ release_nodes+0x6a/0xa0
+ devres_release_all+0xf8/0x150
+
+Allocated by task 37:
+ kasan_save_stack+0x1c/0x40
+ kasan_set_track+0x21/0x30
+ __kasan_slab_alloc+0x5d/0x70
+ slab_post_alloc_hook+0x62/0x510
+ kmem_cache_alloc_lru+0x222/0x5a0
+ __d_alloc+0x31/0x440
+ d_alloc+0x30/0xf0
+ d_alloc_parallel+0xc4/0xd20
+ __lookup_slow+0x15e/0x2f0
+ lookup_one_len+0x13a/0x150
+ start_creating+0xea/0x190
+ debugfs_create_dir+0x1e/0x210
+ create_regulator+0x254/0x4e0
+ _regulator_get+0x2a1/0x467
+ _devm_regulator_get+0x5a/0xb0
+ regulator_virtual_probe+0xb9/0x1a0
+
+Freed by task 30:
+ kasan_save_stack+0x1c/0x40
+ kasan_set_track+0x21/0x30
+ kasan_save_free_info+0x2a/0x50
+ __kasan_slab_free+0x102/0x190
+ kmem_cache_free+0xf6/0x600
+ rcu_core+0x54c/0x12b0
+ __do_softirq+0xf2/0x5e3
+
+Last potentially related work creation:
+ kasan_save_stack+0x1c/0x40
+ __kasan_record_aux_stack+0x98/0xb0
+ call_rcu+0x42/0x700
+ dentry_free+0x6c/0xd0
+ __dentry_kill+0x23b/0x2d0
+ dput.part.31+0x431/0x780
+ simple_recursive_removal+0xa9/0x440
+ debugfs_remove.part.12+0x32/0x50
+ debugfs_remove+0x29/0x30
+ regulator_unregister+0xe3/0x230
+ release_nodes+0x6a/0xa0
+
+==================================================================
+
+Here is how happened:
+
+processor A                                    processor B
+regulator_register()
+  rdev_init_debugfs()
+    rdev->debugfs = debugfs_create_dir()
+                                               devm_regulator_get()
+                                                 rdev = regulator_dev_lookup()
+                                                 create_regulator(rdev)
+                                                   // using rdev->debugfs as parent
+                                                   debugfs_create_dir(rdev->debugfs)
+
+mfd_remove_devices_fn()
+  release_nodes()
+    regulator_unregister()
+      // free rdev->debugfs
+      debugfs_remove_recursive(rdev->debugfs)
+                                               release_nodes()
+                                                 destroy_regulator()
+                                                   debugfs_remove_recursive() <- causes UAF
+
+In devm_regulator_get(), after getting rdev, the refcount
+is get, so fix this by moving debugfs_remove_recursive()
+to regulator_dev_release(), then it can be proctected by
+the refcount, the 'rdev->debugfs' can not be freed until
+the refcount is 0.
+
+Fixes: 5de705194e98 ("regulator: Add basic per consumer debugfs")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221116033706.3595812-1-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index fd61c5c54a07..221ae807b379 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -5071,6 +5071,7 @@ static void regulator_dev_release(struct device *dev)
+ {
+       struct regulator_dev *rdev = dev_get_drvdata(dev);
++      debugfs_remove_recursive(rdev->debugfs);
+       kfree(rdev->constraints);
+       of_node_put(rdev->dev.of_node);
+       kfree(rdev);
+@@ -5586,7 +5587,6 @@ void regulator_unregister(struct regulator_dev *rdev)
+       mutex_lock(&regulator_list_mutex);
+-      debugfs_remove_recursive(rdev->debugfs);
+       WARN_ON(rdev->open_count);
+       regulator_remove_coupling(rdev);
+       unset_regulator_supplies(rdev);
+-- 
+2.35.1
+
diff --git a/queue-5.15/regulator-twl6030-re-add-twl6032_subclass.patch b/queue-5.15/regulator-twl6030-re-add-twl6032_subclass.patch
new file mode 100644 (file)
index 0000000..3270361
--- /dev/null
@@ -0,0 +1,47 @@
+From 21d20a7d7dbec9f9b0682e4dbab4484c2f1dc608 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Nov 2022 23:12:07 +0100
+Subject: regulator: twl6030: re-add TWL6032_SUBCLASS
+
+From: Andreas Kemnade <andreas@kemnade.info>
+
+[ Upstream commit 3d6c982b26db94cc21bc9f7784f63e8286b7be62 ]
+
+In former times, info->feature was populated via the parent driver
+by pdata/regulator_init_data->driver_data for all regulators when
+USB_PRODUCT_ID_LSB indicates a TWL6032.
+Today, the information is not set, so re-add it at the regulator
+definitions.
+
+Fixes: 25d82337705e2 ("regulator: twl: make driver DT only")
+Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
+Link: https://lore.kernel.org/r/20221120221208.3093727-2-andreas@kemnade.info
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/twl6030-regulator.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/regulator/twl6030-regulator.c b/drivers/regulator/twl6030-regulator.c
+index 430265c404d6..7c7e3648ea4b 100644
+--- a/drivers/regulator/twl6030-regulator.c
++++ b/drivers/regulator/twl6030-regulator.c
+@@ -530,6 +530,7 @@ static const struct twlreg_info TWL6030_INFO_##label = { \
+ #define TWL6032_ADJUSTABLE_LDO(label, offset) \
+ static const struct twlreg_info TWL6032_INFO_##label = { \
+       .base = offset, \
++      .features = TWL6032_SUBCLASS, \
+       .desc = { \
+               .name = #label, \
+               .id = TWL6032_REG_##label, \
+@@ -562,6 +563,7 @@ static const struct twlreg_info TWLFIXED_INFO_##label = { \
+ #define TWL6032_ADJUSTABLE_SMPS(label, offset) \
+ static const struct twlreg_info TWLSMPS_INFO_##label = { \
+       .base = offset, \
++      .features = TWL6032_SUBCLASS, \
+       .desc = { \
+               .name = #label, \
+               .id = TWL6032_REG_##label, \
+-- 
+2.35.1
+
diff --git a/queue-5.15/rxrpc-allow-list-of-in-use-local-udp-endpoints-to-be.patch b/queue-5.15/rxrpc-allow-list-of-in-use-local-udp-endpoints-to-be.patch
new file mode 100644 (file)
index 0000000..f97f2f6
--- /dev/null
@@ -0,0 +1,256 @@
+From 43b2978d26918174bcf61e14185cf1ccdffecc76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 08:45:15 +0100
+Subject: rxrpc: Allow list of in-use local UDP endpoints to be viewed in /proc
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 33912c2639ad76660988c8ca97e4d18fca89b668 ]
+
+Allow the list of in-use local UDP endpoints in the current network
+namespace to be viewed in /proc.
+
+To aid with this, the endpoint list is converted to an hlist and RCU-safe
+manipulation is used so that the list can be read with only the RCU
+read lock held.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: linux-afs@lists.infradead.org
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 3bcd6c7eaa53 ("rxrpc: Fix race between conn bundle lookup and bundle removal [ZDI-CAN-15975]")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/ar-internal.h  |  5 +--
+ net/rxrpc/local_object.c | 37 +++++++++++----------
+ net/rxrpc/net_ns.c       |  5 ++-
+ net/rxrpc/proc.c         | 69 ++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 94 insertions(+), 22 deletions(-)
+
+diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
+index f2e3fb77a02d..38dd63169aac 100644
+--- a/net/rxrpc/ar-internal.h
++++ b/net/rxrpc/ar-internal.h
+@@ -88,7 +88,7 @@ struct rxrpc_net {
+       struct work_struct      client_conn_reaper;
+       struct timer_list       client_conn_reap_timer;
+-      struct list_head        local_endpoints;
++      struct hlist_head       local_endpoints;
+       struct mutex            local_mutex;    /* Lock for ->local_endpoints */
+       DECLARE_HASHTABLE       (peer_hash, 10);
+@@ -281,7 +281,7 @@ struct rxrpc_local {
+       atomic_t                active_users;   /* Number of users of the local endpoint */
+       atomic_t                usage;          /* Number of references to the structure */
+       struct rxrpc_net        *rxnet;         /* The network ns in which this resides */
+-      struct list_head        link;
++      struct hlist_node       link;
+       struct socket           *socket;        /* my UDP socket */
+       struct work_struct      processor;
+       struct rxrpc_sock __rcu *service;       /* Service(s) listening on this endpoint */
+@@ -1016,6 +1016,7 @@ void rxrpc_put_peer_locked(struct rxrpc_peer *);
+ extern const struct seq_operations rxrpc_call_seq_ops;
+ extern const struct seq_operations rxrpc_connection_seq_ops;
+ extern const struct seq_operations rxrpc_peer_seq_ops;
++extern const struct seq_operations rxrpc_local_seq_ops;
+ /*
+  * recvmsg.c
+diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
+index 1d15940f61d7..0cbbbbcf490e 100644
+--- a/net/rxrpc/local_object.c
++++ b/net/rxrpc/local_object.c
+@@ -82,7 +82,7 @@ static struct rxrpc_local *rxrpc_alloc_local(struct rxrpc_net *rxnet,
+               atomic_set(&local->usage, 1);
+               atomic_set(&local->active_users, 1);
+               local->rxnet = rxnet;
+-              INIT_LIST_HEAD(&local->link);
++              INIT_HLIST_NODE(&local->link);
+               INIT_WORK(&local->processor, rxrpc_local_processor);
+               init_rwsem(&local->defrag_sem);
+               skb_queue_head_init(&local->reject_queue);
+@@ -181,7 +181,7 @@ struct rxrpc_local *rxrpc_lookup_local(struct net *net,
+ {
+       struct rxrpc_local *local;
+       struct rxrpc_net *rxnet = rxrpc_net(net);
+-      struct list_head *cursor;
++      struct hlist_node *cursor;
+       const char *age;
+       long diff;
+       int ret;
+@@ -191,16 +191,12 @@ struct rxrpc_local *rxrpc_lookup_local(struct net *net,
+       mutex_lock(&rxnet->local_mutex);
+-      for (cursor = rxnet->local_endpoints.next;
+-           cursor != &rxnet->local_endpoints;
+-           cursor = cursor->next) {
+-              local = list_entry(cursor, struct rxrpc_local, link);
++      hlist_for_each(cursor, &rxnet->local_endpoints) {
++              local = hlist_entry(cursor, struct rxrpc_local, link);
+               diff = rxrpc_local_cmp_key(local, srx);
+-              if (diff < 0)
++              if (diff != 0)
+                       continue;
+-              if (diff > 0)
+-                      break;
+               /* Services aren't allowed to share transport sockets, so
+                * reject that here.  It is possible that the object is dying -
+@@ -212,9 +208,10 @@ struct rxrpc_local *rxrpc_lookup_local(struct net *net,
+                       goto addr_in_use;
+               }
+-              /* Found a match.  We replace a dying object.  Attempting to
+-               * bind the transport socket may still fail if we're attempting
+-               * to use a local address that the dying object is still using.
++              /* Found a match.  We want to replace a dying object.
++               * Attempting to bind the transport socket may still fail if
++               * we're attempting to use a local address that the dying
++               * object is still using.
+                */
+               if (!rxrpc_use_local(local))
+                       break;
+@@ -231,10 +228,12 @@ struct rxrpc_local *rxrpc_lookup_local(struct net *net,
+       if (ret < 0)
+               goto sock_error;
+-      if (cursor != &rxnet->local_endpoints)
+-              list_replace_init(cursor, &local->link);
+-      else
+-              list_add_tail(&local->link, cursor);
++      if (cursor) {
++              hlist_replace_rcu(cursor, &local->link);
++              cursor->pprev = NULL;
++      } else {
++              hlist_add_head_rcu(&local->link, &rxnet->local_endpoints);
++      }
+       age = "new";
+ found:
+@@ -375,7 +374,7 @@ static void rxrpc_local_destroyer(struct rxrpc_local *local)
+       local->dead = true;
+       mutex_lock(&rxnet->local_mutex);
+-      list_del_init(&local->link);
++      hlist_del_init_rcu(&local->link);
+       mutex_unlock(&rxnet->local_mutex);
+       rxrpc_clean_up_local_conns(local);
+@@ -462,9 +461,9 @@ void rxrpc_destroy_all_locals(struct rxrpc_net *rxnet)
+       flush_workqueue(rxrpc_workqueue);
+-      if (!list_empty(&rxnet->local_endpoints)) {
++      if (!hlist_empty(&rxnet->local_endpoints)) {
+               mutex_lock(&rxnet->local_mutex);
+-              list_for_each_entry(local, &rxnet->local_endpoints, link) {
++              hlist_for_each_entry(local, &rxnet->local_endpoints, link) {
+                       pr_err("AF_RXRPC: Leaked local %p {%d}\n",
+                              local, atomic_read(&local->usage));
+               }
+diff --git a/net/rxrpc/net_ns.c b/net/rxrpc/net_ns.c
+index e4d6d432515b..bb4c25d6df64 100644
+--- a/net/rxrpc/net_ns.c
++++ b/net/rxrpc/net_ns.c
+@@ -72,7 +72,7 @@ static __net_init int rxrpc_init_net(struct net *net)
+       timer_setup(&rxnet->client_conn_reap_timer,
+                   rxrpc_client_conn_reap_timeout, 0);
+-      INIT_LIST_HEAD(&rxnet->local_endpoints);
++      INIT_HLIST_HEAD(&rxnet->local_endpoints);
+       mutex_init(&rxnet->local_mutex);
+       hash_init(rxnet->peer_hash);
+@@ -98,6 +98,9 @@ static __net_init int rxrpc_init_net(struct net *net)
+       proc_create_net("peers", 0444, rxnet->proc_net,
+                       &rxrpc_peer_seq_ops,
+                       sizeof(struct seq_net_private));
++      proc_create_net("locals", 0444, rxnet->proc_net,
++                      &rxrpc_local_seq_ops,
++                      sizeof(struct seq_net_private));
+       return 0;
+ err_proc:
+diff --git a/net/rxrpc/proc.c b/net/rxrpc/proc.c
+index 5a67955cc00f..7d007a66eba5 100644
+--- a/net/rxrpc/proc.c
++++ b/net/rxrpc/proc.c
+@@ -328,3 +328,72 @@ const struct seq_operations rxrpc_peer_seq_ops = {
+       .stop   = rxrpc_peer_seq_stop,
+       .show   = rxrpc_peer_seq_show,
+ };
++
++/*
++ * Generate a list of extant virtual local endpoints in /proc/net/rxrpc/locals
++ */
++static int rxrpc_local_seq_show(struct seq_file *seq, void *v)
++{
++      struct rxrpc_local *local;
++      char lbuff[50];
++
++      if (v == SEQ_START_TOKEN) {
++              seq_puts(seq,
++                       "Proto Local                                          "
++                       " Use Act\n");
++              return 0;
++      }
++
++      local = hlist_entry(v, struct rxrpc_local, link);
++
++      sprintf(lbuff, "%pISpc", &local->srx.transport);
++
++      seq_printf(seq,
++                 "UDP   %-47.47s %3u %3u\n",
++                 lbuff,
++                 atomic_read(&local->usage),
++                 atomic_read(&local->active_users));
++
++      return 0;
++}
++
++static void *rxrpc_local_seq_start(struct seq_file *seq, loff_t *_pos)
++      __acquires(rcu)
++{
++      struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
++      unsigned int n;
++
++      rcu_read_lock();
++
++      if (*_pos >= UINT_MAX)
++              return NULL;
++
++      n = *_pos;
++      if (n == 0)
++              return SEQ_START_TOKEN;
++
++      return seq_hlist_start_rcu(&rxnet->local_endpoints, n - 1);
++}
++
++static void *rxrpc_local_seq_next(struct seq_file *seq, void *v, loff_t *_pos)
++{
++      struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
++
++      if (*_pos >= UINT_MAX)
++              return NULL;
++
++      return seq_hlist_next_rcu(v, &rxnet->local_endpoints, _pos);
++}
++
++static void rxrpc_local_seq_stop(struct seq_file *seq, void *v)
++      __releases(rcu)
++{
++      rcu_read_unlock();
++}
++
++const struct seq_operations rxrpc_local_seq_ops = {
++      .start  = rxrpc_local_seq_start,
++      .next   = rxrpc_local_seq_next,
++      .stop   = rxrpc_local_seq_stop,
++      .show   = rxrpc_local_seq_show,
++};
+-- 
+2.35.1
+
diff --git a/queue-5.15/rxrpc-fix-race-between-conn-bundle-lookup-and-bundle.patch b/queue-5.15/rxrpc-fix-race-between-conn-bundle-lookup-and-bundle.patch
new file mode 100644 (file)
index 0000000..5904ef5
--- /dev/null
@@ -0,0 +1,173 @@
+From 5a9d3fa4412612b3a24698c7270748c5767cf745 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 14:02:28 +0000
+Subject: rxrpc: Fix race between conn bundle lookup and bundle removal
+ [ZDI-CAN-15975]
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 3bcd6c7eaa53b56c3f584da46a1f7652e759d0e5 ]
+
+After rxrpc_unbundle_conn() has removed a connection from a bundle, it
+checks to see if there are any conns with available channels and, if not,
+removes and attempts to destroy the bundle.
+
+Whilst it does check after grabbing client_bundles_lock that there are no
+connections attached, this races with rxrpc_look_up_bundle() retrieving the
+bundle, but not attaching a connection for the connection to be attached
+later.
+
+There is therefore a window in which the bundle can get destroyed before we
+manage to attach a new connection to it.
+
+Fix this by adding an "active" counter to struct rxrpc_bundle:
+
+ (1) rxrpc_connect_call() obtains an active count by prepping/looking up a
+     bundle and ditches it before returning.
+
+ (2) If, during rxrpc_connect_call(), a connection is added to the bundle,
+     this obtains an active count, which is held until the connection is
+     discarded.
+
+ (3) rxrpc_deactivate_bundle() is created to drop an active count on a
+     bundle and destroy it when the active count reaches 0.  The active
+     count is checked inside client_bundles_lock() to prevent a race with
+     rxrpc_look_up_bundle().
+
+ (4) rxrpc_unbundle_conn() then calls rxrpc_deactivate_bundle().
+
+Fixes: 245500d853e9 ("rxrpc: Rewrite the client connection manager")
+Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-15975
+Signed-off-by: David Howells <dhowells@redhat.com>
+Tested-by: zdi-disclosures@trendmicro.com
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: linux-afs@lists.infradead.org
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/ar-internal.h |  1 +
+ net/rxrpc/conn_client.c | 38 +++++++++++++++++++++++---------------
+ 2 files changed, 24 insertions(+), 15 deletions(-)
+
+diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
+index 62c70709d798..e0123efa2a62 100644
+--- a/net/rxrpc/ar-internal.h
++++ b/net/rxrpc/ar-internal.h
+@@ -399,6 +399,7 @@ enum rxrpc_conn_proto_state {
+ struct rxrpc_bundle {
+       struct rxrpc_conn_parameters params;
+       refcount_t              ref;
++      atomic_t                active;         /* Number of active users */
+       unsigned int            debug_id;
+       bool                    try_upgrade;    /* True if the bundle is attempting upgrade */
+       bool                    alloc_conn;     /* True if someone's getting a conn */
+diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c
+index 3c9eeb5b750c..bdb335cb2d05 100644
+--- a/net/rxrpc/conn_client.c
++++ b/net/rxrpc/conn_client.c
+@@ -40,6 +40,8 @@ __read_mostly unsigned long rxrpc_conn_idle_client_fast_expiry = 2 * HZ;
+ DEFINE_IDR(rxrpc_client_conn_ids);
+ static DEFINE_SPINLOCK(rxrpc_conn_id_lock);
++static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle);
++
+ /*
+  * Get a connection ID and epoch for a client connection from the global pool.
+  * The connection struct pointer is then recorded in the idr radix tree.  The
+@@ -123,6 +125,7 @@ static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_conn_parameters *cp,
+               bundle->params = *cp;
+               rxrpc_get_peer(bundle->params.peer);
+               refcount_set(&bundle->ref, 1);
++              atomic_set(&bundle->active, 1);
+               spin_lock_init(&bundle->channel_lock);
+               INIT_LIST_HEAD(&bundle->waiting_calls);
+       }
+@@ -149,7 +152,7 @@ void rxrpc_put_bundle(struct rxrpc_bundle *bundle)
+       dead = __refcount_dec_and_test(&bundle->ref, &r);
+-      _debug("PUT B=%x %d", d, r);
++      _debug("PUT B=%x %d", d, r - 1);
+       if (dead)
+               rxrpc_free_bundle(bundle);
+ }
+@@ -338,6 +341,7 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
+       rxrpc_free_bundle(candidate);
+ found_bundle:
+       rxrpc_get_bundle(bundle);
++      atomic_inc(&bundle->active);
+       spin_unlock(&local->client_bundles_lock);
+       _leave(" = %u [found]", bundle->debug_id);
+       return bundle;
+@@ -435,6 +439,7 @@ static void rxrpc_add_conn_to_bundle(struct rxrpc_bundle *bundle, gfp_t gfp)
+                       if (old)
+                               trace_rxrpc_client(old, -1, rxrpc_client_replace);
+                       candidate->bundle_shift = shift;
++                      atomic_inc(&bundle->active);
+                       bundle->conns[i] = candidate;
+                       for (j = 0; j < RXRPC_MAXCALLS; j++)
+                               set_bit(shift + j, &bundle->avail_chans);
+@@ -725,6 +730,7 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,
+       smp_rmb();
+ out_put_bundle:
++      rxrpc_deactivate_bundle(bundle);
+       rxrpc_put_bundle(bundle);
+ out:
+       _leave(" = %d", ret);
+@@ -900,9 +906,8 @@ void rxrpc_disconnect_client_call(struct rxrpc_bundle *bundle, struct rxrpc_call
+ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
+ {
+       struct rxrpc_bundle *bundle = conn->bundle;
+-      struct rxrpc_local *local = bundle->params.local;
+       unsigned int bindex;
+-      bool need_drop = false, need_put = false;
++      bool need_drop = false;
+       int i;
+       _enter("C=%x", conn->debug_id);
+@@ -921,15 +926,22 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
+       }
+       spin_unlock(&bundle->channel_lock);
+-      /* If there are no more connections, remove the bundle */
+-      if (!bundle->avail_chans) {
+-              _debug("maybe unbundle");
+-              spin_lock(&local->client_bundles_lock);
++      if (need_drop) {
++              rxrpc_deactivate_bundle(bundle);
++              rxrpc_put_connection(conn);
++      }
++}
+-              for (i = 0; i < ARRAY_SIZE(bundle->conns); i++)
+-                      if (bundle->conns[i])
+-                              break;
+-              if (i == ARRAY_SIZE(bundle->conns) && !bundle->params.exclusive) {
++/*
++ * Drop the active count on a bundle.
++ */
++static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle)
++{
++      struct rxrpc_local *local = bundle->params.local;
++      bool need_put = false;
++
++      if (atomic_dec_and_lock(&bundle->active, &local->client_bundles_lock)) {
++              if (!bundle->params.exclusive) {
+                       _debug("erase bundle");
+                       rb_erase(&bundle->local_node, &local->client_bundles);
+                       need_put = true;
+@@ -939,10 +951,6 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
+               if (need_put)
+                       rxrpc_put_bundle(bundle);
+       }
+-
+-      if (need_drop)
+-              rxrpc_put_connection(conn);
+-      _leave("");
+ }
+ /*
+-- 
+2.35.1
+
diff --git a/queue-5.15/rxrpc-use-refcount_t-rather-than-atomic_t.patch b/queue-5.15/rxrpc-use-refcount_t-rather-than-atomic_t.patch
new file mode 100644 (file)
index 0000000..b63131f
--- /dev/null
@@ -0,0 +1,864 @@
+From 52810344f776ff77fc3b17f9ef57071c00d54613 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 08:45:22 +0100
+Subject: rxrpc: Use refcount_t rather than atomic_t
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit a05754295e01f006a651eec759c5dbe682ef6cef ]
+
+Move to using refcount_t rather than atomic_t for refcounts in rxrpc.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: linux-afs@lists.infradead.org
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 3bcd6c7eaa53 ("rxrpc: Fix race between conn bundle lookup and bundle removal [ZDI-CAN-15975]")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/trace/events/rxrpc.h |  2 +-
+ net/rxrpc/af_rxrpc.c         |  2 +-
+ net/rxrpc/ar-internal.h      | 18 ++++---------
+ net/rxrpc/call_accept.c      |  4 +--
+ net/rxrpc/call_object.c      | 44 ++++++++++++++++----------------
+ net/rxrpc/conn_client.c      | 30 +++++++++++-----------
+ net/rxrpc/conn_object.c      | 49 ++++++++++++++++++------------------
+ net/rxrpc/conn_service.c     |  8 +++---
+ net/rxrpc/input.c            |  4 +--
+ net/rxrpc/local_object.c     | 31 ++++++++++++-----------
+ net/rxrpc/peer_object.c      | 40 +++++++++++++++--------------
+ net/rxrpc/proc.c             |  8 +++---
+ net/rxrpc/skbuff.c           |  1 -
+ 13 files changed, 119 insertions(+), 122 deletions(-)
+
+diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h
+index 1c714336b863..221856f2d295 100644
+--- a/include/trace/events/rxrpc.h
++++ b/include/trace/events/rxrpc.h
+@@ -583,7 +583,7 @@ TRACE_EVENT(rxrpc_client,
+           TP_fast_assign(
+                   __entry->conn = conn ? conn->debug_id : 0;
+                   __entry->channel = channel;
+-                  __entry->usage = conn ? atomic_read(&conn->usage) : -2;
++                  __entry->usage = conn ? refcount_read(&conn->ref) : -2;
+                   __entry->op = op;
+                   __entry->cid = conn ? conn->proto.cid : 0;
+                          ),
+diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
+index 2b5f89713e36..ceba28e9dce6 100644
+--- a/net/rxrpc/af_rxrpc.c
++++ b/net/rxrpc/af_rxrpc.c
+@@ -351,7 +351,7 @@ static void rxrpc_dummy_notify_rx(struct sock *sk, struct rxrpc_call *rxcall,
+  */
+ void rxrpc_kernel_end_call(struct socket *sock, struct rxrpc_call *call)
+ {
+-      _enter("%d{%d}", call->debug_id, atomic_read(&call->usage));
++      _enter("%d{%d}", call->debug_id, refcount_read(&call->ref));
+       mutex_lock(&call->user_mutex);
+       rxrpc_release_call(rxrpc_sk(sock->sk), call);
+diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
+index 38dd63169aac..62c70709d798 100644
+--- a/net/rxrpc/ar-internal.h
++++ b/net/rxrpc/ar-internal.h
+@@ -15,14 +15,6 @@
+ #include <keys/rxrpc-type.h>
+ #include "protocol.h"
+-#if 0
+-#define CHECK_SLAB_OKAY(X)                                 \
+-      BUG_ON(atomic_read((X)) >> (sizeof(atomic_t) - 2) == \
+-             (POISON_FREE << 8 | POISON_FREE))
+-#else
+-#define CHECK_SLAB_OKAY(X) do {} while (0)
+-#endif
+-
+ #define FCRYPT_BSIZE 8
+ struct rxrpc_crypt {
+       union {
+@@ -279,7 +271,7 @@ struct rxrpc_security {
+ struct rxrpc_local {
+       struct rcu_head         rcu;
+       atomic_t                active_users;   /* Number of users of the local endpoint */
+-      atomic_t                usage;          /* Number of references to the structure */
++      refcount_t              ref;            /* Number of references to the structure */
+       struct rxrpc_net        *rxnet;         /* The network ns in which this resides */
+       struct hlist_node       link;
+       struct socket           *socket;        /* my UDP socket */
+@@ -304,7 +296,7 @@ struct rxrpc_local {
+  */
+ struct rxrpc_peer {
+       struct rcu_head         rcu;            /* This must be first */
+-      atomic_t                usage;
++      refcount_t              ref;
+       unsigned long           hash_key;
+       struct hlist_node       hash_link;
+       struct rxrpc_local      *local;
+@@ -406,7 +398,7 @@ enum rxrpc_conn_proto_state {
+  */
+ struct rxrpc_bundle {
+       struct rxrpc_conn_parameters params;
+-      atomic_t                usage;
++      refcount_t              ref;
+       unsigned int            debug_id;
+       bool                    try_upgrade;    /* True if the bundle is attempting upgrade */
+       bool                    alloc_conn;     /* True if someone's getting a conn */
+@@ -427,7 +419,7 @@ struct rxrpc_connection {
+       struct rxrpc_conn_proto proto;
+       struct rxrpc_conn_parameters params;
+-      atomic_t                usage;
++      refcount_t              ref;
+       struct rcu_head         rcu;
+       struct list_head        cache_link;
+@@ -609,7 +601,7 @@ struct rxrpc_call {
+       int                     error;          /* Local error incurred */
+       enum rxrpc_call_state   state;          /* current state of call */
+       enum rxrpc_call_completion completion;  /* Call completion condition */
+-      atomic_t                usage;
++      refcount_t              ref;
+       u16                     service_id;     /* service ID */
+       u8                      security_ix;    /* Security type */
+       enum rxrpc_interruptibility interruptibility; /* At what point call may be interrupted */
+diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c
+index 8b24ffbc72ef..99e10eea3732 100644
+--- a/net/rxrpc/call_accept.c
++++ b/net/rxrpc/call_accept.c
+@@ -91,7 +91,7 @@ static int rxrpc_service_prealloc_one(struct rxrpc_sock *rx,
+                                 (head + 1) & (size - 1));
+               trace_rxrpc_conn(conn->debug_id, rxrpc_conn_new_service,
+-                               atomic_read(&conn->usage), here);
++                               refcount_read(&conn->ref), here);
+       }
+       /* Now it gets complicated, because calls get registered with the
+@@ -104,7 +104,7 @@ static int rxrpc_service_prealloc_one(struct rxrpc_sock *rx,
+       call->state = RXRPC_CALL_SERVER_PREALLOC;
+       trace_rxrpc_call(call->debug_id, rxrpc_call_new_service,
+-                       atomic_read(&call->usage),
++                       refcount_read(&call->ref),
+                        here, (const void *)user_call_ID);
+       write_lock(&rx->call_lock);
+diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c
+index d674d90e7031..6401cdf7a624 100644
+--- a/net/rxrpc/call_object.c
++++ b/net/rxrpc/call_object.c
+@@ -112,7 +112,7 @@ struct rxrpc_call *rxrpc_find_call_by_user_ID(struct rxrpc_sock *rx,
+ found_extant_call:
+       rxrpc_get_call(call, rxrpc_call_got);
+       read_unlock(&rx->call_lock);
+-      _leave(" = %p [%d]", call, atomic_read(&call->usage));
++      _leave(" = %p [%d]", call, refcount_read(&call->ref));
+       return call;
+ }
+@@ -160,7 +160,7 @@ struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp,
+       spin_lock_init(&call->notify_lock);
+       spin_lock_init(&call->input_lock);
+       rwlock_init(&call->state_lock);
+-      atomic_set(&call->usage, 1);
++      refcount_set(&call->ref, 1);
+       call->debug_id = debug_id;
+       call->tx_total_len = -1;
+       call->next_rx_timo = 20 * HZ;
+@@ -301,7 +301,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
+       call->interruptibility = p->interruptibility;
+       call->tx_total_len = p->tx_total_len;
+       trace_rxrpc_call(call->debug_id, rxrpc_call_new_client,
+-                       atomic_read(&call->usage),
++                       refcount_read(&call->ref),
+                        here, (const void *)p->user_call_ID);
+       if (p->kernel)
+               __set_bit(RXRPC_CALL_KERNEL, &call->flags);
+@@ -354,7 +354,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
+               goto error_attached_to_socket;
+       trace_rxrpc_call(call->debug_id, rxrpc_call_connected,
+-                       atomic_read(&call->usage), here, NULL);
++                       refcount_read(&call->ref), here, NULL);
+       rxrpc_start_call_timer(call);
+@@ -374,7 +374,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
+       __rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR,
+                                   RX_CALL_DEAD, -EEXIST);
+       trace_rxrpc_call(call->debug_id, rxrpc_call_error,
+-                       atomic_read(&call->usage), here, ERR_PTR(-EEXIST));
++                       refcount_read(&call->ref), here, ERR_PTR(-EEXIST));
+       rxrpc_release_call(rx, call);
+       mutex_unlock(&call->user_mutex);
+       rxrpc_put_call(call, rxrpc_call_put);
+@@ -388,7 +388,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
+        */
+ error_attached_to_socket:
+       trace_rxrpc_call(call->debug_id, rxrpc_call_error,
+-                       atomic_read(&call->usage), here, ERR_PTR(ret));
++                       refcount_read(&call->ref), here, ERR_PTR(ret));
+       set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
+       __rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR,
+                                   RX_CALL_DEAD, ret);
+@@ -444,8 +444,9 @@ void rxrpc_incoming_call(struct rxrpc_sock *rx,
+ bool rxrpc_queue_call(struct rxrpc_call *call)
+ {
+       const void *here = __builtin_return_address(0);
+-      int n = atomic_fetch_add_unless(&call->usage, 1, 0);
+-      if (n == 0)
++      int n;
++
++      if (!__refcount_inc_not_zero(&call->ref, &n))
+               return false;
+       if (rxrpc_queue_work(&call->processor))
+               trace_rxrpc_call(call->debug_id, rxrpc_call_queued, n + 1,
+@@ -461,7 +462,7 @@ bool rxrpc_queue_call(struct rxrpc_call *call)
+ bool __rxrpc_queue_call(struct rxrpc_call *call)
+ {
+       const void *here = __builtin_return_address(0);
+-      int n = atomic_read(&call->usage);
++      int n = refcount_read(&call->ref);
+       ASSERTCMP(n, >=, 1);
+       if (rxrpc_queue_work(&call->processor))
+               trace_rxrpc_call(call->debug_id, rxrpc_call_queued_ref, n,
+@@ -478,7 +479,7 @@ void rxrpc_see_call(struct rxrpc_call *call)
+ {
+       const void *here = __builtin_return_address(0);
+       if (call) {
+-              int n = atomic_read(&call->usage);
++              int n = refcount_read(&call->ref);
+               trace_rxrpc_call(call->debug_id, rxrpc_call_seen, n,
+                                here, NULL);
+@@ -488,11 +489,11 @@ void rxrpc_see_call(struct rxrpc_call *call)
+ bool rxrpc_try_get_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
+ {
+       const void *here = __builtin_return_address(0);
+-      int n = atomic_fetch_add_unless(&call->usage, 1, 0);
++      int n;
+-      if (n == 0)
++      if (!__refcount_inc_not_zero(&call->ref, &n))
+               return false;
+-      trace_rxrpc_call(call->debug_id, op, n, here, NULL);
++      trace_rxrpc_call(call->debug_id, op, n + 1, here, NULL);
+       return true;
+ }
+@@ -502,9 +503,10 @@ bool rxrpc_try_get_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
+ void rxrpc_get_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
+ {
+       const void *here = __builtin_return_address(0);
+-      int n = atomic_inc_return(&call->usage);
++      int n;
+-      trace_rxrpc_call(call->debug_id, op, n, here, NULL);
++      __refcount_inc(&call->ref, &n);
++      trace_rxrpc_call(call->debug_id, op, n + 1, here, NULL);
+ }
+ /*
+@@ -529,10 +531,10 @@ void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call)
+       struct rxrpc_connection *conn = call->conn;
+       bool put = false;
+-      _enter("{%d,%d}", call->debug_id, atomic_read(&call->usage));
++      _enter("{%d,%d}", call->debug_id, refcount_read(&call->ref));
+       trace_rxrpc_call(call->debug_id, rxrpc_call_release,
+-                       atomic_read(&call->usage),
++                       refcount_read(&call->ref),
+                        here, (const void *)call->flags);
+       ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
+@@ -621,14 +623,14 @@ void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
+       struct rxrpc_net *rxnet = call->rxnet;
+       const void *here = __builtin_return_address(0);
+       unsigned int debug_id = call->debug_id;
++      bool dead;
+       int n;
+       ASSERT(call != NULL);
+-      n = atomic_dec_return(&call->usage);
++      dead = __refcount_dec_and_test(&call->ref, &n);
+       trace_rxrpc_call(debug_id, op, n, here, NULL);
+-      ASSERTCMP(n, >=, 0);
+-      if (n == 0) {
++      if (dead) {
+               _debug("call %d dead", call->debug_id);
+               ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
+@@ -718,7 +720,7 @@ void rxrpc_destroy_all_calls(struct rxrpc_net *rxnet)
+                       list_del_init(&call->link);
+                       pr_err("Call %p still in use (%d,%s,%lx,%lx)!\n",
+-                             call, atomic_read(&call->usage),
++                             call, refcount_read(&call->ref),
+                              rxrpc_call_states[call->state],
+                              call->flags, call->events);
+diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c
+index 8120138dac01..3c9eeb5b750c 100644
+--- a/net/rxrpc/conn_client.c
++++ b/net/rxrpc/conn_client.c
+@@ -102,7 +102,7 @@ void rxrpc_destroy_client_conn_ids(void)
+       if (!idr_is_empty(&rxrpc_client_conn_ids)) {
+               idr_for_each_entry(&rxrpc_client_conn_ids, conn, id) {
+                       pr_err("AF_RXRPC: Leaked client conn %p {%d}\n",
+-                             conn, atomic_read(&conn->usage));
++                             conn, refcount_read(&conn->ref));
+               }
+               BUG();
+       }
+@@ -122,7 +122,7 @@ static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_conn_parameters *cp,
+       if (bundle) {
+               bundle->params = *cp;
+               rxrpc_get_peer(bundle->params.peer);
+-              atomic_set(&bundle->usage, 1);
++              refcount_set(&bundle->ref, 1);
+               spin_lock_init(&bundle->channel_lock);
+               INIT_LIST_HEAD(&bundle->waiting_calls);
+       }
+@@ -131,7 +131,7 @@ static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_conn_parameters *cp,
+ struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *bundle)
+ {
+-      atomic_inc(&bundle->usage);
++      refcount_inc(&bundle->ref);
+       return bundle;
+ }
+@@ -144,10 +144,13 @@ static void rxrpc_free_bundle(struct rxrpc_bundle *bundle)
+ void rxrpc_put_bundle(struct rxrpc_bundle *bundle)
+ {
+       unsigned int d = bundle->debug_id;
+-      unsigned int u = atomic_dec_return(&bundle->usage);
++      bool dead;
++      int r;
+-      _debug("PUT B=%x %u", d, u);
+-      if (u == 0)
++      dead = __refcount_dec_and_test(&bundle->ref, &r);
++
++      _debug("PUT B=%x %d", d, r);
++      if (dead)
+               rxrpc_free_bundle(bundle);
+ }
+@@ -169,7 +172,7 @@ rxrpc_alloc_client_connection(struct rxrpc_bundle *bundle, gfp_t gfp)
+               return ERR_PTR(-ENOMEM);
+       }
+-      atomic_set(&conn->usage, 1);
++      refcount_set(&conn->ref, 1);
+       conn->bundle            = bundle;
+       conn->params            = bundle->params;
+       conn->out_clientflag    = RXRPC_CLIENT_INITIATED;
+@@ -195,7 +198,7 @@ rxrpc_alloc_client_connection(struct rxrpc_bundle *bundle, gfp_t gfp)
+       key_get(conn->params.key);
+       trace_rxrpc_conn(conn->debug_id, rxrpc_conn_new_client,
+-                       atomic_read(&conn->usage),
++                       refcount_read(&conn->ref),
+                        __builtin_return_address(0));
+       atomic_inc(&rxnet->nr_client_conns);
+@@ -966,14 +969,13 @@ void rxrpc_put_client_conn(struct rxrpc_connection *conn)
+ {
+       const void *here = __builtin_return_address(0);
+       unsigned int debug_id = conn->debug_id;
+-      int n;
++      bool dead;
++      int r;
+-      n = atomic_dec_return(&conn->usage);
+-      trace_rxrpc_conn(debug_id, rxrpc_conn_put_client, n, here);
+-      if (n <= 0) {
+-              ASSERTCMP(n, >=, 0);
++      dead = __refcount_dec_and_test(&conn->ref, &r);
++      trace_rxrpc_conn(debug_id, rxrpc_conn_put_client, r - 1, here);
++      if (dead)
+               rxrpc_kill_client_conn(conn);
+-      }
+ }
+ /*
+diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c
+index 660cd9b1a465..22089e37e97f 100644
+--- a/net/rxrpc/conn_object.c
++++ b/net/rxrpc/conn_object.c
+@@ -104,7 +104,7 @@ struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *local,
+                       goto not_found;
+               *_peer = peer;
+               conn = rxrpc_find_service_conn_rcu(peer, skb);
+-              if (!conn || atomic_read(&conn->usage) == 0)
++              if (!conn || refcount_read(&conn->ref) == 0)
+                       goto not_found;
+               _leave(" = %p", conn);
+               return conn;
+@@ -114,7 +114,7 @@ struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *local,
+                */
+               conn = idr_find(&rxrpc_client_conn_ids,
+                               sp->hdr.cid >> RXRPC_CIDSHIFT);
+-              if (!conn || atomic_read(&conn->usage) == 0) {
++              if (!conn || refcount_read(&conn->ref) == 0) {
+                       _debug("no conn");
+                       goto not_found;
+               }
+@@ -263,11 +263,12 @@ void rxrpc_kill_connection(struct rxrpc_connection *conn)
+ bool rxrpc_queue_conn(struct rxrpc_connection *conn)
+ {
+       const void *here = __builtin_return_address(0);
+-      int n = atomic_fetch_add_unless(&conn->usage, 1, 0);
+-      if (n == 0)
++      int r;
++
++      if (!__refcount_inc_not_zero(&conn->ref, &r))
+               return false;
+       if (rxrpc_queue_work(&conn->processor))
+-              trace_rxrpc_conn(conn->debug_id, rxrpc_conn_queued, n + 1, here);
++              trace_rxrpc_conn(conn->debug_id, rxrpc_conn_queued, r + 1, here);
+       else
+               rxrpc_put_connection(conn);
+       return true;
+@@ -280,7 +281,7 @@ void rxrpc_see_connection(struct rxrpc_connection *conn)
+ {
+       const void *here = __builtin_return_address(0);
+       if (conn) {
+-              int n = atomic_read(&conn->usage);
++              int n = refcount_read(&conn->ref);
+               trace_rxrpc_conn(conn->debug_id, rxrpc_conn_seen, n, here);
+       }
+@@ -292,9 +293,10 @@ void rxrpc_see_connection(struct rxrpc_connection *conn)
+ struct rxrpc_connection *rxrpc_get_connection(struct rxrpc_connection *conn)
+ {
+       const void *here = __builtin_return_address(0);
+-      int n = atomic_inc_return(&conn->usage);
++      int r;
+-      trace_rxrpc_conn(conn->debug_id, rxrpc_conn_got, n, here);
++      __refcount_inc(&conn->ref, &r);
++      trace_rxrpc_conn(conn->debug_id, rxrpc_conn_got, r, here);
+       return conn;
+ }
+@@ -305,11 +307,11 @@ struct rxrpc_connection *
+ rxrpc_get_connection_maybe(struct rxrpc_connection *conn)
+ {
+       const void *here = __builtin_return_address(0);
++      int r;
+       if (conn) {
+-              int n = atomic_fetch_add_unless(&conn->usage, 1, 0);
+-              if (n > 0)
+-                      trace_rxrpc_conn(conn->debug_id, rxrpc_conn_got, n + 1, here);
++              if (__refcount_inc_not_zero(&conn->ref, &r))
++                      trace_rxrpc_conn(conn->debug_id, rxrpc_conn_got, r + 1, here);
+               else
+                       conn = NULL;
+       }
+@@ -333,12 +335,11 @@ void rxrpc_put_service_conn(struct rxrpc_connection *conn)
+ {
+       const void *here = __builtin_return_address(0);
+       unsigned int debug_id = conn->debug_id;
+-      int n;
++      int r;
+-      n = atomic_dec_return(&conn->usage);
+-      trace_rxrpc_conn(debug_id, rxrpc_conn_put_service, n, here);
+-      ASSERTCMP(n, >=, 0);
+-      if (n == 1)
++      __refcount_dec(&conn->ref, &r);
++      trace_rxrpc_conn(debug_id, rxrpc_conn_put_service, r - 1, here);
++      if (r - 1 == 1)
+               rxrpc_set_service_reap_timer(conn->params.local->rxnet,
+                                            jiffies + rxrpc_connection_expiry);
+ }
+@@ -351,9 +352,9 @@ static void rxrpc_destroy_connection(struct rcu_head *rcu)
+       struct rxrpc_connection *conn =
+               container_of(rcu, struct rxrpc_connection, rcu);
+-      _enter("{%d,u=%d}", conn->debug_id, atomic_read(&conn->usage));
++      _enter("{%d,u=%d}", conn->debug_id, refcount_read(&conn->ref));
+-      ASSERTCMP(atomic_read(&conn->usage), ==, 0);
++      ASSERTCMP(refcount_read(&conn->ref), ==, 0);
+       _net("DESTROY CONN %d", conn->debug_id);
+@@ -392,8 +393,8 @@ void rxrpc_service_connection_reaper(struct work_struct *work)
+       write_lock(&rxnet->conn_lock);
+       list_for_each_entry_safe(conn, _p, &rxnet->service_conns, link) {
+-              ASSERTCMP(atomic_read(&conn->usage), >, 0);
+-              if (likely(atomic_read(&conn->usage) > 1))
++              ASSERTCMP(refcount_read(&conn->ref), >, 0);
++              if (likely(refcount_read(&conn->ref) > 1))
+                       continue;
+               if (conn->state == RXRPC_CONN_SERVICE_PREALLOC)
+                       continue;
+@@ -405,7 +406,7 @@ void rxrpc_service_connection_reaper(struct work_struct *work)
+                               expire_at = idle_timestamp + rxrpc_closed_conn_expiry * HZ;
+                       _debug("reap CONN %d { u=%d,t=%ld }",
+-                             conn->debug_id, atomic_read(&conn->usage),
++                             conn->debug_id, refcount_read(&conn->ref),
+                              (long)expire_at - (long)now);
+                       if (time_before(now, expire_at)) {
+@@ -418,7 +419,7 @@ void rxrpc_service_connection_reaper(struct work_struct *work)
+               /* The usage count sits at 1 whilst the object is unused on the
+                * list; we reduce that to 0 to make the object unavailable.
+                */
+-              if (atomic_cmpxchg(&conn->usage, 1, 0) != 1)
++              if (!refcount_dec_if_one(&conn->ref))
+                       continue;
+               trace_rxrpc_conn(conn->debug_id, rxrpc_conn_reap_service, 0, NULL);
+@@ -442,7 +443,7 @@ void rxrpc_service_connection_reaper(struct work_struct *work)
+                                 link);
+               list_del_init(&conn->link);
+-              ASSERTCMP(atomic_read(&conn->usage), ==, 0);
++              ASSERTCMP(refcount_read(&conn->ref), ==, 0);
+               rxrpc_kill_connection(conn);
+       }
+@@ -470,7 +471,7 @@ void rxrpc_destroy_all_connections(struct rxrpc_net *rxnet)
+       write_lock(&rxnet->conn_lock);
+       list_for_each_entry_safe(conn, _p, &rxnet->service_conns, link) {
+               pr_err("AF_RXRPC: Leaked conn %p {%d}\n",
+-                     conn, atomic_read(&conn->usage));
++                     conn, refcount_read(&conn->ref));
+               leak = true;
+       }
+       write_unlock(&rxnet->conn_lock);
+diff --git a/net/rxrpc/conn_service.c b/net/rxrpc/conn_service.c
+index e1966dfc9152..6e6aa02c6f9e 100644
+--- a/net/rxrpc/conn_service.c
++++ b/net/rxrpc/conn_service.c
+@@ -9,7 +9,7 @@
+ #include "ar-internal.h"
+ static struct rxrpc_bundle rxrpc_service_dummy_bundle = {
+-      .usage          = ATOMIC_INIT(1),
++      .ref            = REFCOUNT_INIT(1),
+       .debug_id       = UINT_MAX,
+       .channel_lock   = __SPIN_LOCK_UNLOCKED(&rxrpc_service_dummy_bundle.channel_lock),
+ };
+@@ -99,7 +99,7 @@ static void rxrpc_publish_service_conn(struct rxrpc_peer *peer,
+       return;
+ found_extant_conn:
+-      if (atomic_read(&cursor->usage) == 0)
++      if (refcount_read(&cursor->ref) == 0)
+               goto replace_old_connection;
+       write_sequnlock_bh(&peer->service_conn_lock);
+       /* We should not be able to get here.  rxrpc_incoming_connection() is
+@@ -132,7 +132,7 @@ struct rxrpc_connection *rxrpc_prealloc_service_connection(struct rxrpc_net *rxn
+                * the rxrpc_connections list.
+                */
+               conn->state = RXRPC_CONN_SERVICE_PREALLOC;
+-              atomic_set(&conn->usage, 2);
++              refcount_set(&conn->ref, 2);
+               conn->bundle = rxrpc_get_bundle(&rxrpc_service_dummy_bundle);
+               atomic_inc(&rxnet->nr_conns);
+@@ -142,7 +142,7 @@ struct rxrpc_connection *rxrpc_prealloc_service_connection(struct rxrpc_net *rxn
+               write_unlock(&rxnet->conn_lock);
+               trace_rxrpc_conn(conn->debug_id, rxrpc_conn_new_service,
+-                               atomic_read(&conn->usage),
++                               refcount_read(&conn->ref),
+                                __builtin_return_address(0));
+       }
+diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
+index 3521ebd0ee41..721d847ba92b 100644
+--- a/net/rxrpc/input.c
++++ b/net/rxrpc/input.c
+@@ -1190,8 +1190,6 @@ static void rxrpc_post_packet_to_local(struct rxrpc_local *local,
+  */
+ static void rxrpc_reject_packet(struct rxrpc_local *local, struct sk_buff *skb)
+ {
+-      CHECK_SLAB_OKAY(&local->usage);
+-
+       if (rxrpc_get_local_maybe(local)) {
+               skb_queue_tail(&local->reject_queue, skb);
+               rxrpc_queue_local(local);
+@@ -1449,7 +1447,7 @@ int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb)
+               }
+       }
+-      if (!call || atomic_read(&call->usage) == 0) {
++      if (!call || refcount_read(&call->ref) == 0) {
+               if (rxrpc_to_client(sp) ||
+                   sp->hdr.type != RXRPC_PACKET_TYPE_DATA)
+                       goto bad_message;
+diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
+index 0cbbbbcf490e..38ea98ff426b 100644
+--- a/net/rxrpc/local_object.c
++++ b/net/rxrpc/local_object.c
+@@ -79,7 +79,7 @@ static struct rxrpc_local *rxrpc_alloc_local(struct rxrpc_net *rxnet,
+       local = kzalloc(sizeof(struct rxrpc_local), GFP_KERNEL);
+       if (local) {
+-              atomic_set(&local->usage, 1);
++              refcount_set(&local->ref, 1);
+               atomic_set(&local->active_users, 1);
+               local->rxnet = rxnet;
+               INIT_HLIST_NODE(&local->link);
+@@ -266,10 +266,10 @@ struct rxrpc_local *rxrpc_lookup_local(struct net *net,
+ struct rxrpc_local *rxrpc_get_local(struct rxrpc_local *local)
+ {
+       const void *here = __builtin_return_address(0);
+-      int n;
++      int r;
+-      n = atomic_inc_return(&local->usage);
+-      trace_rxrpc_local(local->debug_id, rxrpc_local_got, n, here);
++      __refcount_inc(&local->ref, &r);
++      trace_rxrpc_local(local->debug_id, rxrpc_local_got, r + 1, here);
+       return local;
+ }
+@@ -279,12 +279,12 @@ struct rxrpc_local *rxrpc_get_local(struct rxrpc_local *local)
+ struct rxrpc_local *rxrpc_get_local_maybe(struct rxrpc_local *local)
+ {
+       const void *here = __builtin_return_address(0);
++      int r;
+       if (local) {
+-              int n = atomic_fetch_add_unless(&local->usage, 1, 0);
+-              if (n > 0)
++              if (__refcount_inc_not_zero(&local->ref, &r))
+                       trace_rxrpc_local(local->debug_id, rxrpc_local_got,
+-                                        n + 1, here);
++                                        r + 1, here);
+               else
+                       local = NULL;
+       }
+@@ -298,10 +298,10 @@ void rxrpc_queue_local(struct rxrpc_local *local)
+ {
+       const void *here = __builtin_return_address(0);
+       unsigned int debug_id = local->debug_id;
+-      int n = atomic_read(&local->usage);
++      int r = refcount_read(&local->ref);
+       if (rxrpc_queue_work(&local->processor))
+-              trace_rxrpc_local(debug_id, rxrpc_local_queued, n, here);
++              trace_rxrpc_local(debug_id, rxrpc_local_queued, r + 1, here);
+       else
+               rxrpc_put_local(local);
+ }
+@@ -313,15 +313,16 @@ void rxrpc_put_local(struct rxrpc_local *local)
+ {
+       const void *here = __builtin_return_address(0);
+       unsigned int debug_id;
+-      int n;
++      bool dead;
++      int r;
+       if (local) {
+               debug_id = local->debug_id;
+-              n = atomic_dec_return(&local->usage);
+-              trace_rxrpc_local(debug_id, rxrpc_local_put, n, here);
++              dead = __refcount_dec_and_test(&local->ref, &r);
++              trace_rxrpc_local(debug_id, rxrpc_local_put, r, here);
+-              if (n == 0)
++              if (dead)
+                       call_rcu(&local->rcu, rxrpc_local_rcu);
+       }
+ }
+@@ -409,7 +410,7 @@ static void rxrpc_local_processor(struct work_struct *work)
+               return;
+       trace_rxrpc_local(local->debug_id, rxrpc_local_processing,
+-                        atomic_read(&local->usage), NULL);
++                        refcount_read(&local->ref), NULL);
+       do {
+               again = false;
+@@ -465,7 +466,7 @@ void rxrpc_destroy_all_locals(struct rxrpc_net *rxnet)
+               mutex_lock(&rxnet->local_mutex);
+               hlist_for_each_entry(local, &rxnet->local_endpoints, link) {
+                       pr_err("AF_RXRPC: Leaked local %p {%d}\n",
+-                             local, atomic_read(&local->usage));
++                             local, refcount_read(&local->ref));
+               }
+               mutex_unlock(&rxnet->local_mutex);
+               BUG();
+diff --git a/net/rxrpc/peer_object.c b/net/rxrpc/peer_object.c
+index 0298fe2ad6d3..26d2ae9baaf2 100644
+--- a/net/rxrpc/peer_object.c
++++ b/net/rxrpc/peer_object.c
+@@ -121,7 +121,7 @@ static struct rxrpc_peer *__rxrpc_lookup_peer_rcu(
+       hash_for_each_possible_rcu(rxnet->peer_hash, peer, hash_link, hash_key) {
+               if (rxrpc_peer_cmp_key(peer, local, srx, hash_key) == 0 &&
+-                  atomic_read(&peer->usage) > 0)
++                  refcount_read(&peer->ref) > 0)
+                       return peer;
+       }
+@@ -140,7 +140,7 @@ struct rxrpc_peer *rxrpc_lookup_peer_rcu(struct rxrpc_local *local,
+       peer = __rxrpc_lookup_peer_rcu(local, srx, hash_key);
+       if (peer) {
+               _net("PEER %d {%pISp}", peer->debug_id, &peer->srx.transport);
+-              _leave(" = %p {u=%d}", peer, atomic_read(&peer->usage));
++              _leave(" = %p {u=%d}", peer, refcount_read(&peer->ref));
+       }
+       return peer;
+ }
+@@ -216,7 +216,7 @@ struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *local, gfp_t gfp)
+       peer = kzalloc(sizeof(struct rxrpc_peer), gfp);
+       if (peer) {
+-              atomic_set(&peer->usage, 1);
++              refcount_set(&peer->ref, 1);
+               peer->local = rxrpc_get_local(local);
+               INIT_HLIST_HEAD(&peer->error_targets);
+               peer->service_conns = RB_ROOT;
+@@ -378,7 +378,7 @@ struct rxrpc_peer *rxrpc_lookup_peer(struct rxrpc_sock *rx,
+       _net("PEER %d {%pISp}", peer->debug_id, &peer->srx.transport);
+-      _leave(" = %p {u=%d}", peer, atomic_read(&peer->usage));
++      _leave(" = %p {u=%d}", peer, refcount_read(&peer->ref));
+       return peer;
+ }
+@@ -388,10 +388,10 @@ struct rxrpc_peer *rxrpc_lookup_peer(struct rxrpc_sock *rx,
+ struct rxrpc_peer *rxrpc_get_peer(struct rxrpc_peer *peer)
+ {
+       const void *here = __builtin_return_address(0);
+-      int n;
++      int r;
+-      n = atomic_inc_return(&peer->usage);
+-      trace_rxrpc_peer(peer->debug_id, rxrpc_peer_got, n, here);
++      __refcount_inc(&peer->ref, &r);
++      trace_rxrpc_peer(peer->debug_id, rxrpc_peer_got, r + 1, here);
+       return peer;
+ }
+@@ -401,11 +401,11 @@ struct rxrpc_peer *rxrpc_get_peer(struct rxrpc_peer *peer)
+ struct rxrpc_peer *rxrpc_get_peer_maybe(struct rxrpc_peer *peer)
+ {
+       const void *here = __builtin_return_address(0);
++      int r;
+       if (peer) {
+-              int n = atomic_fetch_add_unless(&peer->usage, 1, 0);
+-              if (n > 0)
+-                      trace_rxrpc_peer(peer->debug_id, rxrpc_peer_got, n + 1, here);
++              if (__refcount_inc_not_zero(&peer->ref, &r))
++                      trace_rxrpc_peer(peer->debug_id, rxrpc_peer_got, r + 1, here);
+               else
+                       peer = NULL;
+       }
+@@ -436,13 +436,14 @@ void rxrpc_put_peer(struct rxrpc_peer *peer)
+ {
+       const void *here = __builtin_return_address(0);
+       unsigned int debug_id;
+-      int n;
++      bool dead;
++      int r;
+       if (peer) {
+               debug_id = peer->debug_id;
+-              n = atomic_dec_return(&peer->usage);
+-              trace_rxrpc_peer(debug_id, rxrpc_peer_put, n, here);
+-              if (n == 0)
++              dead = __refcount_dec_and_test(&peer->ref, &r);
++              trace_rxrpc_peer(debug_id, rxrpc_peer_put, r - 1, here);
++              if (dead)
+                       __rxrpc_put_peer(peer);
+       }
+ }
+@@ -455,11 +456,12 @@ void rxrpc_put_peer_locked(struct rxrpc_peer *peer)
+ {
+       const void *here = __builtin_return_address(0);
+       unsigned int debug_id = peer->debug_id;
+-      int n;
++      bool dead;
++      int r;
+-      n = atomic_dec_return(&peer->usage);
+-      trace_rxrpc_peer(debug_id, rxrpc_peer_put, n, here);
+-      if (n == 0) {
++      dead = __refcount_dec_and_test(&peer->ref, &r);
++      trace_rxrpc_peer(debug_id, rxrpc_peer_put, r - 1, here);
++      if (dead) {
+               hash_del_rcu(&peer->hash_link);
+               list_del_init(&peer->keepalive_link);
+               rxrpc_free_peer(peer);
+@@ -481,7 +483,7 @@ void rxrpc_destroy_all_peers(struct rxrpc_net *rxnet)
+               hlist_for_each_entry(peer, &rxnet->peer_hash[i], hash_link) {
+                       pr_err("Leaked peer %u {%u} %pISp\n",
+                              peer->debug_id,
+-                             atomic_read(&peer->usage),
++                             refcount_read(&peer->ref),
+                              &peer->srx.transport);
+               }
+       }
+diff --git a/net/rxrpc/proc.c b/net/rxrpc/proc.c
+index 7d007a66eba5..245418943e01 100644
+--- a/net/rxrpc/proc.c
++++ b/net/rxrpc/proc.c
+@@ -101,7 +101,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
+                  call->cid,
+                  call->call_id,
+                  rxrpc_is_service_call(call) ? "Svc" : "Clt",
+-                 atomic_read(&call->usage),
++                 refcount_read(&call->ref),
+                  rxrpc_call_states[call->state],
+                  call->abort_code,
+                  call->debug_id,
+@@ -183,7 +183,7 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
+                  conn->service_id,
+                  conn->proto.cid,
+                  rxrpc_conn_is_service(conn) ? "Svc" : "Clt",
+-                 atomic_read(&conn->usage),
++                 refcount_read(&conn->ref),
+                  rxrpc_conn_states[conn->state],
+                  key_serial(conn->params.key),
+                  atomic_read(&conn->serial),
+@@ -233,7 +233,7 @@ static int rxrpc_peer_seq_show(struct seq_file *seq, void *v)
+                  " %3u %5u %6llus %8u %8u\n",
+                  lbuff,
+                  rbuff,
+-                 atomic_read(&peer->usage),
++                 refcount_read(&peer->ref),
+                  peer->cong_cwnd,
+                  peer->mtu,
+                  now - peer->last_tx_at,
+@@ -351,7 +351,7 @@ static int rxrpc_local_seq_show(struct seq_file *seq, void *v)
+       seq_printf(seq,
+                  "UDP   %-47.47s %3u %3u\n",
+                  lbuff,
+-                 atomic_read(&local->usage),
++                 refcount_read(&local->ref),
+                  atomic_read(&local->active_users));
+       return 0;
+diff --git a/net/rxrpc/skbuff.c b/net/rxrpc/skbuff.c
+index 0348d2bf6f7d..580a5acffee7 100644
+--- a/net/rxrpc/skbuff.c
++++ b/net/rxrpc/skbuff.c
+@@ -71,7 +71,6 @@ void rxrpc_free_skb(struct sk_buff *skb, enum rxrpc_skb_trace op)
+       const void *here = __builtin_return_address(0);
+       if (skb) {
+               int n;
+-              CHECK_SLAB_OKAY(&skb->users);
+               n = atomic_dec_return(select_skb_count(skb));
+               trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n,
+                               rxrpc_skb(skb)->rx_flags, here);
+-- 
+2.35.1
+
diff --git a/queue-5.15/s390-crashdump-fix-tod-programmable-field-size.patch b/queue-5.15/s390-crashdump-fix-tod-programmable-field-size.patch
new file mode 100644 (file)
index 0000000..8d68250
--- /dev/null
@@ -0,0 +1,61 @@
+From 2a5bfbc1f57cc735571a635a409f4b2c5de762ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 13:05:39 +0100
+Subject: s390/crashdump: fix TOD programmable field size
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Heiko Carstens <hca@linux.ibm.com>
+
+[ Upstream commit f44e07a8afdd713ddc1a8832c39372fe5dd86895 ]
+
+The size of the TOD programmable field was incorrectly increased from
+four to eight bytes with commit 1a2c5840acf9 ("s390/dump: cleanup CPU
+save area handling").
+This leads to an elf notes section NT_S390_TODPREG which has a size of
+eight instead of four bytes in case of kdump, however even worse is
+that the contents is incorrect: it is supposed to contain only the
+contents of the TOD programmable field, but in fact contains a mix of
+the TOD programmable field (32 bit upper bits) and parts of the CPU
+timer register (lower 32 bits).
+
+Fix this by simply changing the size of the todpreg field within the
+save area structure. This will implicitly also fix the size of the
+corresponding elf notes sections.
+
+This also gets rid of this compile time warning:
+
+in function â€˜fortify_memcpy_chk’,
+    inlined from â€˜save_area_add_regs’ at arch/s390/kernel/crash_dump.c:99:2:
+./include/linux/fortify-string.h:413:25: error: call to â€˜__read_overflow2_field’
+   declared with attribute warning: detected read beyond size of field
+   (2nd parameter); maybe use struct_group()? [-Werror=attribute-warning]
+  413 |                         __read_overflow2_field(q_size_field, size);
+      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Fixes: 1a2c5840acf9 ("s390/dump: cleanup CPU save area handling")
+Reviewed-by: Christian Borntraeger <borntraeger@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/crash_dump.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
+index f17ad2daab07..8722bd07c607 100644
+--- a/arch/s390/kernel/crash_dump.c
++++ b/arch/s390/kernel/crash_dump.c
+@@ -44,7 +44,7 @@ struct save_area {
+       u64 fprs[16];
+       u32 fpc;
+       u32 prefix;
+-      u64 todpreg;
++      u32 todpreg;
+       u64 timer;
+       u64 todcmp;
+       u64 vxrs_low[16];
+-- 
+2.35.1
+
diff --git a/queue-5.15/s390-dasd-fix-no-record-found-for-raw_track_access.patch b/queue-5.15/s390-dasd-fix-no-record-found-for-raw_track_access.patch
new file mode 100644 (file)
index 0000000..7163e5b
--- /dev/null
@@ -0,0 +1,75 @@
+From a6b30514704c966d0335f42c8b89413b556f051b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 17:07:18 +0100
+Subject: s390/dasd: fix no record found for raw_track_access
+
+From: Stefan Haberland <sth@linux.ibm.com>
+
+[ Upstream commit 590ce6d96d6a224b470a3862c33a483d5022bfdb ]
+
+For DASD devices in raw_track_access mode only full track images are
+read and written.
+For this purpose it is not necessary to do search operation in the
+locate record extended function. The documentation even states that
+this might fail if the searched record is not found on a track.
+
+Currently the driver sets a value of 1 in the search field for the first
+record after record zero. This is the default for disks not in
+raw_track_access mode but record 1 might be missing on a completely
+empty track.
+
+There has not been any problem with this on IBM storage servers but it
+might lead to errors with DASD devices on other vendors storage servers.
+
+Fix this by setting the search field to 0. Record zero is always available
+even on a completely empty track.
+
+Fixes: e4dbb0f2b5dd ("[S390] dasd: Add support for raw ECKD access.")
+Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
+Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
+Link: https://lore.kernel.org/r/20221123160719.3002694-4-sth@linux.ibm.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/block/dasd_eckd.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
+index ff7b7d470e96..57dfc92aa756 100644
+--- a/drivers/s390/block/dasd_eckd.c
++++ b/drivers/s390/block/dasd_eckd.c
+@@ -4696,7 +4696,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
+       struct dasd_device *basedev;
+       struct req_iterator iter;
+       struct dasd_ccw_req *cqr;
+-      unsigned int first_offs;
+       unsigned int trkcount;
+       unsigned long *idaws;
+       unsigned int size;
+@@ -4730,7 +4729,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
+       last_trk = (blk_rq_pos(req) + blk_rq_sectors(req) - 1) /
+               DASD_RAW_SECTORS_PER_TRACK;
+       trkcount = last_trk - first_trk + 1;
+-      first_offs = 0;
+       if (rq_data_dir(req) == READ)
+               cmd = DASD_ECKD_CCW_READ_TRACK;
+@@ -4774,13 +4772,13 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
+       if (use_prefix) {
+               prefix_LRE(ccw++, data, first_trk, last_trk, cmd, basedev,
+-                         startdev, 1, first_offs + 1, trkcount, 0, 0);
++                         startdev, 1, 0, trkcount, 0, 0);
+       } else {
+               define_extent(ccw++, data, first_trk, last_trk, cmd, basedev, 0);
+               ccw[-1].flags |= CCW_FLAG_CC;
+               data += sizeof(struct DE_eckd_data);
+-              locate_record_ext(ccw++, data, first_trk, first_offs + 1,
++              locate_record_ext(ccw++, data, first_trk, 0,
+                                 trkcount, cmd, basedev, 0, 0);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-storvsc-fix-handling-of-srb_status-and-capacity.patch b/queue-5.15/scsi-storvsc-fix-handling-of-srb_status-and-capacity.patch
new file mode 100644 (file)
index 0000000..745d487
--- /dev/null
@@ -0,0 +1,148 @@
+From 7da41f2dd3fe0029c0a6411c8fe63390be4b92f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 10:48:42 -0800
+Subject: scsi: storvsc: Fix handling of srb_status and capacity change events
+
+From: Michael Kelley <mikelley@microsoft.com>
+
+[ Upstream commit b8a5376c321b4669f7ffabc708fd30c3970f3084 ]
+
+Current handling of the srb_status is incorrect. Commit 52e1b3b3daa9
+("scsi: storvsc: Correctly handle multiple flags in srb_status")
+is based on srb_status being a set of flags, when in fact only the
+2 high order bits are flags and the remaining 6 bits are an integer
+status. Because the integer values of interest mostly look like flags,
+the code actually works when treated that way.
+
+But in the interest of correctness going forward, fix this by treating
+the low 6 bits of srb_status as an integer status code. Add handling
+for SRB_STATUS_INVALID_REQUEST, which was the original intent of commit
+52e1b3b3daa9. Furthermore, treat the ERROR, ABORTED, and INVALID_REQUEST
+srb status codes as essentially equivalent for the cases we care about.
+There's no harm in doing so, and it isn't always clear which status code
+current or older versions of Hyper-V report for particular conditions.
+
+Treating the srb status codes as equivalent has the additional benefit
+of ensuring that capacity change events result in an immediate rescan
+so that the new size is known to Linux. Existing code checks SCSI
+sense data for capacity change events when the srb status is ABORTED.
+But capacity change events are also being observed when Hyper-V reports
+the srb status as ERROR. Without the immediate rescan, the new size
+isn't known until something else causes a rescan (such as running
+fdisk to expand a partition), and in the meantime, tools such as "lsblk"
+continue to report the old size.
+
+Fixes: 52e1b3b3daa9 ("scsi: storvsc: Correctly handle multiple flags in srb_status")
+Reported-by: Juan Tian <juantian@microsoft.com>
+Signed-off-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/1668019722-1983-1-git-send-email-mikelley@microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/storvsc_drv.c | 69 +++++++++++++++++++-------------------
+ 1 file changed, 34 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
+index 3d03e1ca5820..6110dfd903f7 100644
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -344,16 +344,21 @@ enum storvsc_request_type {
+ };
+ /*
+- * SRB status codes and masks; a subset of the codes used here.
++ * SRB status codes and masks. In the 8-bit field, the two high order bits
++ * are flags, while the remaining 6 bits are an integer status code.  The
++ * definitions here include only the subset of the integer status codes that
++ * are tested for in this driver.
+  */
+-
+ #define SRB_STATUS_AUTOSENSE_VALID    0x80
+ #define SRB_STATUS_QUEUE_FROZEN               0x40
+-#define SRB_STATUS_INVALID_LUN        0x20
+-#define SRB_STATUS_SUCCESS    0x01
+-#define SRB_STATUS_ABORTED    0x02
+-#define SRB_STATUS_ERROR      0x04
+-#define SRB_STATUS_DATA_OVERRUN       0x12
++
++/* SRB status integer codes */
++#define SRB_STATUS_SUCCESS            0x01
++#define SRB_STATUS_ABORTED            0x02
++#define SRB_STATUS_ERROR              0x04
++#define SRB_STATUS_INVALID_REQUEST    0x06
++#define SRB_STATUS_DATA_OVERRUN               0x12
++#define SRB_STATUS_INVALID_LUN                0x20
+ #define SRB_STATUS(status) \
+       (status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
+@@ -1032,38 +1037,25 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
+       void (*process_err_fn)(struct work_struct *work);
+       struct hv_host_device *host_dev = shost_priv(host);
+-      /*
+-       * In some situations, Hyper-V sets multiple bits in the
+-       * srb_status, such as ABORTED and ERROR. So process them
+-       * individually, with the most specific bits first.
+-       */
+-
+-      if (vm_srb->srb_status & SRB_STATUS_INVALID_LUN) {
+-              set_host_byte(scmnd, DID_NO_CONNECT);
+-              process_err_fn = storvsc_remove_lun;
+-              goto do_work;
+-      }
++      switch (SRB_STATUS(vm_srb->srb_status)) {
++      case SRB_STATUS_ERROR:
++      case SRB_STATUS_ABORTED:
++      case SRB_STATUS_INVALID_REQUEST:
++              if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID) {
++                      /* Check for capacity change */
++                      if ((asc == 0x2a) && (ascq == 0x9)) {
++                              process_err_fn = storvsc_device_scan;
++                              /* Retry the I/O that triggered this. */
++                              set_host_byte(scmnd, DID_REQUEUE);
++                              goto do_work;
++                      }
+-      if (vm_srb->srb_status & SRB_STATUS_ABORTED) {
+-              if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID &&
+-                  /* Capacity data has changed */
+-                  (asc == 0x2a) && (ascq == 0x9)) {
+-                      process_err_fn = storvsc_device_scan;
+                       /*
+-                       * Retry the I/O that triggered this.
++                       * Otherwise, let upper layer deal with the
++                       * error when sense message is present
+                        */
+-                      set_host_byte(scmnd, DID_REQUEUE);
+-                      goto do_work;
+-              }
+-      }
+-
+-      if (vm_srb->srb_status & SRB_STATUS_ERROR) {
+-              /*
+-               * Let upper layer deal with error when
+-               * sense message is present.
+-               */
+-              if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID)
+                       return;
++              }
+               /*
+                * If there is an error; offline the device since all
+@@ -1086,6 +1078,13 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
+               default:
+                       set_host_byte(scmnd, DID_ERROR);
+               }
++              return;
++
++      case SRB_STATUS_INVALID_LUN:
++              set_host_byte(scmnd, DID_NO_CONNECT);
++              process_err_fn = storvsc_remove_lun;
++              goto do_work;
++
+       }
+       return;
+-- 
+2.35.1
+
diff --git a/queue-5.15/selftests-mptcp-fix-mibit-vs-mbit-mix-up.patch b/queue-5.15/selftests-mptcp-fix-mibit-vs-mbit-mix-up.patch
new file mode 100644 (file)
index 0000000..c158903
--- /dev/null
@@ -0,0 +1,52 @@
+From c5c85137406754ef5dc63dc0d4f884bd4607d443 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 14:10:46 -0800
+Subject: selftests: mptcp: fix mibit vs mbit mix up
+
+From: Matthieu Baerts <matthieu.baerts@tessares.net>
+
+[ Upstream commit 3de88b95c4d436d78afc0266a0bed76c35ddeb62 ]
+
+The estimated time was supposing the rate was expressed in mibit
+(bit * 1024^2) but it is in mbit (bit * 1000^2).
+
+This makes the threshold higher but in a more realistic way to avoid
+false positives reported by CI instances.
+
+Before this patch, the thresholds were at 7561/4005ms and now they are
+at 7906/4178ms.
+
+While at it, also fix a typo in the linked comment, spotted by Mat.
+
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/310
+Fixes: 1a418cb8e888 ("mptcp: simult flow self-tests")
+Suggested-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/mptcp/simult_flows.sh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh
+index f441ff7904fc..7df4900dfaf7 100755
+--- a/tools/testing/selftests/net/mptcp/simult_flows.sh
++++ b/tools/testing/selftests/net/mptcp/simult_flows.sh
+@@ -235,9 +235,10 @@ run_test()
+       tc -n $ns2 qdisc add dev ns2eth1 root netem rate ${rate1}mbit $delay1
+       tc -n $ns2 qdisc add dev ns2eth2 root netem rate ${rate2}mbit $delay2
+-      # time is measured in ms, account for transfer size, affegated link speed
++      # time is measured in ms, account for transfer size, aggregated link speed
+       # and header overhead (10%)
+-      local time=$((size * 8 * 1000 * 10 / (( $rate1 + $rate2) * 1024 *1024 * 9) ))
++      #              ms    byte -> bit   10%        mbit      -> kbit -> bit  10%
++      local time=$((1000 * size  *  8  * 10 / ((rate1 + rate2) * 1000 * 1000 * 9) ))
+       # mptcp_connect will do some sleeps to allow the mp_join handshake
+       # completion (see mptcp_connect): 200ms on each side, add some slack
+-- 
+2.35.1
+
diff --git a/queue-5.15/selftests-mptcp-more-stable-simult_flows-tests.patch b/queue-5.15/selftests-mptcp-more-stable-simult_flows-tests.patch
new file mode 100644 (file)
index 0000000..81b2ba1
--- /dev/null
@@ -0,0 +1,325 @@
+From efb651ce6f2679cae1fe3c98ac5ec267e1218779 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Oct 2021 16:55:59 -0700
+Subject: selftests: mptcp: more stable simult_flows tests
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit b6ab64b074f29b42ff272793806efc913f7cc742 ]
+
+Currently the simult_flows.sh self-tests are not very stable,
+especially when running on slow VMs.
+
+The tests measure runtime for transfers on multiple subflows
+and check that the time is near the theoretical maximum.
+
+The current test infra introduces a bit of jitter in test
+runtime, due to multiple explicit delays. Additionally the
+runtime is measured by the shell script wrapper. On a slow
+VM, the script overhead is measurable and subject to relevant
+jitter.
+
+One solution to make the test more stable would be adding more
+slack to the expected time; that could possibly hide real
+regressions. Instead move the measurement inside the command
+doing the transfer, and drop most unneeded sleeps.
+
+Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 3de88b95c4d4 ("selftests: mptcp: fix mibit vs mbit mix up")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/net/mptcp/mptcp_connect.c       | 72 +++++++++++++++----
+ .../selftests/net/mptcp/simult_flows.sh       | 36 ++++------
+ 2 files changed, 72 insertions(+), 36 deletions(-)
+
+diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
+index 89c4753c2760..95e81d557b08 100644
+--- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
++++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
+@@ -14,6 +14,7 @@
+ #include <strings.h>
+ #include <signal.h>
+ #include <unistd.h>
++#include <time.h>
+ #include <sys/poll.h>
+ #include <sys/sendfile.h>
+@@ -64,6 +65,7 @@ static int cfg_sndbuf;
+ static int cfg_rcvbuf;
+ static bool cfg_join;
+ static bool cfg_remove;
++static unsigned int cfg_time;
+ static unsigned int cfg_do_w;
+ static int cfg_wait;
+ static uint32_t cfg_mark;
+@@ -78,9 +80,10 @@ static struct cfg_cmsg_types cfg_cmsg_types;
+ static void die_usage(void)
+ {
+       fprintf(stderr, "Usage: mptcp_connect [-6] [-u] [-s MPTCP|TCP] [-p port] [-m mode]"
+-              "[-l] [-w sec] connect_address\n");
++              "[-l] [-w sec] [-t num] [-T num] connect_address\n");
+       fprintf(stderr, "\t-6 use ipv6\n");
+       fprintf(stderr, "\t-t num -- set poll timeout to num\n");
++      fprintf(stderr, "\t-T num -- set expected runtime to num ms\n");
+       fprintf(stderr, "\t-S num -- set SO_SNDBUF to num\n");
+       fprintf(stderr, "\t-R num -- set SO_RCVBUF to num\n");
+       fprintf(stderr, "\t-p num -- use port num\n");
+@@ -448,7 +451,7 @@ static void set_nonblock(int fd)
+       fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+ }
+-static int copyfd_io_poll(int infd, int peerfd, int outfd)
++static int copyfd_io_poll(int infd, int peerfd, int outfd, bool *in_closed_after_out)
+ {
+       struct pollfd fds = {
+               .fd = peerfd,
+@@ -487,9 +490,11 @@ static int copyfd_io_poll(int infd, int peerfd, int outfd)
+                                */
+                               fds.events &= ~POLLIN;
+-                              if ((fds.events & POLLOUT) == 0)
++                              if ((fds.events & POLLOUT) == 0) {
++                                      *in_closed_after_out = true;
+                                       /* and nothing more to send */
+                                       break;
++                              }
+                       /* Else, still have data to transmit */
+                       } else if (len < 0) {
+@@ -547,7 +552,7 @@ static int copyfd_io_poll(int infd, int peerfd, int outfd)
+       }
+       /* leave some time for late join/announce */
+-      if (cfg_join || cfg_remove)
++      if (cfg_remove)
+               usleep(cfg_wait);
+       close(peerfd);
+@@ -646,7 +651,7 @@ static int do_sendfile(int infd, int outfd, unsigned int count)
+ }
+ static int copyfd_io_mmap(int infd, int peerfd, int outfd,
+-                        unsigned int size)
++                        unsigned int size, bool *in_closed_after_out)
+ {
+       int err;
+@@ -664,13 +669,14 @@ static int copyfd_io_mmap(int infd, int peerfd, int outfd,
+               shutdown(peerfd, SHUT_WR);
+               err = do_recvfile(peerfd, outfd);
++              *in_closed_after_out = true;
+       }
+       return err;
+ }
+ static int copyfd_io_sendfile(int infd, int peerfd, int outfd,
+-                            unsigned int size)
++                            unsigned int size, bool *in_closed_after_out)
+ {
+       int err;
+@@ -685,6 +691,7 @@ static int copyfd_io_sendfile(int infd, int peerfd, int outfd,
+               if (err)
+                       return err;
+               err = do_recvfile(peerfd, outfd);
++              *in_closed_after_out = true;
+       }
+       return err;
+@@ -692,27 +699,62 @@ static int copyfd_io_sendfile(int infd, int peerfd, int outfd,
+ static int copyfd_io(int infd, int peerfd, int outfd)
+ {
++      bool in_closed_after_out = false;
++      struct timespec start, end;
+       int file_size;
++      int ret;
++
++      if (cfg_time && (clock_gettime(CLOCK_MONOTONIC, &start) < 0))
++              xerror("can not fetch start time %d", errno);
+       switch (cfg_mode) {
+       case CFG_MODE_POLL:
+-              return copyfd_io_poll(infd, peerfd, outfd);
++              ret = copyfd_io_poll(infd, peerfd, outfd, &in_closed_after_out);
++              break;
++
+       case CFG_MODE_MMAP:
+               file_size = get_infd_size(infd);
+               if (file_size < 0)
+                       return file_size;
+-              return copyfd_io_mmap(infd, peerfd, outfd, file_size);
++              ret = copyfd_io_mmap(infd, peerfd, outfd, file_size, &in_closed_after_out);
++              break;
++
+       case CFG_MODE_SENDFILE:
+               file_size = get_infd_size(infd);
+               if (file_size < 0)
+                       return file_size;
+-              return copyfd_io_sendfile(infd, peerfd, outfd, file_size);
++              ret = copyfd_io_sendfile(infd, peerfd, outfd, file_size, &in_closed_after_out);
++              break;
++
++      default:
++              fprintf(stderr, "Invalid mode %d\n", cfg_mode);
++
++              die_usage();
++              return 1;
+       }
+-      fprintf(stderr, "Invalid mode %d\n", cfg_mode);
++      if (ret)
++              return ret;
+-      die_usage();
+-      return 1;
++      if (cfg_time) {
++              unsigned int delta_ms;
++
++              if (clock_gettime(CLOCK_MONOTONIC, &end) < 0)
++                      xerror("can not fetch end time %d", errno);
++              delta_ms = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000;
++              if (delta_ms > cfg_time) {
++                      xerror("transfer slower than expected! runtime %d ms, expected %d ms",
++                             delta_ms, cfg_time);
++              }
++
++              /* show the runtime only if this end shutdown(wr) before receiving the EOF,
++               * (that is, if this end got the longer runtime)
++               */
++              if (in_closed_after_out)
++                      fprintf(stderr, "%d", delta_ms);
++      }
++
++      return 0;
+ }
+ static void check_sockaddr(int pf, struct sockaddr_storage *ss,
+@@ -1005,12 +1047,11 @@ static void parse_opts(int argc, char **argv)
+ {
+       int c;
+-      while ((c = getopt(argc, argv, "6jr:lp:s:hut:m:S:R:w:M:P:c:")) != -1) {
++      while ((c = getopt(argc, argv, "6jr:lp:s:hut:T:m:S:R:w:M:P:c:")) != -1) {
+               switch (c) {
+               case 'j':
+                       cfg_join = true;
+                       cfg_mode = CFG_MODE_POLL;
+-                      cfg_wait = 400000;
+                       break;
+               case 'r':
+                       cfg_remove = true;
+@@ -1043,6 +1084,9 @@ static void parse_opts(int argc, char **argv)
+                       if (poll_timeout <= 0)
+                               poll_timeout = -1;
+                       break;
++              case 'T':
++                      cfg_time = atoi(optarg);
++                      break;
+               case 'm':
+                       cfg_mode = parse_mode(optarg);
+                       break;
+diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh
+index 910d8126af8f..f441ff7904fc 100755
+--- a/tools/testing/selftests/net/mptcp/simult_flows.sh
++++ b/tools/testing/selftests/net/mptcp/simult_flows.sh
+@@ -51,7 +51,7 @@ setup()
+       sout=$(mktemp)
+       cout=$(mktemp)
+       capout=$(mktemp)
+-      size=$((2048 * 4096))
++      size=$((2 * 2048 * 4096))
+       dd if=/dev/zero of=$small bs=4096 count=20 >/dev/null 2>&1
+       dd if=/dev/zero of=$large bs=4096 count=$((size / 4096)) >/dev/null 2>&1
+@@ -161,17 +161,15 @@ do_transfer()
+       timeout ${timeout_test} \
+               ip netns exec ${ns3} \
+-                      ./mptcp_connect -jt ${timeout_poll} -l -p $port \
++                      ./mptcp_connect -jt ${timeout_poll} -l -p $port -T $time \
+                               0.0.0.0 < "$sin" > "$sout" &
+       local spid=$!
+       wait_local_port_listen "${ns3}" "${port}"
+-      local start
+-      start=$(date +%s%3N)
+       timeout ${timeout_test} \
+               ip netns exec ${ns1} \
+-                      ./mptcp_connect -jt ${timeout_poll} -p $port \
++                      ./mptcp_connect -jt ${timeout_poll} -p $port -T $time \
+                               10.0.3.3 < "$cin" > "$cout" &
+       local cpid=$!
+@@ -180,27 +178,20 @@ do_transfer()
+       wait $spid
+       local rets=$?
+-      local stop
+-      stop=$(date +%s%3N)
+-
+       if $capture; then
+               sleep 1
+               kill ${cappid_listener}
+               kill ${cappid_connector}
+       fi
+-      local duration
+-      duration=$((stop-start))
+-
+       cmp $sin $cout > /dev/null 2>&1
+       local cmps=$?
+       cmp $cin $sout > /dev/null 2>&1
+       local cmpc=$?
+-      printf "%16s" "$duration max $max_time "
++      printf "%-16s" " max $max_time "
+       if [ $retc -eq 0 ] && [ $rets -eq 0 ] && \
+-         [ $cmpc -eq 0 ] && [ $cmps -eq 0 ] && \
+-         [ $duration -lt $max_time ]; then
++         [ $cmpc -eq 0 ] && [ $cmps -eq 0 ]; then
+               echo "[ OK ]"
+               cat "$capout"
+               return 0
+@@ -244,23 +235,24 @@ run_test()
+       tc -n $ns2 qdisc add dev ns2eth1 root netem rate ${rate1}mbit $delay1
+       tc -n $ns2 qdisc add dev ns2eth2 root netem rate ${rate2}mbit $delay2
+-      # time is measure in ms
+-      local time=$((size * 8 * 1000 / (( $rate1 + $rate2) * 1024 *1024) ))
++      # time is measured in ms, account for transfer size, affegated link speed
++      # and header overhead (10%)
++      local time=$((size * 8 * 1000 * 10 / (( $rate1 + $rate2) * 1024 *1024 * 9) ))
+       # mptcp_connect will do some sleeps to allow the mp_join handshake
+-      # completion
+-      time=$((time + 1350))
++      # completion (see mptcp_connect): 200ms on each side, add some slack
++      time=$((time + 450))
+-      printf "%-50s" "$msg"
+-      do_transfer $small $large $((time * 11 / 10))
++      printf "%-60s" "$msg"
++      do_transfer $small $large $time
+       lret=$?
+       if [ $lret -ne 0 ]; then
+               ret=$lret
+               [ $bail -eq 0 ] || exit $ret
+       fi
+-      printf "%-50s" "$msg - reverse direction"
+-      do_transfer $large $small $((time * 11 / 10))
++      printf "%-60s" "$msg - reverse direction"
++      do_transfer $large $small $time
+       lret=$?
+       if [ $lret -ne 0 ]; then
+               ret=$lret
+-- 
+2.35.1
+
index cf245bc364a9cf1d49267c97a0ab017262b47c7d..1ebee440fcf03277f7a510b5f43fe1362fc77a0e 100644 (file)
@@ -52,3 +52,82 @@ revert-drm-amdgpu-revert-drm-amdgpu-getting-fan-spee.patch
 alsa-usb-audio-add-quirk-to-fix-hamedal-c20-disconne.patch
 risc-v-vdso-do-not-add-missing-symbols-to-version-se.patch
 mips-pic32-treat-port-as-signed-integer.patch
+xfrm-fix-disable_policy-on-ipv4-early-demux.patch
+xfrm-replay-fix-esn-wrap-around-for-gso.patch
+af_key-fix-send_acquire-race-with-pfkey_register.patch
+arm-dts-am335x-pcm-953-define-fixed-regulators-in-ro.patch
+asoc-hdac_hda-fix-hda-pcm-buffer-overflow-issue.patch
+asoc-sgtl5000-reset-the-chip_clk_ctrl-reg-on-remove.patch
+asoc-soc-pcm-don-t-zero-tdm-masks-in-__soc_pcm_open.patch
+x86-hyperv-restore-vp-assist-page-after-cpu-offlinin.patch
+scsi-storvsc-fix-handling-of-srb_status-and-capacity.patch
+asoc-max98373-add-checks-for-devm_kcalloc.patch
+regulator-core-fix-kobject-release-warning-and-memor.patch
+spi-dw-dma-decrease-reference-count-in-dw_spi_dma_in.patch
+regulator-core-fix-uaf-in-destroy_regulator.patch
+bus-sunxi-rsb-remove-the-shutdown-callback.patch
+bus-sunxi-rsb-support-atomic-transfers.patch
+tee-optee-fix-possible-memory-leak-in-optee_register.patch
+arm-dts-at91-sam9g20ek-enable-udc-vbus-gpio-pinctrl.patch
+selftests-mptcp-more-stable-simult_flows-tests.patch
+selftests-mptcp-fix-mibit-vs-mbit-mix-up.patch
+net-liquidio-simplify-if-expression.patch
+rxrpc-allow-list-of-in-use-local-udp-endpoints-to-be.patch
+rxrpc-use-refcount_t-rather-than-atomic_t.patch
+rxrpc-fix-race-between-conn-bundle-lookup-and-bundle.patch
+net-dsa-sja1105-disallow-c45-transactions-on-the-bas.patch
+nfc-nci-fix-race-with-opening-and-closing.patch
+net-pch_gbe-fix-potential-memleak-in-pch_gbe_tx_queu.patch
+9p-fd-fix-issue-of-list_del-corruption-in-p9_fd_canc.patch
+netfilter-conntrack-fix-data-races-around-ct-mark.patch
+netfilter-nf_tables-do-not-set-up-extensions-for-end.patch
+iavf-fix-a-crash-during-reset-task.patch
+iavf-do-not-restart-tx-queues-after-reset-task-failu.patch
+iavf-fix-race-condition-between-iavf_shutdown-and-ia.patch
+arm-mxs-fix-memory-leak-in-mxs_machine_init.patch
+arm-dts-imx6q-prti6q-fix-ref-tcxo-clock-frequency-pr.patch
+net-ethernet-mtk_eth_soc-fix-error-handling-in-mtk_o.patch
+net-mlx4-check-retval-of-mlx4_bitmap_init.patch
+net-mvpp2-fix-possible-invalid-pointer-dereference.patch
+net-qla3xxx-fix-potential-memleak-in-ql3xxx_send.patch
+octeontx2-af-debugsfs-fix-pci-device-refcount-leak.patch
+net-pch_gbe-fix-pci-device-refcount-leak-while-modul.patch
+nfp-fill-splittable-of-devlink_port_attrs-correctly.patch
+nfp-add-port-from-netdev-validation-for-eeprom-acces.patch
+macsec-fix-invalid-error-code-set.patch
+drivers-hv-vmbus-fix-double-free-in-the-error-path-o.patch
+drivers-hv-vmbus-fix-possible-memory-leak-in-vmbus_d.patch
+netfilter-ipset-regression-in-ip_set_hash_ip.c.patch
+net-mlx5-do-not-query-pci-info-while-pci-disabled.patch
+net-mlx5-fix-fw-tracer-timestamp-calculation.patch
+net-mlx5-fix-handling-of-entry-refcount-when-command.patch
+tipc-set-con-sock-in-tipc_conn_alloc.patch
+tipc-add-an-extra-conn_get-in-tipc_conn_alloc.patch
+tipc-check-skb_linearize-return-value-in-tipc_disc_r.patch
+xfrm-fix-oops-in-__xfrm_state_delete.patch
+xfrm-fix-ignored-return-value-in-xfrm6_init.patch
+net-wwan-iosm-use-acpi_free-but-not-kfree-in-ipc_pci.patch
+sfc-fix-potential-memleak-in-__ef100_hard_start_xmit.patch
+net-sparx5-fix-error-handling-in-sparx5_port_open.patch
+net-sched-allow-act_ct-to-be-built-without-nf_nat.patch
+nfc-nci-fix-memory-leak-in-nci_rx_data_packet.patch
+regulator-twl6030-re-add-twl6032_subclass.patch
+bnx2x-fix-pci-device-refcount-leak-in-bnx2x_vf_is_pc.patch
+dma-buf-fix-racing-conflict-of-dma_heap_add.patch
+netfilter-ipset-restore-allowing-64-clashing-element.patch
+netfilter-flowtable_offload-add-missing-locking.patch
+fs-do-not-update-freeing-inode-i_io_list.patch
+dccp-tcp-reset-saddr-on-failure-after-inet6-_hash_co.patch
+ipv4-fix-error-return-code-in-fib_table_insert.patch
+arcnet-fix-potential-memory-leak-in-com20020_probe.patch
+s390-dasd-fix-no-record-found-for-raw_track_access.patch
+nfc-st-nci-fix-incorrect-validating-logic-in-evt_tra.patch
+nfc-st-nci-fix-memory-leaks-in-evt_transaction.patch
+nfc-st-nci-fix-incorrect-sizing-calculations-in-evt_.patch
+net-enetc-manage-enetc_f_qbv-in-priv-active_offloads.patch
+net-enetc-cache-accesses-to-priv-si-hw.patch
+net-enetc-preserve-tx-ring-priority-across-reconfigu.patch
+octeontx2-pf-add-check-for-devm_kcalloc.patch
+octeontx2-af-fix-reference-count-issue-in-rvu_sdp_in.patch
+net-thunderx-fix-the-acpi-memory-leak.patch
+s390-crashdump-fix-tod-programmable-field-size.patch
diff --git a/queue-5.15/sfc-fix-potential-memleak-in-__ef100_hard_start_xmit.patch b/queue-5.15/sfc-fix-potential-memleak-in-__ef100_hard_start_xmit.patch
new file mode 100644 (file)
index 0000000..d1735f7
--- /dev/null
@@ -0,0 +1,38 @@
+From 941b61821495965348d512b8a4289c391b3a234b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 15:50:09 +0800
+Subject: sfc: fix potential memleak in __ef100_hard_start_xmit()
+
+From: Zhang Changzhong <zhangchangzhong@huawei.com>
+
+[ Upstream commit aad98abd5cb8133507f22654f56bcb443aaa2d89 ]
+
+The __ef100_hard_start_xmit() returns NETDEV_TX_OK without freeing skb
+in error handling case, add dev_kfree_skb_any() to fix it.
+
+Fixes: 51b35a454efd ("sfc: skeleton EF100 PF driver")
+Signed-off-by: Zhang Changzhong <zhangchangzhong@huawei.com>
+Acked-by: Martin Habets <habetsm.xilinx@gmail.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Link: https://lore.kernel.org/r/1668671409-10909-1-git-send-email-zhangchangzhong@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/sfc/ef100_netdev.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c
+index 67fe44db6b61..63a44ee763be 100644
+--- a/drivers/net/ethernet/sfc/ef100_netdev.c
++++ b/drivers/net/ethernet/sfc/ef100_netdev.c
+@@ -200,6 +200,7 @@ static netdev_tx_t ef100_hard_start_xmit(struct sk_buff *skb,
+                  skb->len, skb->data_len, channel->channel);
+       if (!efx->n_channels || !efx->n_tx_channels || !channel) {
+               netif_stop_queue(net_dev);
++              dev_kfree_skb_any(skb);
+               goto err;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/spi-dw-dma-decrease-reference-count-in-dw_spi_dma_in.patch b/queue-5.15/spi-dw-dma-decrease-reference-count-in-dw_spi_dma_in.patch
new file mode 100644 (file)
index 0000000..1c5cfcb
--- /dev/null
@@ -0,0 +1,47 @@
+From bcfca3135a1642496a31e9dfd7c4b8b01c10459f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 17:32:04 +0800
+Subject: spi: dw-dma: decrease reference count in dw_spi_dma_init_mfld()
+
+From: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+
+[ Upstream commit 804313b64e412a81b0b3389a10e7622452004aa6 ]
+
+pci_get_device() will increase the reference count for the returned
+pci_dev. Since 'dma_dev' is only used to filter the channel in
+dw_spi_dma_chan_filer() after using it we need to call pci_dev_put() to
+decrease the reference count. Also add pci_dev_put() for the error case.
+
+Fixes: 7063c0d942a1 ("spi/dw_spi: add DMA support")
+Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
+Acked-by: Serge Semin <fancer.lancer@gmail.com>
+Link: https://lore.kernel.org/r/20221116093204.46700-1-wangxiongfeng2@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-dw-dma.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c
+index a09831c62192..32ac8f9068e8 100644
+--- a/drivers/spi/spi-dw-dma.c
++++ b/drivers/spi/spi-dw-dma.c
+@@ -127,12 +127,15 @@ static int dw_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
+       dw_spi_dma_sg_burst_init(dws);
++      pci_dev_put(dma_dev);
++
+       return 0;
+ free_rxchan:
+       dma_release_channel(dws->rxchan);
+       dws->rxchan = NULL;
+ err_exit:
++      pci_dev_put(dma_dev);
+       return -EBUSY;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/tee-optee-fix-possible-memory-leak-in-optee_register.patch b/queue-5.15/tee-optee-fix-possible-memory-leak-in-optee_register.patch
new file mode 100644 (file)
index 0000000..f058511
--- /dev/null
@@ -0,0 +1,41 @@
+From 24d4421c33a61571f1fb5225436e6ac5ee32448d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 22:01:24 +0800
+Subject: tee: optee: fix possible memory leak in optee_register_device()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit cce616e012c215d65c15e5d1afa73182dea49389 ]
+
+If device_register() returns error in optee_register_device(),
+the name allocated by dev_set_name() need be freed. As comment
+of device_register() says, it should use put_device() to give
+up the reference in the error path. So fix this by calling
+put_device(), then the name can be freed in kobject_cleanup(),
+and optee_device is freed in optee_release_device().
+
+Fixes: c3fa24af9244 ("tee: optee: add TEE bus device enumeration support")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
+Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tee/optee/device.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c
+index 128a2d2a50a1..a74d82e230e3 100644
+--- a/drivers/tee/optee/device.c
++++ b/drivers/tee/optee/device.c
+@@ -80,7 +80,7 @@ static int optee_register_device(const uuid_t *device_uuid)
+       rc = device_register(&optee_device->dev);
+       if (rc) {
+               pr_err("device registration failed, err: %d\n", rc);
+-              kfree(optee_device);
++              put_device(&optee_device->dev);
+       }
+       return rc;
+-- 
+2.35.1
+
diff --git a/queue-5.15/tipc-add-an-extra-conn_get-in-tipc_conn_alloc.patch b/queue-5.15/tipc-add-an-extra-conn_get-in-tipc_conn_alloc.patch
new file mode 100644 (file)
index 0000000..247e4ee
--- /dev/null
@@ -0,0 +1,84 @@
+From 69fc839dc2f7a2df5965b66ce565bcf1999239ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 16:45:01 -0500
+Subject: tipc: add an extra conn_get in tipc_conn_alloc
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit a7b42969d63f47320853a802efd879fbdc4e010e ]
+
+One extra conn_get() is needed in tipc_conn_alloc(), as after
+tipc_conn_alloc() is called, tipc_conn_close() may free this
+con before deferencing it in tipc_topsrv_accept():
+
+   tipc_conn_alloc();
+   newsk = newsock->sk;
+                                 <---- tipc_conn_close();
+   write_lock_bh(&sk->sk_callback_lock);
+   newsk->sk_data_ready = tipc_conn_data_ready;
+
+Then an uaf issue can be triggered:
+
+  BUG: KASAN: use-after-free in tipc_topsrv_accept+0x1e7/0x370 [tipc]
+  Call Trace:
+   <TASK>
+   dump_stack_lvl+0x33/0x46
+   print_report+0x178/0x4b0
+   kasan_report+0x8c/0x100
+   kasan_check_range+0x179/0x1e0
+   tipc_topsrv_accept+0x1e7/0x370 [tipc]
+   process_one_work+0x6a3/0x1030
+   worker_thread+0x8a/0xdf0
+
+This patch fixes it by holding it in tipc_conn_alloc(), then after
+all accessing in tipc_topsrv_accept() releasing it. Note when does
+this in tipc_topsrv_kern_subscr(), as tipc_conn_rcv_sub() returns
+0 or -1 only, we don't need to check for "> 0".
+
+Fixes: c5fa7b3cf3cb ("tipc: introduce new TIPC server infrastructure")
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Acked-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/topsrv.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
+index b0f9aa521670..e3b427a70398 100644
+--- a/net/tipc/topsrv.c
++++ b/net/tipc/topsrv.c
+@@ -206,6 +206,7 @@ static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s, struct socket *s
+       set_bit(CF_CONNECTED, &con->flags);
+       con->server = s;
+       con->sock = sock;
++      conn_get(con);
+       spin_unlock_bh(&s->idr_lock);
+       return con;
+@@ -484,6 +485,7 @@ static void tipc_topsrv_accept(struct work_struct *work)
+               /* Wake up receive process in case of 'SYN+' message */
+               newsk->sk_data_ready(newsk);
++              conn_put(con);
+       }
+ }
+@@ -583,10 +585,11 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
+       *conid = con->conid;
+       rc = tipc_conn_rcv_sub(tipc_topsrv(net), con, &sub);
+-      if (rc >= 0)
+-              return true;
++      if (rc)
++              conn_put(con);
++
+       conn_put(con);
+-      return false;
++      return !rc;
+ }
+ void tipc_topsrv_kern_unsubscr(struct net *net, int conid)
+-- 
+2.35.1
+
diff --git a/queue-5.15/tipc-check-skb_linearize-return-value-in-tipc_disc_r.patch b/queue-5.15/tipc-check-skb_linearize-return-value-in-tipc_disc_r.patch
new file mode 100644 (file)
index 0000000..d8ff6ba
--- /dev/null
@@ -0,0 +1,41 @@
+From ead71705b8b955516c7e7bdff573e11ae0c9a6d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Nov 2022 15:28:32 +0800
+Subject: tipc: check skb_linearize() return value in tipc_disc_rcv()
+
+From: YueHaibing <yuehaibing@huawei.com>
+
+[ Upstream commit cd0f6421162201e4b22ce757a1966729323185eb ]
+
+If skb_linearize() fails in tipc_disc_rcv(), we need to free the skb instead of
+handle it.
+
+Fixes: 25b0b9c4e835 ("tipc: handle collisions of 32-bit node address hash values")
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Acked-by: Jon Maloy <jmaloy@redhat.com>
+Link: https://lore.kernel.org/r/20221119072832.7896-1-yuehaibing@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/discover.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/tipc/discover.c b/net/tipc/discover.c
+index e8630707901e..e8dcdf267c0c 100644
+--- a/net/tipc/discover.c
++++ b/net/tipc/discover.c
+@@ -211,7 +211,10 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
+       u32 self;
+       int err;
+-      skb_linearize(skb);
++      if (skb_linearize(skb)) {
++              kfree_skb(skb);
++              return;
++      }
+       hdr = buf_msg(skb);
+       if (caps & TIPC_NODE_ID128)
+-- 
+2.35.1
+
diff --git a/queue-5.15/tipc-set-con-sock-in-tipc_conn_alloc.patch b/queue-5.15/tipc-set-con-sock-in-tipc_conn_alloc.patch
new file mode 100644 (file)
index 0000000..87a6233
--- /dev/null
@@ -0,0 +1,106 @@
+From 4d92303386e21963a475c27877b0616959694aa3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 16:45:00 -0500
+Subject: tipc: set con sock in tipc_conn_alloc
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 0e5d56c64afcd6fd2d132ea972605b66f8a7d3c4 ]
+
+A crash was reported by Wei Chen:
+
+  BUG: kernel NULL pointer dereference, address: 0000000000000018
+  RIP: 0010:tipc_conn_close+0x12/0x100
+  Call Trace:
+   tipc_topsrv_exit_net+0x139/0x320
+   ops_exit_list.isra.9+0x49/0x80
+   cleanup_net+0x31a/0x540
+   process_one_work+0x3fa/0x9f0
+   worker_thread+0x42/0x5c0
+
+It was caused by !con->sock in tipc_conn_close(). In tipc_topsrv_accept(),
+con is allocated in conn_idr then its sock is set:
+
+  con = tipc_conn_alloc();
+  ...                    <----[1]
+  con->sock = newsock;
+
+If tipc_conn_close() is called in anytime of [1], the null-pointer-def
+is triggered by con->sock->sk due to con->sock is not yet set.
+
+This patch fixes it by moving the con->sock setting to tipc_conn_alloc()
+under s->idr_lock. So that con->sock can never be NULL when getting the
+con from s->conn_idr. It will be also safer to move con->server and flag
+CF_CONNECTED setting under s->idr_lock, as they should all be set before
+tipc_conn_alloc() is called.
+
+Fixes: c5fa7b3cf3cb ("tipc: introduce new TIPC server infrastructure")
+Reported-by: Wei Chen <harperchen1110@gmail.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Acked-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/topsrv.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
+index d92ec92f0b71..b0f9aa521670 100644
+--- a/net/tipc/topsrv.c
++++ b/net/tipc/topsrv.c
+@@ -176,7 +176,7 @@ static void tipc_conn_close(struct tipc_conn *con)
+       conn_put(con);
+ }
+-static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)
++static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s, struct socket *sock)
+ {
+       struct tipc_conn *con;
+       int ret;
+@@ -202,10 +202,11 @@ static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)
+       }
+       con->conid = ret;
+       s->idr_in_use++;
+-      spin_unlock_bh(&s->idr_lock);
+       set_bit(CF_CONNECTED, &con->flags);
+       con->server = s;
++      con->sock = sock;
++      spin_unlock_bh(&s->idr_lock);
+       return con;
+ }
+@@ -467,7 +468,7 @@ static void tipc_topsrv_accept(struct work_struct *work)
+               ret = kernel_accept(lsock, &newsock, O_NONBLOCK);
+               if (ret < 0)
+                       return;
+-              con = tipc_conn_alloc(srv);
++              con = tipc_conn_alloc(srv, newsock);
+               if (IS_ERR(con)) {
+                       ret = PTR_ERR(con);
+                       sock_release(newsock);
+@@ -479,7 +480,6 @@ static void tipc_topsrv_accept(struct work_struct *work)
+               newsk->sk_data_ready = tipc_conn_data_ready;
+               newsk->sk_write_space = tipc_conn_write_space;
+               newsk->sk_user_data = con;
+-              con->sock = newsock;
+               write_unlock_bh(&newsk->sk_callback_lock);
+               /* Wake up receive process in case of 'SYN+' message */
+@@ -577,12 +577,11 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
+       sub.filter = filter;
+       *(u64 *)&sub.usr_handle = (u64)port;
+-      con = tipc_conn_alloc(tipc_topsrv(net));
++      con = tipc_conn_alloc(tipc_topsrv(net), NULL);
+       if (IS_ERR(con))
+               return false;
+       *conid = con->conid;
+-      con->sock = NULL;
+       rc = tipc_conn_rcv_sub(tipc_topsrv(net), con, &sub);
+       if (rc >= 0)
+               return true;
+-- 
+2.35.1
+
diff --git a/queue-5.15/x86-hyperv-restore-vp-assist-page-after-cpu-offlinin.patch b/queue-5.15/x86-hyperv-restore-vp-assist-page-after-cpu-offlinin.patch
new file mode 100644 (file)
index 0000000..b0768e7
--- /dev/null
@@ -0,0 +1,125 @@
+From 4f0eed21277bf72409b7aded09ec62d672549d9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Nov 2022 20:06:01 +0100
+Subject: x86/hyperv: Restore VP assist page after cpu offlining/onlining
+
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+
+[ Upstream commit ee6815416380bc069b7dcbdff0682d4c53617527 ]
+
+Commit e5d9b714fe40 ("x86/hyperv: fix root partition faults when writing
+to VP assist page MSR") moved 'wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE)' under
+'if (*hvp)' condition. This works for root partition as hv_cpu_die()
+does memunmap() and sets 'hv_vp_assist_page[cpu]' to NULL but breaks
+non-root partitions as hv_cpu_die() doesn't free 'hv_vp_assist_page[cpu]'
+for them. This causes VP assist page to remain unset after CPU
+offline/online cycle:
+
+$ rdmsr -p 24 0x40000073
+  10212f001
+$ echo 0 > /sys/devices/system/cpu/cpu24/online
+$ echo 1 > /sys/devices/system/cpu/cpu24/online
+$ rdmsr -p 24 0x40000073
+  0
+
+Fix the issue by always writing to HV_X64_MSR_VP_ASSIST_PAGE in
+hv_cpu_init(). Note, checking 'if (!*hvp)', for root partition is
+pointless as hv_cpu_die() always sets 'hv_vp_assist_page[cpu]' to
+NULL (and it's also NULL initially).
+
+Note: the fact that 'hv_vp_assist_page[cpu]' is reset to NULL may
+present a (potential) issue for KVM. While Hyper-V uses
+CPUHP_AP_ONLINE_DYN stage in CPU hotplug, KVM uses CPUHP_AP_KVM_STARTING
+which comes earlier in CPU teardown sequence. It is theoretically
+possible that Enlightened VMCS is still in use. It is unclear if the
+issue is real and if using KVM with Hyper-V root partition is even
+possible.
+
+While on it, drop the unneeded smp_processor_id() call from hv_cpu_init().
+
+Fixes: e5d9b714fe40 ("x86/hyperv: fix root partition faults when writing to VP assist page MSR")
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/20221103190601.399343-1-vkuznets@redhat.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/hyperv/hv_init.c | 54 +++++++++++++++++++--------------------
+ 1 file changed, 26 insertions(+), 28 deletions(-)
+
+diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
+index b6d48ca5b0f1..762f10cdfb7a 100644
+--- a/arch/x86/hyperv/hv_init.c
++++ b/arch/x86/hyperv/hv_init.c
+@@ -45,7 +45,7 @@ EXPORT_SYMBOL_GPL(hv_vp_assist_page);
+ static int hv_cpu_init(unsigned int cpu)
+ {
+       union hv_vp_assist_msr_contents msr = { 0 };
+-      struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()];
++      struct hv_vp_assist_page **hvp = &hv_vp_assist_page[cpu];
+       int ret;
+       ret = hv_common_cpu_init(cpu);
+@@ -55,34 +55,32 @@ static int hv_cpu_init(unsigned int cpu)
+       if (!hv_vp_assist_page)
+               return 0;
+-      if (!*hvp) {
+-              if (hv_root_partition) {
+-                      /*
+-                       * For root partition we get the hypervisor provided VP assist
+-                       * page, instead of allocating a new page.
+-                       */
+-                      rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
+-                      *hvp = memremap(msr.pfn <<
+-                                      HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT,
+-                                      PAGE_SIZE, MEMREMAP_WB);
+-              } else {
+-                      /*
+-                       * The VP assist page is an "overlay" page (see Hyper-V TLFS's
+-                       * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed
+-                       * out to make sure we always write the EOI MSR in
+-                       * hv_apic_eoi_write() *after* the EOI optimization is disabled
+-                       * in hv_cpu_die(), otherwise a CPU may not be stopped in the
+-                       * case of CPU offlining and the VM will hang.
+-                       */
++      if (hv_root_partition) {
++              /*
++               * For root partition we get the hypervisor provided VP assist
++               * page, instead of allocating a new page.
++               */
++              rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
++              *hvp = memremap(msr.pfn << HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT,
++                              PAGE_SIZE, MEMREMAP_WB);
++      } else {
++              /*
++               * The VP assist page is an "overlay" page (see Hyper-V TLFS's
++               * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed
++               * out to make sure we always write the EOI MSR in
++               * hv_apic_eoi_write() *after* the EOI optimization is disabled
++               * in hv_cpu_die(), otherwise a CPU may not be stopped in the
++               * case of CPU offlining and the VM will hang.
++               */
++              if (!*hvp)
+                       *hvp = __vmalloc(PAGE_SIZE, GFP_KERNEL | __GFP_ZERO);
+-                      if (*hvp)
+-                              msr.pfn = vmalloc_to_pfn(*hvp);
+-              }
+-              WARN_ON(!(*hvp));
+-              if (*hvp) {
+-                      msr.enable = 1;
+-                      wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
+-              }
++              if (*hvp)
++                      msr.pfn = vmalloc_to_pfn(*hvp);
++
++      }
++      if (!WARN_ON(!(*hvp))) {
++              msr.enable = 1;
++              wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
+       }
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.15/xfrm-fix-disable_policy-on-ipv4-early-demux.patch b/queue-5.15/xfrm-fix-disable_policy-on-ipv4-early-demux.patch
new file mode 100644 (file)
index 0000000..ba86038
--- /dev/null
@@ -0,0 +1,54 @@
+From 3c1f8ce26a7fd2951da47105171ba4d224fb8dc8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Oct 2022 22:16:43 +0300
+Subject: xfrm: fix "disable_policy" on ipv4 early demux
+
+From: Eyal Birger <eyal.birger@gmail.com>
+
+[ Upstream commit 3a5913183aa1b14148c723bda030e6102ad73008 ]
+
+The commit in the "Fixes" tag tried to avoid a case where policy check
+is ignored due to dst caching in next hops.
+
+However, when the traffic is locally consumed, the dst may be cached
+in a local TCP or UDP socket as part of early demux. In this case the
+"disable_policy" flag is not checked as ip_route_input_noref() was only
+called before caching, and thus, packets after the initial packet in a
+flow will be dropped if not matching policies.
+
+Fix by checking the "disable_policy" flag also when a valid dst is
+already available.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216557
+Reported-by: Monil Patel <monil191989@gmail.com>
+Fixes: e6175a2ed1f1 ("xfrm: fix "disable_policy" flag use when arriving from different devices")
+Signed-off-by: Eyal Birger <eyal.birger@gmail.com>
+
+----
+
+v2: use dev instead of skb->dev
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_input.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
+index 459d7e630cb0..124bf8fdf924 100644
+--- a/net/ipv4/ip_input.c
++++ b/net/ipv4/ip_input.c
+@@ -364,6 +364,11 @@ static int ip_rcv_finish_core(struct net *net, struct sock *sk,
+                                          iph->tos, dev);
+               if (unlikely(err))
+                       goto drop_error;
++      } else {
++              struct in_device *in_dev = __in_dev_get_rcu(dev);
++
++              if (in_dev && IN_DEV_ORCONF(in_dev, NOPOLICY))
++                      IPCB(skb)->flags |= IPSKB_NOPOLICY;
+       }
+ #ifdef CONFIG_IP_ROUTE_CLASSID
+-- 
+2.35.1
+
diff --git a/queue-5.15/xfrm-fix-ignored-return-value-in-xfrm6_init.patch b/queue-5.15/xfrm-fix-ignored-return-value-in-xfrm6_init.patch
new file mode 100644 (file)
index 0000000..cf267e6
--- /dev/null
@@ -0,0 +1,59 @@
+From 78245d75b21394601f4f54a3496776503da10948 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Nov 2022 17:07:13 +0800
+Subject: xfrm: Fix ignored return value in xfrm6_init()
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit 40781bfb836eda57d19c0baa37c7e72590e05fdc ]
+
+When IPv6 module initializing in xfrm6_init(), register_pernet_subsys()
+is possible to fail but its return value is ignored.
+
+If IPv6 initialization fails later and xfrm6_fini() is called,
+removing uninitialized list in xfrm6_net_ops will cause null-ptr-deref:
+
+KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
+CPU: 1 PID: 330 Comm: insmod
+RIP: 0010:unregister_pernet_operations+0xc9/0x450
+Call Trace:
+ <TASK>
+ unregister_pernet_subsys+0x31/0x3e
+ xfrm6_fini+0x16/0x30 [ipv6]
+ ip6_route_init+0xcd/0x128 [ipv6]
+ inet6_init+0x29c/0x602 [ipv6]
+ ...
+
+Fix it by catching the error return value of register_pernet_subsys().
+
+Fixes: 8d068875caca ("xfrm: make gc_thresh configurable in all namespaces")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/xfrm6_policy.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
+index af7a4b8b1e9c..247296e3294b 100644
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -289,9 +289,13 @@ int __init xfrm6_init(void)
+       if (ret)
+               goto out_state;
+-      register_pernet_subsys(&xfrm6_net_ops);
++      ret = register_pernet_subsys(&xfrm6_net_ops);
++      if (ret)
++              goto out_protocol;
+ out:
+       return ret;
++out_protocol:
++      xfrm6_protocol_fini();
+ out_state:
+       xfrm6_state_fini();
+ out_policy:
+-- 
+2.35.1
+
diff --git a/queue-5.15/xfrm-fix-oops-in-__xfrm_state_delete.patch b/queue-5.15/xfrm-fix-oops-in-__xfrm_state_delete.patch
new file mode 100644 (file)
index 0000000..9f407cf
--- /dev/null
@@ -0,0 +1,119 @@
+From e7cc851a408e4ba2a9f90da7148db57a81ba17a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Nov 2022 11:18:48 +0100
+Subject: xfrm: Fix oops in __xfrm_state_delete()
+
+From: Thomas Jarosch <thomas.jarosch@intra2net.com>
+
+[ Upstream commit b97df039a68b2f3e848e238df5d5d06343ea497b ]
+
+Kernel 5.14 added a new "byseq" index to speed
+up xfrm_state lookups by sequence number in commit
+fe9f1d8779cb ("xfrm: add state hashtable keyed by seq")
+
+While the patch was thorough, the function pfkey_send_new_mapping()
+in net/af_key.c also modifies x->km.seq and never added
+the current xfrm_state to the "byseq" index.
+
+This leads to the following kernel Ooops:
+    BUG: kernel NULL pointer dereference, address: 0000000000000000
+    ..
+    RIP: 0010:__xfrm_state_delete+0xc9/0x1c0
+    ..
+    Call Trace:
+    <TASK>
+    xfrm_state_delete+0x1e/0x40
+    xfrm_del_sa+0xb0/0x110 [xfrm_user]
+    xfrm_user_rcv_msg+0x12d/0x270 [xfrm_user]
+    ? remove_entity_load_avg+0x8a/0xa0
+    ? copy_to_user_state_extra+0x580/0x580 [xfrm_user]
+    netlink_rcv_skb+0x51/0x100
+    xfrm_netlink_rcv+0x30/0x50 [xfrm_user]
+    netlink_unicast+0x1a6/0x270
+    netlink_sendmsg+0x22a/0x480
+    __sys_sendto+0x1a6/0x1c0
+    ? __audit_syscall_entry+0xd8/0x130
+    ? __audit_syscall_exit+0x249/0x2b0
+    __x64_sys_sendto+0x23/0x30
+    do_syscall_64+0x3a/0x90
+    entry_SYSCALL_64_after_hwframe+0x61/0xcb
+
+Exact location of the crash in __xfrm_state_delete():
+    if (x->km.seq)
+        hlist_del_rcu(&x->byseq);
+
+The hlist_node "byseq" was never populated.
+
+The bug only triggers if a new NAT traversal mapping (changed IP or port)
+is detected in esp_input_done2() / esp6_input_done2(), which in turn
+indirectly calls pfkey_send_new_mapping() *if* the kernel is compiled
+with CONFIG_NET_KEY and "af_key" is active.
+
+The PF_KEYv2 message SADB_X_NAT_T_NEW_MAPPING is not part of RFC 2367.
+Various implementations have been examined how they handle
+the "sadb_msg_seq" header field:
+
+- racoon (Android): does not process SADB_X_NAT_T_NEW_MAPPING
+- strongswan: does not care about sadb_msg_seq
+- openswan: does not care about sadb_msg_seq
+
+There is no standard how PF_KEYv2 sadb_msg_seq should be populated
+for SADB_X_NAT_T_NEW_MAPPING and it's not used in popular
+implementations either. Herbert Xu suggested we should just
+use the current km.seq value as is. This fixes the root cause
+of the oops since we no longer modify km.seq itself.
+
+The update of "km.seq" looks like a copy'n'paste error
+from pfkey_send_acquire(). SADB_ACQUIRE must indeed assign a unique km.seq
+number according to RFC 2367. It has been verified that code paths
+involving pfkey_send_acquire() don't cause the same Oops.
+
+PF_KEYv2 SADB_X_NAT_T_NEW_MAPPING support was originally added here:
+    https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git
+
+    commit cbc3488685b20e7b2a98ad387a1a816aada569d8
+    Author:     Derek Atkins <derek@ihtfp.com>
+    AuthorDate: Wed Apr 2 13:21:02 2003 -0800
+
+        [IPSEC]: Implement UDP Encapsulation framework.
+
+        In particular, implement ESPinUDP encapsulation for IPsec
+        Nat Traversal.
+
+A note on triggering the bug: I was not able to trigger it using VMs.
+There is one VPN using a high latency link on our production VPN server
+that triggered it like once a day though.
+
+Link: https://github.com/strongswan/strongswan/issues/992
+Link: https://lore.kernel.org/netdev/00959f33ee52c4b3b0084d42c430418e502db554.1652340703.git.antony.antony@secunet.com/T/
+Link: https://lore.kernel.org/netdev/20221027142455.3975224-1-chenzhihao@meizu.com/T/
+
+Fixes: fe9f1d8779cb ("xfrm: add state hashtable keyed by seq")
+Reported-by: Roth Mark <rothm@mail.com>
+Reported-by: Zhihao Chen <chenzhihao@meizu.com>
+Tested-by: Roth Mark <rothm@mail.com>
+Signed-off-by: Thomas Jarosch <thomas.jarosch@intra2net.com>
+Acked-by: Antony Antony <antony.antony@secunet.com>
+Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/key/af_key.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/key/af_key.c b/net/key/af_key.c
+index a654bd4bc437..1d6ae1df3886 100644
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -3394,7 +3394,7 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
+       hdr->sadb_msg_len = size / sizeof(uint64_t);
+       hdr->sadb_msg_errno = 0;
+       hdr->sadb_msg_reserved = 0;
+-      hdr->sadb_msg_seq = x->km.seq = get_acqseq();
++      hdr->sadb_msg_seq = x->km.seq;
+       hdr->sadb_msg_pid = 0;
+       /* SA */
+-- 
+2.35.1
+
diff --git a/queue-5.15/xfrm-replay-fix-esn-wrap-around-for-gso.patch b/queue-5.15/xfrm-replay-fix-esn-wrap-around-for-gso.patch
new file mode 100644 (file)
index 0000000..4edbb80
--- /dev/null
@@ -0,0 +1,103 @@
+From 39f79cd8e5445597ef17d1f95bdf89f1ab2ad2a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Oct 2022 08:34:47 +0200
+Subject: xfrm: replay: Fix ESN wrap around for GSO
+
+From: Christian Langrock <christian.langrock@secunet.com>
+
+[ Upstream commit 4b549ccce941798703f159b227aa28c716aa78fa ]
+
+When using GSO it can happen that the wrong seq_hi is used for the last
+packets before the wrap around. This can lead to double usage of a
+sequence number. To avoid this, we should serialize this last GSO
+packet.
+
+Fixes: d7dbefc45cf5 ("xfrm: Add xfrm_replay_overflow functions for offloading")
+Co-developed-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Christian Langrock <christian.langrock@secunet.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/esp4_offload.c |  3 +++
+ net/ipv6/esp6_offload.c |  3 +++
+ net/xfrm/xfrm_device.c  | 15 ++++++++++++++-
+ net/xfrm/xfrm_replay.c  |  2 +-
+ 4 files changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c
+index dad5d29a6a8d..2ddba1e2cf22 100644
+--- a/net/ipv4/esp4_offload.c
++++ b/net/ipv4/esp4_offload.c
+@@ -311,6 +311,9 @@ static int esp_xmit(struct xfrm_state *x, struct sk_buff *skb,  netdev_features_
+                       xo->seq.low += skb_shinfo(skb)->gso_segs;
+       }
++      if (xo->seq.low < seq)
++              xo->seq.hi++;
++
+       esp.seqno = cpu_to_be64(seq + ((u64)xo->seq.hi << 32));
+       ip_hdr(skb)->tot_len = htons(skb->len);
+diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c
+index 302170882382..4cc19acfc369 100644
+--- a/net/ipv6/esp6_offload.c
++++ b/net/ipv6/esp6_offload.c
+@@ -343,6 +343,9 @@ static int esp6_xmit(struct xfrm_state *x, struct sk_buff *skb,  netdev_features
+                       xo->seq.low += skb_shinfo(skb)->gso_segs;
+       }
++      if (xo->seq.low < seq)
++              xo->seq.hi++;
++
+       esp.seqno = cpu_to_be64(xo->seq.low + ((u64)xo->seq.hi << 32));
+       len = skb->len - sizeof(struct ipv6hdr);
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index c255aac6b816..8b8e957a69c3 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -97,6 +97,18 @@ static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb)
+       }
+ }
++static inline bool xmit_xfrm_check_overflow(struct sk_buff *skb)
++{
++      struct xfrm_offload *xo = xfrm_offload(skb);
++      __u32 seq = xo->seq.low;
++
++      seq += skb_shinfo(skb)->gso_segs;
++      if (unlikely(seq < xo->seq.low))
++              return true;
++
++      return false;
++}
++
+ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again)
+ {
+       int err;
+@@ -134,7 +146,8 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
+               return skb;
+       }
+-      if (skb_is_gso(skb) && unlikely(x->xso.dev != dev)) {
++      if (skb_is_gso(skb) && (unlikely(x->xso.dev != dev) ||
++                              unlikely(xmit_xfrm_check_overflow(skb)))) {
+               struct sk_buff *segs;
+               /* Packet got rerouted, fixup features and segment it. */
+diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
+index 9277d81b344c..49dd788859d8 100644
+--- a/net/xfrm/xfrm_replay.c
++++ b/net/xfrm/xfrm_replay.c
+@@ -714,7 +714,7 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff
+                       oseq += skb_shinfo(skb)->gso_segs;
+               }
+-              if (unlikely(oseq < replay_esn->oseq)) {
++              if (unlikely(xo->seq.low < replay_esn->oseq)) {
+                       XFRM_SKB_CB(skb)->seq.output.hi = ++oseq_hi;
+                       xo->seq.hi = oseq_hi;
+                       replay_esn->oseq_hi = oseq_hi;
+-- 
+2.35.1
+