]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Mon, 17 Jun 2024 11:30:32 +0000 (07:30 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 17 Jun 2024 11:30:32 +0000 (07:30 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
40 files changed:
queue-5.15/af_unix-read-with-msg_peek-loops-if-the-first-unread.patch [new file with mode: 0644]
queue-5.15/bluetooth-l2cap-fix-rejecting-l2cap_conn_param_updat.patch [new file with mode: 0644]
queue-5.15/clk-sifive-do-not-register-clkdevs-for-prci-clocks.patch [new file with mode: 0644]
queue-5.15/drm-bridge-panel-fix-runtime-warning-on-panel-bridge.patch [new file with mode: 0644]
queue-5.15/drm-komeda-check-for-error-valued-pointer.patch [new file with mode: 0644]
queue-5.15/drm-vmwgfx-3d-disabled-should-not-effect-stdu-memory.patch [new file with mode: 0644]
queue-5.15/geneve-fix-incorrect-inner-network-header-offset-whe.patch [new file with mode: 0644]
queue-5.15/genirq-allow-the-pm-device-to-originate-from-irq-dom.patch [new file with mode: 0644]
queue-5.15/gpio-add-helpers-to-ease-the-transition-towards-immu.patch [new file with mode: 0644]
queue-5.15/gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch [new file with mode: 0644]
queue-5.15/gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch [new file with mode: 0644]
queue-5.15/gpio-tpmx86-move-pm-device-over-to-irq-domain.patch [new file with mode: 0644]
queue-5.15/gpio-tqmx86-convert-to-immutable-irq_chip.patch [new file with mode: 0644]
queue-5.15/gpio-tqmx86-fix-broken-irq_type_edge_both-interrupt-.patch [new file with mode: 0644]
queue-5.15/gpio-tqmx86-fix-typo-in-kconfig-label.patch [new file with mode: 0644]
queue-5.15/gpio-tqmx86-introduce-shadow-register-for-gpio-outpu.patch [new file with mode: 0644]
queue-5.15/gpio-tqmx86-remove-unneeded-call-to-platform_set_drv.patch [new file with mode: 0644]
queue-5.15/gpio-tqmx86-store-irq-trigger-type-and-unmask-status.patch [new file with mode: 0644]
queue-5.15/hid-core-remove-unnecessary-warn_on-in-implement.patch [new file with mode: 0644]
queue-5.15/hid-logitech-dj-fix-memory-leak-in-logi_dj_recv_swit.patch [new file with mode: 0644]
queue-5.15/iommu-amd-fix-sysfs-leak-in-iommu-init.patch [new file with mode: 0644]
queue-5.15/iommu-amd-introduce-pci-segment-structure.patch [new file with mode: 0644]
queue-5.15/iommu-return-right-value-in-iommu_sva_bind_device.patch [new file with mode: 0644]
queue-5.15/ionic-fix-use-after-netif_napi_del.patch [new file with mode: 0644]
queue-5.15/kernel.h-split-out-container_of-and-typeof_member-ma.patch [new file with mode: 0644]
queue-5.15/liquidio-adjust-a-null-pointer-handling-path-in-lio_.patch [new file with mode: 0644]
queue-5.15/net-geneve-support-ipv4-ipv6-as-inner-protocol.patch [new file with mode: 0644]
queue-5.15/net-hns3-add-cond_resched-to-hns3-ring-buffer-init-p.patch [new file with mode: 0644]
queue-5.15/net-hns3-fix-kernel-crash-problem-in-concurrent-scen.patch [new file with mode: 0644]
queue-5.15/net-ipv6-fix-the-rt-cache-flush-via-sysctl-using-a-p.patch [new file with mode: 0644]
queue-5.15/net-mlx5e-fix-features-validation-check-for-tunneled.patch [new file with mode: 0644]
queue-5.15/net-sfp-always-call-sfp_sm_mod_remove-on-remove.patch [new file with mode: 0644]
queue-5.15/net-stmmac-replace-priv-speed-with-the-porttransmitr.patch [new file with mode: 0644]
queue-5.15/netfilter-ipset-fix-race-between-namespace-cleanup-a.patch [new file with mode: 0644]
queue-5.15/netfilter-use-flowlabel-flow-key-when-re-routing-man.patch [new file with mode: 0644]
queue-5.15/platform-x86-dell-smbios-base-use-sysfs_emit.patch [new file with mode: 0644]
queue-5.15/platform-x86-dell-smbios-fix-wrong-token-data-in-sys.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/sunrpc-return-proper-error-from-gss_wrap_req_priv.patch [new file with mode: 0644]
queue-5.15/tcp-fix-race-in-tcp_v6_syn_recv_sock.patch [new file with mode: 0644]

diff --git a/queue-5.15/af_unix-read-with-msg_peek-loops-if-the-first-unread.patch b/queue-5.15/af_unix-read-with-msg_peek-loops-if-the-first-unread.patch
new file mode 100644 (file)
index 0000000..f327a2c
--- /dev/null
@@ -0,0 +1,85 @@
+From cfa8617f46189537fb7143ec8603cf4f7db08fce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jun 2024 01:46:39 -0700
+Subject: af_unix: Read with MSG_PEEK loops if the first unread byte is OOB
+
+From: Rao Shoaib <Rao.Shoaib@oracle.com>
+
+[ Upstream commit a6736a0addd60fccc3a3508461d72314cc609772 ]
+
+Read with MSG_PEEK flag loops if the first byte to read is an OOB byte.
+commit 22dd70eb2c3d ("af_unix: Don't peek OOB data without MSG_OOB.")
+addresses the loop issue but does not address the issue that no data
+beyond OOB byte can be read.
+
+>>> from socket import *
+>>> c1, c2 = socketpair(AF_UNIX, SOCK_STREAM)
+>>> c1.send(b'a', MSG_OOB)
+1
+>>> c1.send(b'b')
+1
+>>> c2.recv(1, MSG_PEEK | MSG_DONTWAIT)
+b'b'
+
+>>> from socket import *
+>>> c1, c2 = socketpair(AF_UNIX, SOCK_STREAM)
+>>> c2.setsockopt(SOL_SOCKET, SO_OOBINLINE, 1)
+>>> c1.send(b'a', MSG_OOB)
+1
+>>> c1.send(b'b')
+1
+>>> c2.recv(1, MSG_PEEK | MSG_DONTWAIT)
+b'a'
+>>> c2.recv(1, MSG_PEEK | MSG_DONTWAIT)
+b'a'
+>>> c2.recv(1, MSG_DONTWAIT)
+b'a'
+>>> c2.recv(1, MSG_PEEK | MSG_DONTWAIT)
+b'b'
+>>>
+
+Fixes: 314001f0bf92 ("af_unix: Add OOB support")
+Signed-off-by: Rao Shoaib <Rao.Shoaib@oracle.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://lore.kernel.org/r/20240611084639.2248934-1-Rao.Shoaib@oracle.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/unix/af_unix.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index 12099b06d7e88..c0351a141d0f7 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -2607,18 +2607,18 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
+               if (skb == u->oob_skb) {
+                       if (copied) {
+                               skb = NULL;
+-                      } else if (sock_flag(sk, SOCK_URGINLINE)) {
+-                              if (!(flags & MSG_PEEK)) {
++                      } else if (!(flags & MSG_PEEK)) {
++                              if (sock_flag(sk, SOCK_URGINLINE)) {
+                                       WRITE_ONCE(u->oob_skb, NULL);
+                                       consume_skb(skb);
++                              } else {
++                                      __skb_unlink(skb, &sk->sk_receive_queue);
++                                      WRITE_ONCE(u->oob_skb, NULL);
++                                      unlinked_skb = skb;
++                                      skb = skb_peek(&sk->sk_receive_queue);
+                               }
+-                      } else if (flags & MSG_PEEK) {
+-                              skb = NULL;
+-                      } else {
+-                              __skb_unlink(skb, &sk->sk_receive_queue);
+-                              WRITE_ONCE(u->oob_skb, NULL);
+-                              unlinked_skb = skb;
+-                              skb = skb_peek(&sk->sk_receive_queue);
++                      } else if (!sock_flag(sk, SOCK_URGINLINE)) {
++                              skb = skb_peek_next(skb, &sk->sk_receive_queue);
+                       }
+               }
+-- 
+2.43.0
+
diff --git a/queue-5.15/bluetooth-l2cap-fix-rejecting-l2cap_conn_param_updat.patch b/queue-5.15/bluetooth-l2cap-fix-rejecting-l2cap_conn_param_updat.patch
new file mode 100644 (file)
index 0000000..3be1aee
--- /dev/null
@@ -0,0 +1,108 @@
+From f9fe6807cd1d219cb2bfd9e70acdb413d25dbdf1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 May 2024 16:03:07 -0400
+Subject: Bluetooth: L2CAP: Fix rejecting L2CAP_CONN_PARAM_UPDATE_REQ
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 806a5198c05987b748b50f3d0c0cfb3d417381a4 ]
+
+This removes the bogus check for max > hcon->le_conn_max_interval since
+the later is just the initial maximum conn interval not the maximum the
+stack could support which is really 3200=4000ms.
+
+In order to pass GAP/CONN/CPUP/BV-05-C one shall probably enter values
+of the following fields in IXIT that would cause hci_check_conn_params
+to fail:
+
+TSPX_conn_update_int_min
+TSPX_conn_update_int_max
+TSPX_conn_update_peripheral_latency
+TSPX_conn_update_supervision_timeout
+
+Link: https://github.com/bluez/bluez/issues/847
+Fixes: e4b019515f95 ("Bluetooth: Enforce validation on max value of connection interval")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 36 ++++++++++++++++++++++++++++----
+ net/bluetooth/l2cap_core.c       |  8 +------
+ 2 files changed, 33 insertions(+), 11 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index b6114bc0dd0f2..d5935610c6602 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -1690,18 +1690,46 @@ static inline int hci_check_conn_params(u16 min, u16 max, u16 latency,
+ {
+       u16 max_latency;
+-      if (min > max || min < 6 || max > 3200)
++      if (min > max) {
++              BT_WARN("min %d > max %d", min, max);
+               return -EINVAL;
++      }
++
++      if (min < 6) {
++              BT_WARN("min %d < 6", min);
++              return -EINVAL;
++      }
++
++      if (max > 3200) {
++              BT_WARN("max %d > 3200", max);
++              return -EINVAL;
++      }
++
++      if (to_multiplier < 10) {
++              BT_WARN("to_multiplier %d < 10", to_multiplier);
++              return -EINVAL;
++      }
+-      if (to_multiplier < 10 || to_multiplier > 3200)
++      if (to_multiplier > 3200) {
++              BT_WARN("to_multiplier %d > 3200", to_multiplier);
+               return -EINVAL;
++      }
+-      if (max >= to_multiplier * 8)
++      if (max >= to_multiplier * 8) {
++              BT_WARN("max %d >= to_multiplier %d * 8", max, to_multiplier);
+               return -EINVAL;
++      }
+       max_latency = (to_multiplier * 4 / max) - 1;
+-      if (latency > 499 || latency > max_latency)
++      if (latency > 499) {
++              BT_WARN("latency %d > 499", latency);
+               return -EINVAL;
++      }
++
++      if (latency > max_latency) {
++              BT_WARN("latency %d > max_latency %d", latency, max_latency);
++              return -EINVAL;
++      }
+       return 0;
+ }
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 900b352975856..43a21a90619d9 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -5617,13 +5617,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
+       memset(&rsp, 0, sizeof(rsp));
+-      if (max > hcon->le_conn_max_interval) {
+-              BT_DBG("requested connection interval exceeds current bounds.");
+-              err = -EINVAL;
+-      } else {
+-              err = hci_check_conn_params(min, max, latency, to_multiplier);
+-      }
+-
++      err = hci_check_conn_params(min, max, latency, to_multiplier);
+       if (err)
+               rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
+       else
+-- 
+2.43.0
+
diff --git a/queue-5.15/clk-sifive-do-not-register-clkdevs-for-prci-clocks.patch b/queue-5.15/clk-sifive-do-not-register-clkdevs-for-prci-clocks.patch
new file mode 100644 (file)
index 0000000..e7c3bf9
--- /dev/null
@@ -0,0 +1,62 @@
+From 2b329e40c49c250209ec05e1e86a02e2d684bf33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 May 2024 17:14:12 -0700
+Subject: clk: sifive: Do not register clkdevs for PRCI clocks
+
+From: Samuel Holland <samuel.holland@sifive.com>
+
+[ Upstream commit 2607133196c35f31892ee199ce7ffa717bea4ad1 ]
+
+These clkdevs were unnecessary, because systems using this driver always
+look up clocks using the devicetree. And as Russell King points out[1],
+since the provided device name was truncated, lookups via clkdev would
+never match.
+
+Recently, commit 8d532528ff6a ("clkdev: report over-sized strings when
+creating clkdev entries") caused clkdev registration to fail due to the
+truncation, and this now prevents the driver from probing. Fix the
+driver by removing the clkdev registration.
+
+Link: https://lore.kernel.org/linux-clk/ZkfYqj+OcAxd9O2t@shell.armlinux.org.uk/ [1]
+Fixes: 30b8e27e3b58 ("clk: sifive: add a driver for the SiFive FU540 PRCI IP block")
+Fixes: 8d532528ff6a ("clkdev: report over-sized strings when creating clkdev entries")
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Closes: https://lore.kernel.org/linux-clk/7eda7621-0dde-4153-89e4-172e4c095d01@roeck-us.net/
+Suggested-by: Russell King <linux@armlinux.org.uk>
+Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
+Link: https://lore.kernel.org/r/20240528001432.1200403-1-samuel.holland@sifive.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/sifive/sifive-prci.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
+index 80a288c59e56d..8b573ff646f65 100644
+--- a/drivers/clk/sifive/sifive-prci.c
++++ b/drivers/clk/sifive/sifive-prci.c
+@@ -4,7 +4,6 @@
+  * Copyright (C) 2020 Zong Li
+  */
+-#include <linux/clkdev.h>
+ #include <linux/delay.h>
+ #include <linux/io.h>
+ #include <linux/of_device.h>
+@@ -541,13 +540,6 @@ static int __prci_register_clocks(struct device *dev, struct __prci_data *pd,
+                       return r;
+               }
+-              r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev));
+-              if (r) {
+-                      dev_warn(dev, "Failed to register clkdev for %s: %d\n",
+-                               init.name, r);
+-                      return r;
+-              }
+-
+               pd->hw_clks.hws[i] = &pic->hw;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.15/drm-bridge-panel-fix-runtime-warning-on-panel-bridge.patch b/queue-5.15/drm-bridge-panel-fix-runtime-warning-on-panel-bridge.patch
new file mode 100644 (file)
index 0000000..0f7c2ca
--- /dev/null
@@ -0,0 +1,51 @@
+From 6a90206af6441f14396cc37aca56ef4a5cbeb6b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jun 2024 11:27:39 +0100
+Subject: drm/bridge/panel: Fix runtime warning on panel bridge release
+
+From: Adam Miotk <adam.miotk@arm.com>
+
+[ Upstream commit ce62600c4dbee8d43b02277669dd91785a9b81d9 ]
+
+Device managed panel bridge wrappers are created by calling to
+drm_panel_bridge_add_typed() and registering a release handler for
+clean-up when the device gets unbound.
+
+Since the memory for this bridge is also managed and linked to the panel
+device, the release function should not try to free that memory.
+Moreover, the call to devm_kfree() inside drm_panel_bridge_remove() will
+fail in this case and emit a warning because the panel bridge resource
+is no longer on the device resources list (it has been removed from
+there before the call to release handlers).
+
+Fixes: 67022227ffb1 ("drm/bridge: Add a devm_ allocator for panel bridge.")
+Signed-off-by: Adam Miotk <adam.miotk@arm.com>
+Signed-off-by: Maxime Ripard <mripard@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240610102739.139852-1-adam.miotk@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/panel.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
+index b32295abd9e75..e67bcbef0e8ed 100644
+--- a/drivers/gpu/drm/bridge/panel.c
++++ b/drivers/gpu/drm/bridge/panel.c
+@@ -253,9 +253,12 @@ EXPORT_SYMBOL(drm_panel_bridge_remove);
+ static void devm_drm_panel_bridge_release(struct device *dev, void *res)
+ {
+-      struct drm_bridge **bridge = res;
++      struct drm_bridge *bridge = *(struct drm_bridge **)res;
+-      drm_panel_bridge_remove(*bridge);
++      if (!bridge)
++              return;
++
++      drm_bridge_remove(bridge);
+ }
+ /**
+-- 
+2.43.0
+
diff --git a/queue-5.15/drm-komeda-check-for-error-valued-pointer.patch b/queue-5.15/drm-komeda-check-for-error-valued-pointer.patch
new file mode 100644 (file)
index 0000000..1cbe858
--- /dev/null
@@ -0,0 +1,37 @@
+From fec62843d3d15c56da8d09164cbf37440d6ebab1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jun 2024 11:20:56 +0100
+Subject: drm/komeda: check for error-valued pointer
+
+From: Amjad Ouled-Ameur <amjad.ouled-ameur@arm.com>
+
+[ Upstream commit b880018edd3a577e50366338194dee9b899947e0 ]
+
+komeda_pipeline_get_state() may return an error-valued pointer, thus
+check the pointer for negative or null value before dereferencing.
+
+Fixes: 502932a03fce ("drm/komeda: Add the initial scaler support for CORE")
+Signed-off-by: Amjad Ouled-Ameur <amjad.ouled-ameur@arm.com>
+Signed-off-by: Maxime Ripard <mripard@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240610102056.40406-1-amjad.ouled-ameur@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+index 88b58153f9d66..c956fda918beb 100644
+--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
++++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+@@ -259,7 +259,7 @@ komeda_component_get_avail_scaler(struct komeda_component *c,
+       u32 avail_scalers;
+       pipe_st = komeda_pipeline_get_state(c->pipeline, state);
+-      if (!pipe_st)
++      if (IS_ERR_OR_NULL(pipe_st))
+               return NULL;
+       avail_scalers = (pipe_st->active_comps & KOMEDA_PIPELINE_SCALERS) ^
+-- 
+2.43.0
+
diff --git a/queue-5.15/drm-vmwgfx-3d-disabled-should-not-effect-stdu-memory.patch b/queue-5.15/drm-vmwgfx-3d-disabled-should-not-effect-stdu-memory.patch
new file mode 100644 (file)
index 0000000..602d6a1
--- /dev/null
@@ -0,0 +1,45 @@
+From 3c0217ff0e22f54401f9929fbbc82d9dcbaf0286 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 May 2024 13:47:18 -0500
+Subject: drm/vmwgfx: 3D disabled should not effect STDU memory limits
+
+From: Ian Forbes <ian.forbes@broadcom.com>
+
+[ Upstream commit fb5e19d2dd03eb995ccd468d599b2337f7f66555 ]
+
+This limit became a hard cap starting with the change referenced below.
+Surface creation on the device will fail if the requested size is larger
+than this limit so altering the value arbitrarily will expose modes that
+are too large for the device's hard limits.
+
+Fixes: 7ebb47c9f9ab ("drm/vmwgfx: Read new register for GB memory when available")
+
+Signed-off-by: Ian Forbes <ian.forbes@broadcom.com>
+Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240521184720.767-3-ian.forbes@broadcom.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+index 8449d09c06f7a..0f09a9116b054 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+@@ -904,13 +904,6 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id)
+                               vmw_read(dev_priv,
+                                        SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB);
+-              /*
+-               * Workaround for low memory 2D VMs to compensate for the
+-               * allocation taken by fbdev
+-               */
+-              if (!(dev_priv->capabilities & SVGA_CAP_3D))
+-                      mem_size *= 3;
+-
+               dev_priv->max_mob_pages = mem_size * 1024 / PAGE_SIZE;
+               dev_priv->max_primary_mem =
+                       vmw_read(dev_priv, SVGA_REG_MAX_PRIMARY_MEM);
+-- 
+2.43.0
+
diff --git a/queue-5.15/geneve-fix-incorrect-inner-network-header-offset-whe.patch b/queue-5.15/geneve-fix-incorrect-inner-network-header-offset-whe.patch
new file mode 100644 (file)
index 0000000..5feb7ab
--- /dev/null
@@ -0,0 +1,106 @@
+From 800814a7df99f26dd955e9a8e65d85a5ce418e57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jun 2024 23:32:48 +0300
+Subject: geneve: Fix incorrect inner network header offset when
+ innerprotoinherit is set
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit c6ae073f5903f6c6439d0ac855836a4da5c0a701 ]
+
+When innerprotoinherit is set, the tunneled packets do not have an inner
+Ethernet header.
+Change 'maclen' to not always assume the header length is ETH_HLEN, as
+there might not be a MAC header.
+
+This resolves issues with drivers (e.g. mlx5, in
+mlx5e_tx_tunnel_accel()) who rely on the skb inner network header offset
+to be correct, and use it for TX offloads.
+
+Fixes: d8a6213d70ac ("geneve: fix header validation in geneve[6]_xmit_skb")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/geneve.c     | 10 ++++++----
+ include/net/ip_tunnels.h |  5 +++--
+ 2 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
+index 3f076dadff78b..3cf59fd75f9b2 100644
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -920,6 +920,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+                          struct geneve_dev *geneve,
+                          const struct ip_tunnel_info *info)
+ {
++      bool inner_proto_inherit = geneve->cfg.inner_proto_inherit;
+       bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
+       struct geneve_sock *gs4 = rcu_dereference(geneve->sock4);
+       const struct ip_tunnel_key *key = &info->key;
+@@ -931,7 +932,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+       __be16 sport;
+       int err;
+-      if (!skb_vlan_inet_prepare(skb))
++      if (!skb_vlan_inet_prepare(skb, inner_proto_inherit))
+               return -EINVAL;
+       sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
+@@ -1004,7 +1005,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+       }
+       err = geneve_build_skb(&rt->dst, skb, info, xnet, sizeof(struct iphdr),
+-                             geneve->cfg.inner_proto_inherit);
++                             inner_proto_inherit);
+       if (unlikely(err))
+               return err;
+@@ -1020,6 +1021,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+                           struct geneve_dev *geneve,
+                           const struct ip_tunnel_info *info)
+ {
++      bool inner_proto_inherit = geneve->cfg.inner_proto_inherit;
+       bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
+       struct geneve_sock *gs6 = rcu_dereference(geneve->sock6);
+       const struct ip_tunnel_key *key = &info->key;
+@@ -1029,7 +1031,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+       __be16 sport;
+       int err;
+-      if (!skb_vlan_inet_prepare(skb))
++      if (!skb_vlan_inet_prepare(skb, inner_proto_inherit))
+               return -EINVAL;
+       sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
+@@ -1084,7 +1086,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+               ttl = ttl ? : ip6_dst_hoplimit(dst);
+       }
+       err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr),
+-                             geneve->cfg.inner_proto_inherit);
++                             inner_proto_inherit);
+       if (unlikely(err))
+               return err;
+diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
+index eca36edb85570..526b492ebf78d 100644
+--- a/include/net/ip_tunnels.h
++++ b/include/net/ip_tunnels.h
+@@ -334,9 +334,10 @@ static inline bool pskb_inet_may_pull(struct sk_buff *skb)
+ /* Variant of pskb_inet_may_pull().
+  */
+-static inline bool skb_vlan_inet_prepare(struct sk_buff *skb)
++static inline bool skb_vlan_inet_prepare(struct sk_buff *skb,
++                                       bool inner_proto_inherit)
+ {
+-      int nhlen = 0, maclen = ETH_HLEN;
++      int nhlen = 0, maclen = inner_proto_inherit ? 0 : ETH_HLEN;
+       __be16 type = skb->protocol;
+       /* Essentially this is skb_protocol(skb, true)
+-- 
+2.43.0
+
diff --git a/queue-5.15/genirq-allow-the-pm-device-to-originate-from-irq-dom.patch b/queue-5.15/genirq-allow-the-pm-device-to-originate-from-irq-dom.patch
new file mode 100644 (file)
index 0000000..a496c5c
--- /dev/null
@@ -0,0 +1,122 @@
+From b87525165dae63e1b49e64c38848199b7e00b719 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Feb 2022 12:02:59 +0000
+Subject: genirq: Allow the PM device to originate from irq domain
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit 1f8863bfb5ca500ea1c7669b16b1931ba27fce20 ]
+
+As a preparation to moving the reference to the device used for
+runtime power management, add a new 'dev' field to the irqdomain
+structure for that exact purpose.
+
+The irq_chip_pm_{get,put}() helpers are made aware of the dual
+location via a new private helper.
+
+No functional change intended.
+
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Tested-by: Tony Lindgren <tony@atomide.com>
+Acked-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Link: https://lore.kernel.org/r/20220201120310.878267-2-maz@kernel.org
+Stable-dep-of: 08af509efdf8 ("gpio: tqmx86: store IRQ trigger type and unmask status separately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/irqdomain.h | 10 ++++++++++
+ kernel/irq/chip.c         | 23 ++++++++++++++++++-----
+ 2 files changed, 28 insertions(+), 5 deletions(-)
+
+diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
+index 9ee238ad29ce9..a7c80bd4b45b6 100644
+--- a/include/linux/irqdomain.h
++++ b/include/linux/irqdomain.h
+@@ -147,6 +147,8 @@ struct irq_domain_chip_generic;
+  * @gc: Pointer to a list of generic chips. There is a helper function for
+  *      setting up one or more generic chips for interrupt controllers
+  *      drivers using the generic chip library which uses this pointer.
++ * @dev: Pointer to a device that the domain represent, and that will be
++ *       used for power management purposes.
+  * @parent: Pointer to parent irq_domain to support hierarchy irq_domains
+  *
+  * Revmap data, used internally by irq_domain
+@@ -167,6 +169,7 @@ struct irq_domain {
+       struct fwnode_handle *fwnode;
+       enum irq_domain_bus_token bus_token;
+       struct irq_domain_chip_generic *gc;
++      struct device *dev;
+ #ifdef        CONFIG_IRQ_DOMAIN_HIERARCHY
+       struct irq_domain *parent;
+ #endif
+@@ -222,6 +225,13 @@ static inline struct device_node *irq_domain_get_of_node(struct irq_domain *d)
+       return to_of_node(d->fwnode);
+ }
++static inline void irq_domain_set_pm_device(struct irq_domain *d,
++                                          struct device *dev)
++{
++      if (d)
++              d->dev = dev;
++}
++
+ #ifdef CONFIG_IRQ_DOMAIN
+ struct fwnode_handle *__irq_domain_alloc_fwnode(unsigned int type, int id,
+                                               const char *name, phys_addr_t *pa);
+diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
+index f3920374f71ce..7ea66e55ef86b 100644
+--- a/kernel/irq/chip.c
++++ b/kernel/irq/chip.c
+@@ -1559,6 +1559,17 @@ int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+       return 0;
+ }
++static struct device *irq_get_parent_device(struct irq_data *data)
++{
++      if (data->chip->parent_device)
++              return data->chip->parent_device;
++
++      if (data->domain)
++              return data->domain->dev;
++
++      return NULL;
++}
++
+ /**
+  * irq_chip_pm_get - Enable power for an IRQ chip
+  * @data:     Pointer to interrupt specific data
+@@ -1568,12 +1579,13 @@ int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+  */
+ int irq_chip_pm_get(struct irq_data *data)
+ {
++      struct device *dev = irq_get_parent_device(data);
+       int retval;
+-      if (IS_ENABLED(CONFIG_PM) && data->chip->parent_device) {
+-              retval = pm_runtime_get_sync(data->chip->parent_device);
++      if (IS_ENABLED(CONFIG_PM) && dev) {
++              retval = pm_runtime_get_sync(dev);
+               if (retval < 0) {
+-                      pm_runtime_put_noidle(data->chip->parent_device);
++                      pm_runtime_put_noidle(dev);
+                       return retval;
+               }
+       }
+@@ -1591,10 +1603,11 @@ int irq_chip_pm_get(struct irq_data *data)
+  */
+ int irq_chip_pm_put(struct irq_data *data)
+ {
++      struct device *dev = irq_get_parent_device(data);
+       int retval = 0;
+-      if (IS_ENABLED(CONFIG_PM) && data->chip->parent_device)
+-              retval = pm_runtime_put(data->chip->parent_device);
++      if (IS_ENABLED(CONFIG_PM) && dev)
++              retval = pm_runtime_put(dev);
+       return (retval < 0) ? retval : 0;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.15/gpio-add-helpers-to-ease-the-transition-towards-immu.patch b/queue-5.15/gpio-add-helpers-to-ease-the-transition-towards-immu.patch
new file mode 100644 (file)
index 0000000..e8b8db2
--- /dev/null
@@ -0,0 +1,54 @@
+From c411d53be49d2d1077438662267c7f084dc3ba34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Apr 2022 15:18:39 +0100
+Subject: gpio: Add helpers to ease the transition towards immutable irq_chip
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit 36b78aae4bfee749bbde73be570796bfd0f56bec ]
+
+Add a couple of new helpers to make it slightly simpler to convert
+drivers to immutable irq_chip structures:
+
+- GPIOCHIP_IRQ_RESOURCE_HELPERS populates the irq_chip structure
+  with the resource management callbacks
+
+- gpio_irq_chip_set_chip() populates the gpio_irq_chip.chip
+  structure, avoiding the proliferation of ugly casts
+
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220419141846.598305-4-maz@kernel.org
+Stable-dep-of: 08af509efdf8 ("gpio: tqmx86: store IRQ trigger type and unmask status separately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/gpio/driver.h | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
+index b241fc23ff3a2..91f60d1e3eb31 100644
+--- a/include/linux/gpio/driver.h
++++ b/include/linux/gpio/driver.h
+@@ -599,6 +599,18 @@ void gpiochip_enable_irq(struct gpio_chip *gc, unsigned int offset);
+ int gpiochip_irq_reqres(struct irq_data *data);
+ void gpiochip_irq_relres(struct irq_data *data);
++/* Paste this in your irq_chip structure  */
++#define       GPIOCHIP_IRQ_RESOURCE_HELPERS                                   \
++              .irq_request_resources  = gpiochip_irq_reqres,          \
++              .irq_release_resources  = gpiochip_irq_relres
++
++static inline void gpio_irq_chip_set_chip(struct gpio_irq_chip *girq,
++                                        const struct irq_chip *chip)
++{
++      /* Yes, dropping const is ugly, but it isn't like we have a choice */
++      girq->chip = (struct irq_chip *)chip;
++}
++
+ /* Line status inquiry for drivers */
+ bool gpiochip_line_is_open_drain(struct gpio_chip *gc, unsigned int offset);
+ bool gpiochip_line_is_open_source(struct gpio_chip *gc, unsigned int offset);
+-- 
+2.43.0
+
diff --git a/queue-5.15/gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch b/queue-5.15/gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch
new file mode 100644 (file)
index 0000000..fc670b8
--- /dev/null
@@ -0,0 +1,89 @@
+From 2c04ad8df019c95f15df956c6a7e956d7c5aee2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Apr 2022 15:18:37 +0100
+Subject: gpio: Don't fiddle with irqchips marked as immutable
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit 6c846d026d490b2383d395bc8e7b06336219667b ]
+
+In order to move away from gpiolib messing with the internals of
+unsuspecting irqchips, add a flag by which irqchips advertise
+that they are not to be messed with, and do solemnly swear that
+they correctly call into the gpiolib helpers when required.
+
+Also nudge the users into converting their drivers to the
+new model.
+
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220419141846.598305-2-maz@kernel.org
+Stable-dep-of: 08af509efdf8 ("gpio: tqmx86: store IRQ trigger type and unmask status separately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpiolib.c | 7 ++++++-
+ include/linux/irq.h    | 2 ++
+ kernel/irq/debugfs.c   | 1 +
+ 3 files changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index 34a061b4becdb..bf77c3f5a4e56 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -1483,6 +1483,11 @@ static void gpiochip_set_irq_hooks(struct gpio_chip *gc)
+ {
+       struct irq_chip *irqchip = gc->irq.chip;
++      if (irqchip->flags & IRQCHIP_IMMUTABLE)
++              return;
++
++      chip_warn(gc, "not an immutable chip, please consider fixing it!\n");
++
+       if (!irqchip->irq_request_resources &&
+           !irqchip->irq_release_resources) {
+               irqchip->irq_request_resources = gpiochip_irq_reqres;
+@@ -1650,7 +1655,7 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gc)
+               irq_domain_remove(gc->irq.domain);
+       }
+-      if (irqchip) {
++      if (irqchip && !(irqchip->flags & IRQCHIP_IMMUTABLE)) {
+               if (irqchip->irq_request_resources == gpiochip_irq_reqres) {
+                       irqchip->irq_request_resources = NULL;
+                       irqchip->irq_release_resources = NULL;
+diff --git a/include/linux/irq.h b/include/linux/irq.h
+index f9e6449fbbbae..296ef3b7d7afa 100644
+--- a/include/linux/irq.h
++++ b/include/linux/irq.h
+@@ -570,6 +570,7 @@ struct irq_chip {
+  * IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND:  Invokes __enable_irq()/__disable_irq() for wake irqs
+  *                                    in the suspend path if they are in disabled state
+  * IRQCHIP_AFFINITY_PRE_STARTUP:      Default affinity update before startup
++ * IRQCHIP_IMMUTABLE:               Don't ever change anything in this chip
+  */
+ enum {
+       IRQCHIP_SET_TYPE_MASKED                 = (1 <<  0),
+@@ -583,6 +584,7 @@ enum {
+       IRQCHIP_SUPPORTS_NMI                    = (1 <<  8),
+       IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND        = (1 <<  9),
+       IRQCHIP_AFFINITY_PRE_STARTUP            = (1 << 10),
++      IRQCHIP_IMMUTABLE                       = (1 << 11),
+ };
+ #include <linux/irqdesc.h>
+diff --git a/kernel/irq/debugfs.c b/kernel/irq/debugfs.c
+index e4cff358b437e..7ff52d94b42c0 100644
+--- a/kernel/irq/debugfs.c
++++ b/kernel/irq/debugfs.c
+@@ -58,6 +58,7 @@ static const struct irq_bit_descr irqchip_flags[] = {
+       BIT_MASK_DESCR(IRQCHIP_SUPPORTS_LEVEL_MSI),
+       BIT_MASK_DESCR(IRQCHIP_SUPPORTS_NMI),
+       BIT_MASK_DESCR(IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND),
++      BIT_MASK_DESCR(IRQCHIP_IMMUTABLE),
+ };
+ static void
+-- 
+2.43.0
+
diff --git a/queue-5.15/gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch b/queue-5.15/gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch
new file mode 100644 (file)
index 0000000..c64b0d0
--- /dev/null
@@ -0,0 +1,70 @@
+From 334f6b83bffa3d0ea9e1849a3604a20adb5190a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Apr 2022 15:18:38 +0100
+Subject: gpio: Expose the gpiochip_irq_re[ql]res helpers
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit 704f08753b6dcd0e08c1953af0b2c7f3fac87111 ]
+
+The GPIO subsystem has a couple of internal helpers to manage
+resources on behalf of the irqchip. Expose them so that GPIO
+drivers can use them directly.
+
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220419141846.598305-3-maz@kernel.org
+Stable-dep-of: 08af509efdf8 ("gpio: tqmx86: store IRQ trigger type and unmask status separately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpiolib.c      | 6 ++++--
+ include/linux/gpio/driver.h | 4 ++++
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index bf77c3f5a4e56..9e91e7f9596d4 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -1431,19 +1431,21 @@ static int gpiochip_to_irq(struct gpio_chip *gc, unsigned int offset)
+       return irq_create_mapping(domain, offset);
+ }
+-static int gpiochip_irq_reqres(struct irq_data *d)
++int gpiochip_irq_reqres(struct irq_data *d)
+ {
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       return gpiochip_reqres_irq(gc, d->hwirq);
+ }
++EXPORT_SYMBOL(gpiochip_irq_reqres);
+-static void gpiochip_irq_relres(struct irq_data *d)
++void gpiochip_irq_relres(struct irq_data *d)
+ {
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       gpiochip_relres_irq(gc, d->hwirq);
+ }
++EXPORT_SYMBOL(gpiochip_irq_relres);
+ static void gpiochip_irq_mask(struct irq_data *d)
+ {
+diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
+index 65df2ce96f0b1..b241fc23ff3a2 100644
+--- a/include/linux/gpio/driver.h
++++ b/include/linux/gpio/driver.h
+@@ -595,6 +595,10 @@ void gpiochip_relres_irq(struct gpio_chip *gc, unsigned int offset);
+ void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset);
+ void gpiochip_enable_irq(struct gpio_chip *gc, unsigned int offset);
++/* irq_data versions of the above */
++int gpiochip_irq_reqres(struct irq_data *data);
++void gpiochip_irq_relres(struct irq_data *data);
++
+ /* Line status inquiry for drivers */
+ bool gpiochip_line_is_open_drain(struct gpio_chip *gc, unsigned int offset);
+ bool gpiochip_line_is_open_source(struct gpio_chip *gc, unsigned int offset);
+-- 
+2.43.0
+
diff --git a/queue-5.15/gpio-tpmx86-move-pm-device-over-to-irq-domain.patch b/queue-5.15/gpio-tpmx86-move-pm-device-over-to-irq-domain.patch
new file mode 100644 (file)
index 0000000..ca49070
--- /dev/null
@@ -0,0 +1,44 @@
+From 5152f2434b824ef78f204af311af419c45a7da21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Feb 2022 12:03:07 +0000
+Subject: gpio: tpmx86: Move PM device over to irq domain
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit 924610607f191bee4379bc3775b0fd025ad7e922 ]
+
+Move the reference to the device over to the irq domain.
+
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Acked-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Link: https://lore.kernel.org/r/20220201120310.878267-10-maz@kernel.org
+Stable-dep-of: 08af509efdf8 ("gpio: tqmx86: store IRQ trigger type and unmask status separately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-tqmx86.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c
+index 65184ad2df1a0..171d66fcd9096 100644
+--- a/drivers/gpio/gpio-tqmx86.c
++++ b/drivers/gpio/gpio-tqmx86.c
+@@ -283,7 +283,6 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
+               u8 irq_status;
+               irq_chip->name = chip->label;
+-              irq_chip->parent_device = &pdev->dev;
+               irq_chip->irq_mask = tqmx86_gpio_irq_mask;
+               irq_chip->irq_unmask = tqmx86_gpio_irq_unmask;
+               irq_chip->irq_set_type = tqmx86_gpio_irq_set_type;
+@@ -318,6 +317,8 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
+               goto out_pm_dis;
+       }
++      irq_domain_set_pm_device(girq->domain, dev);
++
+       dev_info(dev, "GPIO functionality initialized with %d pins\n",
+                chip->ngpio);
+-- 
+2.43.0
+
diff --git a/queue-5.15/gpio-tqmx86-convert-to-immutable-irq_chip.patch b/queue-5.15/gpio-tqmx86-convert-to-immutable-irq_chip.patch
new file mode 100644 (file)
index 0000000..9630972
--- /dev/null
@@ -0,0 +1,108 @@
+From a201198bf9e9221693f5911c94f96b7b5b72ee22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Mar 2023 10:55:12 +0100
+Subject: gpio: tqmx86: Convert to immutable irq_chip
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit 8e43827b6ae727a745ce7a8cc19184b28905a965 ]
+
+Convert the driver to immutable irq-chip with a bit of
+intuition.
+
+Cc: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Stable-dep-of: 08af509efdf8 ("gpio: tqmx86: store IRQ trigger type and unmask status separately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-tqmx86.c | 28 ++++++++++++++++++++--------
+ 1 file changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c
+index 171d66fcd9096..51a996d387b89 100644
+--- a/drivers/gpio/gpio-tqmx86.c
++++ b/drivers/gpio/gpio-tqmx86.c
+@@ -16,6 +16,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
++#include <linux/seq_file.h>
+ #include <linux/slab.h>
+ #define TQMX86_NGPIO  8
+@@ -35,7 +36,6 @@
+ struct tqmx86_gpio_data {
+       struct gpio_chip        chip;
+-      struct irq_chip         irq_chip;
+       void __iomem            *io_base;
+       int                     irq;
+       raw_spinlock_t          spinlock;
+@@ -119,6 +119,7 @@ static void tqmx86_gpio_irq_mask(struct irq_data *data)
+       gpiic &= ~mask;
+       tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
+       raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
++      gpiochip_disable_irq(&gpio->chip, irqd_to_hwirq(data));
+ }
+ static void tqmx86_gpio_irq_unmask(struct irq_data *data)
+@@ -131,6 +132,7 @@ static void tqmx86_gpio_irq_unmask(struct irq_data *data)
+       mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
++      gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(data));
+       raw_spin_lock_irqsave(&gpio->spinlock, flags);
+       gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
+       gpiic &= ~mask;
+@@ -223,6 +225,22 @@ static void tqmx86_init_irq_valid_mask(struct gpio_chip *chip,
+       clear_bit(3, valid_mask);
+ }
++static void tqmx86_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p)
++{
++      struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++
++      seq_printf(p, gc->label);
++}
++
++static const struct irq_chip tqmx86_gpio_irq_chip = {
++      .irq_mask = tqmx86_gpio_irq_mask,
++      .irq_unmask = tqmx86_gpio_irq_unmask,
++      .irq_set_type = tqmx86_gpio_irq_set_type,
++      .irq_print_chip = tqmx86_gpio_irq_print_chip,
++      .flags = IRQCHIP_IMMUTABLE,
++      GPIOCHIP_IRQ_RESOURCE_HELPERS,
++};
++
+ static int tqmx86_gpio_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -279,14 +297,8 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
+       pm_runtime_enable(&pdev->dev);
+       if (irq > 0) {
+-              struct irq_chip *irq_chip = &gpio->irq_chip;
+               u8 irq_status;
+-              irq_chip->name = chip->label;
+-              irq_chip->irq_mask = tqmx86_gpio_irq_mask;
+-              irq_chip->irq_unmask = tqmx86_gpio_irq_unmask;
+-              irq_chip->irq_set_type = tqmx86_gpio_irq_set_type;
+-
+               /* Mask all interrupts */
+               tqmx86_gpio_write(gpio, 0, TQMX86_GPIIC);
+@@ -295,7 +307,7 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
+               tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
+               girq = &chip->irq;
+-              girq->chip = irq_chip;
++              gpio_irq_chip_set_chip(girq, &tqmx86_gpio_irq_chip);
+               girq->parent_handler = tqmx86_gpio_irq_handler;
+               girq->num_parents = 1;
+               girq->parents = devm_kcalloc(&pdev->dev, 1,
+-- 
+2.43.0
+
diff --git a/queue-5.15/gpio-tqmx86-fix-broken-irq_type_edge_both-interrupt-.patch b/queue-5.15/gpio-tqmx86-fix-broken-irq_type_edge_both-interrupt-.patch
new file mode 100644 (file)
index 0000000..94eecef
--- /dev/null
@@ -0,0 +1,114 @@
+From 135e150c7b5356868851c3770f03ba6f820a6289 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 May 2024 12:20:02 +0200
+Subject: gpio: tqmx86: fix broken IRQ_TYPE_EDGE_BOTH interrupt type
+
+From: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+
+[ Upstream commit 90dd7de4ef7ba584823dfbeba834c2919a4bb55b ]
+
+The TQMx86 GPIO controller only supports falling and rising edge
+triggers, but not both. Fix this by implementing a software both-edge
+mode that toggles the edge type after every interrupt.
+
+Fixes: b868db94a6a7 ("gpio: tqmx86: Add GPIO from for this IO controller")
+Co-developed-by: Gregor Herburger <gregor.herburger@tq-group.com>
+Signed-off-by: Gregor Herburger <gregor.herburger@tq-group.com>
+Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+Link: https://lore.kernel.org/r/515324f0491c4d44f4ef49f170354aca002d81ef.1717063994.git.matthias.schiffer@ew.tq-group.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-tqmx86.c | 46 ++++++++++++++++++++++++++++++++++----
+ 1 file changed, 42 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c
+index 4040c1e870607..bb3304a4cb150 100644
+--- a/drivers/gpio/gpio-tqmx86.c
++++ b/drivers/gpio/gpio-tqmx86.c
+@@ -32,6 +32,10 @@
+ #define TQMX86_GPII_NONE      0
+ #define TQMX86_GPII_FALLING   BIT(0)
+ #define TQMX86_GPII_RISING    BIT(1)
++/* Stored in irq_type as a trigger type, but not actually valid as a register
++ * value, so the name doesn't use "GPII"
++ */
++#define TQMX86_INT_BOTH               (BIT(0) | BIT(1))
+ #define TQMX86_GPII_MASK      (BIT(0) | BIT(1))
+ #define TQMX86_GPII_BITS      2
+ /* Stored in irq_type with GPII bits */
+@@ -113,9 +117,15 @@ static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int offset)
+ {
+       u8 type = TQMX86_GPII_NONE, gpiic;
+-      if (gpio->irq_type[offset] & TQMX86_INT_UNMASKED)
++      if (gpio->irq_type[offset] & TQMX86_INT_UNMASKED) {
+               type = gpio->irq_type[offset] & TQMX86_GPII_MASK;
++              if (type == TQMX86_INT_BOTH)
++                      type = tqmx86_gpio_get(&gpio->chip, offset + TQMX86_NGPO)
++                              ? TQMX86_GPII_FALLING
++                              : TQMX86_GPII_RISING;
++      }
++
+       gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
+       gpiic &= ~(TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS));
+       gpiic |= type << (offset * TQMX86_GPII_BITS);
+@@ -169,7 +179,7 @@ static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
+               new_type = TQMX86_GPII_FALLING;
+               break;
+       case IRQ_TYPE_EDGE_BOTH:
+-              new_type = TQMX86_GPII_FALLING | TQMX86_GPII_RISING;
++              new_type = TQMX86_INT_BOTH;
+               break;
+       default:
+               return -EINVAL; /* not supported */
+@@ -189,8 +199,8 @@ static void tqmx86_gpio_irq_handler(struct irq_desc *desc)
+       struct gpio_chip *chip = irq_desc_get_handler_data(desc);
+       struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
+       struct irq_chip *irq_chip = irq_desc_get_chip(desc);
+-      unsigned long irq_bits;
+-      int i = 0;
++      unsigned long irq_bits, flags;
++      int i;
+       u8 irq_status;
+       chained_irq_enter(irq_chip, desc);
+@@ -199,6 +209,34 @@ static void tqmx86_gpio_irq_handler(struct irq_desc *desc)
+       tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
+       irq_bits = irq_status;
++
++      raw_spin_lock_irqsave(&gpio->spinlock, flags);
++      for_each_set_bit(i, &irq_bits, TQMX86_NGPI) {
++              /*
++               * Edge-both triggers are implemented by flipping the edge
++               * trigger after each interrupt, as the controller only supports
++               * either rising or falling edge triggers, but not both.
++               *
++               * Internally, the TQMx86 GPIO controller has separate status
++               * registers for rising and falling edge interrupts. GPIIC
++               * configures which bits from which register are visible in the
++               * interrupt status register GPIIS and defines what triggers the
++               * parent IRQ line. Writing to GPIIS always clears both rising
++               * and falling interrupt flags internally, regardless of the
++               * currently configured trigger.
++               *
++               * In consequence, we can cleanly implement the edge-both
++               * trigger in software by first clearing the interrupt and then
++               * setting the new trigger based on the current GPIO input in
++               * tqmx86_gpio_irq_config() - even if an edge arrives between
++               * reading the input and setting the trigger, we will have a new
++               * interrupt pending.
++               */
++              if ((gpio->irq_type[i] & TQMX86_GPII_MASK) == TQMX86_INT_BOTH)
++                      tqmx86_gpio_irq_config(gpio, i);
++      }
++      raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
++
+       for_each_set_bit(i, &irq_bits, TQMX86_NGPI)
+               generic_handle_domain_irq(gpio->chip.irq.domain,
+                                         i + TQMX86_NGPO);
+-- 
+2.43.0
+
diff --git a/queue-5.15/gpio-tqmx86-fix-typo-in-kconfig-label.patch b/queue-5.15/gpio-tqmx86-fix-typo-in-kconfig-label.patch
new file mode 100644 (file)
index 0000000..6c75d5f
--- /dev/null
@@ -0,0 +1,38 @@
+From ed4fd04406cca1ea310c050ffbe8951ac721f8d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 May 2024 12:19:59 +0200
+Subject: gpio: tqmx86: fix typo in Kconfig label
+
+From: Gregor Herburger <gregor.herburger@tq-group.com>
+
+[ Upstream commit 8c219e52ca4d9a67cd6a7074e91bf29b55edc075 ]
+
+Fix description for GPIO_TQMX86 from QTMX86 to TQMx86.
+
+Fixes: b868db94a6a7 ("gpio: tqmx86: Add GPIO from for this IO controller")
+Signed-off-by: Gregor Herburger <gregor.herburger@tq-group.com>
+Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/e0e38c9944ad6d281d9a662a45d289b88edc808e.1717063994.git.matthias.schiffer@ew.tq-group.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
+index 7b9def6b10047..a36afb47a6334 100644
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -1396,7 +1396,7 @@ config GPIO_TPS68470
+         drivers are loaded.
+ config GPIO_TQMX86
+-      tristate "TQ-Systems QTMX86 GPIO"
++      tristate "TQ-Systems TQMx86 GPIO"
+       depends on MFD_TQMX86 || COMPILE_TEST
+       depends on HAS_IOPORT_MAP
+       select GPIOLIB_IRQCHIP
+-- 
+2.43.0
+
diff --git a/queue-5.15/gpio-tqmx86-introduce-shadow-register-for-gpio-outpu.patch b/queue-5.15/gpio-tqmx86-introduce-shadow-register-for-gpio-outpu.patch
new file mode 100644 (file)
index 0000000..ae37469
--- /dev/null
@@ -0,0 +1,89 @@
+From 1cc4fa426d3b52405e0ad25e8145619bec69aac2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 May 2024 12:20:00 +0200
+Subject: gpio: tqmx86: introduce shadow register for GPIO output value
+
+From: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+
+[ Upstream commit 9d6a811b522ba558bcb4ec01d12e72a0af8e9f6e ]
+
+The TQMx86 GPIO controller uses the same register address for input and
+output data. Reading the register will always return current inputs
+rather than the previously set outputs (regardless of the current
+direction setting). Therefore, using a RMW pattern does not make sense
+when setting output values. Instead, the previously set output register
+value needs to be stored as a shadow register.
+
+As there is no reliable way to get the current output values from the
+hardware, also initialize all channels to 0, to ensure that stored and
+actual output values match. This should usually not have any effect in
+practise, as the TQMx86 UEFI sets all outputs to 0 during boot.
+
+Also prepare for extension of the driver to more than 8 GPIOs by using
+DECLARE_BITMAP.
+
+Fixes: b868db94a6a7 ("gpio: tqmx86: Add GPIO from for this IO controller")
+Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/d0555933becd45fa92a85675d26e4d59343ddc01.1717063994.git.matthias.schiffer@ew.tq-group.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-tqmx86.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c
+index db54f6c6c159b..65184ad2df1a0 100644
+--- a/drivers/gpio/gpio-tqmx86.c
++++ b/drivers/gpio/gpio-tqmx86.c
+@@ -6,6 +6,7 @@
+  *   Vadim V.Vlasov <vvlasov@dev.rtsoft.ru>
+  */
++#include <linux/bitmap.h>
+ #include <linux/bitops.h>
+ #include <linux/errno.h>
+ #include <linux/gpio/driver.h>
+@@ -38,6 +39,7 @@ struct tqmx86_gpio_data {
+       void __iomem            *io_base;
+       int                     irq;
+       raw_spinlock_t          spinlock;
++      DECLARE_BITMAP(output, TQMX86_NGPIO);
+       u8                      irq_type[TQMX86_NGPI];
+ };
+@@ -64,15 +66,10 @@ static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset,
+ {
+       struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
+       unsigned long flags;
+-      u8 val;
+       raw_spin_lock_irqsave(&gpio->spinlock, flags);
+-      val = tqmx86_gpio_read(gpio, TQMX86_GPIOD);
+-      if (value)
+-              val |= BIT(offset);
+-      else
+-              val &= ~BIT(offset);
+-      tqmx86_gpio_write(gpio, val, TQMX86_GPIOD);
++      __assign_bit(offset, gpio->output, value);
++      tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD);
+       raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
+ }
+@@ -259,6 +256,13 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
+       tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD);
++      /*
++       * Reading the previous output state is not possible with TQMx86 hardware.
++       * Initialize all outputs to 0 to have a defined state that matches the
++       * shadow register.
++       */
++      tqmx86_gpio_write(gpio, 0, TQMX86_GPIOD);
++
+       chip = &gpio->chip;
+       chip->label = "gpio-tqmx86";
+       chip->owner = THIS_MODULE;
+-- 
+2.43.0
+
diff --git a/queue-5.15/gpio-tqmx86-remove-unneeded-call-to-platform_set_drv.patch b/queue-5.15/gpio-tqmx86-remove-unneeded-call-to-platform_set_drv.patch
new file mode 100644 (file)
index 0000000..37146cf
--- /dev/null
@@ -0,0 +1,40 @@
+From 43f7494a9d3f5f4c7e14e1da229a8262775bf4e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 23:38:39 +0300
+Subject: gpio: tqmx86: remove unneeded call to platform_set_drvdata()
+
+From: Andrei Coardos <aboutphysycs@gmail.com>
+
+[ Upstream commit 0a5e9306b812fe3517548fab92b3d3d6ce7576e5 ]
+
+This function call was found to be unnecessary as there is no equivalent
+platform_get_drvdata() call to access the private data of the driver. Also,
+the private data is defined in this driver, so there is no risk of it being
+accessed outside of this driver file.
+
+Reviewed-by: Alexandru Ardelean <alex@shruggie.ro>
+Signed-off-by: Andrei Coardos <aboutphysycs@gmail.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Stable-dep-of: 9d6a811b522b ("gpio: tqmx86: introduce shadow register for GPIO output value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-tqmx86.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c
+index 5b103221b58dd..db54f6c6c159b 100644
+--- a/drivers/gpio/gpio-tqmx86.c
++++ b/drivers/gpio/gpio-tqmx86.c
+@@ -259,8 +259,6 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
+       tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD);
+-      platform_set_drvdata(pdev, gpio);
+-
+       chip = &gpio->chip;
+       chip->label = "gpio-tqmx86";
+       chip->owner = THIS_MODULE;
+-- 
+2.43.0
+
diff --git a/queue-5.15/gpio-tqmx86-store-irq-trigger-type-and-unmask-status.patch b/queue-5.15/gpio-tqmx86-store-irq-trigger-type-and-unmask-status.patch
new file mode 100644 (file)
index 0000000..7ceb27d
--- /dev/null
@@ -0,0 +1,137 @@
+From 5674c759de450d40158d8935e4f7dc431cd2bc03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 May 2024 12:20:01 +0200
+Subject: gpio: tqmx86: store IRQ trigger type and unmask status separately
+
+From: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+
+[ Upstream commit 08af509efdf8dad08e972b48de0e2c2a7919ea8b ]
+
+irq_set_type() should not implicitly unmask the IRQ.
+
+All accesses to the interrupt configuration register are moved to a new
+helper tqmx86_gpio_irq_config(). We also introduce the new rule that
+accessing irq_type must happen while locked, which will become
+significant for fixing EDGE_BOTH handling.
+
+Fixes: b868db94a6a7 ("gpio: tqmx86: Add GPIO from for this IO controller")
+Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+Link: https://lore.kernel.org/r/6aa4f207f77cb58ef64ffb947e91949b0f753ccd.1717063994.git.matthias.schiffer@ew.tq-group.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-tqmx86.c | 48 ++++++++++++++++++++++----------------
+ 1 file changed, 28 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c
+index 51a996d387b89..4040c1e870607 100644
+--- a/drivers/gpio/gpio-tqmx86.c
++++ b/drivers/gpio/gpio-tqmx86.c
+@@ -29,15 +29,19 @@
+ #define TQMX86_GPIIC  3       /* GPI Interrupt Configuration Register */
+ #define TQMX86_GPIIS  4       /* GPI Interrupt Status Register */
++#define TQMX86_GPII_NONE      0
+ #define TQMX86_GPII_FALLING   BIT(0)
+ #define TQMX86_GPII_RISING    BIT(1)
+ #define TQMX86_GPII_MASK      (BIT(0) | BIT(1))
+ #define TQMX86_GPII_BITS      2
++/* Stored in irq_type with GPII bits */
++#define TQMX86_INT_UNMASKED   BIT(2)
+ struct tqmx86_gpio_data {
+       struct gpio_chip        chip;
+       void __iomem            *io_base;
+       int                     irq;
++      /* Lock must be held for accessing output and irq_type fields */
+       raw_spinlock_t          spinlock;
+       DECLARE_BITMAP(output, TQMX86_NGPIO);
+       u8                      irq_type[TQMX86_NGPI];
+@@ -104,21 +108,32 @@ static int tqmx86_gpio_get_direction(struct gpio_chip *chip,
+       return GPIO_LINE_DIRECTION_OUT;
+ }
++static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int offset)
++      __must_hold(&gpio->spinlock)
++{
++      u8 type = TQMX86_GPII_NONE, gpiic;
++
++      if (gpio->irq_type[offset] & TQMX86_INT_UNMASKED)
++              type = gpio->irq_type[offset] & TQMX86_GPII_MASK;
++
++      gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
++      gpiic &= ~(TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS));
++      gpiic |= type << (offset * TQMX86_GPII_BITS);
++      tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
++}
++
+ static void tqmx86_gpio_irq_mask(struct irq_data *data)
+ {
+       unsigned int offset = (data->hwirq - TQMX86_NGPO);
+       struct tqmx86_gpio_data *gpio = gpiochip_get_data(
+               irq_data_get_irq_chip_data(data));
+       unsigned long flags;
+-      u8 gpiic, mask;
+-
+-      mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
+       raw_spin_lock_irqsave(&gpio->spinlock, flags);
+-      gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
+-      gpiic &= ~mask;
+-      tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
++      gpio->irq_type[offset] &= ~TQMX86_INT_UNMASKED;
++      tqmx86_gpio_irq_config(gpio, offset);
+       raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
++
+       gpiochip_disable_irq(&gpio->chip, irqd_to_hwirq(data));
+ }
+@@ -128,16 +143,12 @@ static void tqmx86_gpio_irq_unmask(struct irq_data *data)
+       struct tqmx86_gpio_data *gpio = gpiochip_get_data(
+               irq_data_get_irq_chip_data(data));
+       unsigned long flags;
+-      u8 gpiic, mask;
+-
+-      mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
+       gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(data));
++
+       raw_spin_lock_irqsave(&gpio->spinlock, flags);
+-      gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
+-      gpiic &= ~mask;
+-      gpiic |= gpio->irq_type[offset] << (offset * TQMX86_GPII_BITS);
+-      tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
++      gpio->irq_type[offset] |= TQMX86_INT_UNMASKED;
++      tqmx86_gpio_irq_config(gpio, offset);
+       raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
+ }
+@@ -148,7 +159,7 @@ static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
+       unsigned int offset = (data->hwirq - TQMX86_NGPO);
+       unsigned int edge_type = type & IRQF_TRIGGER_MASK;
+       unsigned long flags;
+-      u8 new_type, gpiic;
++      u8 new_type;
+       switch (edge_type) {
+       case IRQ_TYPE_EDGE_RISING:
+@@ -164,13 +175,10 @@ static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
+               return -EINVAL; /* not supported */
+       }
+-      gpio->irq_type[offset] = new_type;
+-
+       raw_spin_lock_irqsave(&gpio->spinlock, flags);
+-      gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
+-      gpiic &= ~((TQMX86_GPII_MASK) << (offset * TQMX86_GPII_BITS));
+-      gpiic |= new_type << (offset * TQMX86_GPII_BITS);
+-      tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
++      gpio->irq_type[offset] &= ~TQMX86_GPII_MASK;
++      gpio->irq_type[offset] |= new_type;
++      tqmx86_gpio_irq_config(gpio, offset);
+       raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
+       return 0;
+-- 
+2.43.0
+
diff --git a/queue-5.15/hid-core-remove-unnecessary-warn_on-in-implement.patch b/queue-5.15/hid-core-remove-unnecessary-warn_on-in-implement.patch
new file mode 100644 (file)
index 0000000..ea0ef41
--- /dev/null
@@ -0,0 +1,67 @@
+From 51aaefc1d1ab2f15a66613782a903452bec2d068 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 May 2024 07:19:14 -0700
+Subject: HID: core: remove unnecessary WARN_ON() in implement()
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit 4aa2dcfbad538adf7becd0034a3754e1bd01b2b5 ]
+
+Syzkaller hit a warning [1] in a call to implement() when trying
+to write a value into a field of smaller size in an output report.
+
+Since implement() already has a warn message printed out with the
+help of hid_warn() and value in question gets trimmed with:
+       ...
+       value &= m;
+       ...
+WARN_ON may be considered superfluous. Remove it to suppress future
+syzkaller triggers.
+
+[1]
+WARNING: CPU: 0 PID: 5084 at drivers/hid/hid-core.c:1451 implement drivers/hid/hid-core.c:1451 [inline]
+WARNING: CPU: 0 PID: 5084 at drivers/hid/hid-core.c:1451 hid_output_report+0x548/0x760 drivers/hid/hid-core.c:1863
+Modules linked in:
+CPU: 0 PID: 5084 Comm: syz-executor424 Not tainted 6.9.0-rc7-syzkaller-00183-gcf87f46fd34d #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/02/2024
+RIP: 0010:implement drivers/hid/hid-core.c:1451 [inline]
+RIP: 0010:hid_output_report+0x548/0x760 drivers/hid/hid-core.c:1863
+...
+Call Trace:
+ <TASK>
+ __usbhid_submit_report drivers/hid/usbhid/hid-core.c:591 [inline]
+ usbhid_submit_report+0x43d/0x9e0 drivers/hid/usbhid/hid-core.c:636
+ hiddev_ioctl+0x138b/0x1f00 drivers/hid/usbhid/hiddev.c:726
+ vfs_ioctl fs/ioctl.c:51 [inline]
+ __do_sys_ioctl fs/ioctl.c:904 [inline]
+ __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:890
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xf5/0x240 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+...
+
+Fixes: 95d1c8951e5b ("HID: simplify implement() a bit")
+Reported-by: <syzbot+5186630949e3c55f0799@syzkaller.appspotmail.com>
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-core.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index 7b76405df8c47..15f4a80477974 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1446,7 +1446,6 @@ static void implement(const struct hid_device *hid, u8 *report,
+                       hid_warn(hid,
+                                "%s() called with too large value %d (n: %d)! (%s)\n",
+                                __func__, value, n, current->comm);
+-                      WARN_ON(1);
+                       value &= m;
+               }
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.15/hid-logitech-dj-fix-memory-leak-in-logi_dj_recv_swit.patch b/queue-5.15/hid-logitech-dj-fix-memory-leak-in-logi_dj_recv_swit.patch
new file mode 100644 (file)
index 0000000..e0343a6
--- /dev/null
@@ -0,0 +1,41 @@
+From e630a9ab88af5ad535d621e72679246cae1c5856 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 May 2024 15:05:39 +0200
+Subject: HID: logitech-dj: Fix memory leak in logi_dj_recv_switch_to_dj_mode()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit ce3af2ee95170b7d9e15fff6e500d67deab1e7b3 ]
+
+Fix a memory leak on logi_dj_recv_send_report() error path.
+
+Fixes: 6f20d3261265 ("HID: logitech-dj: Fix error handling in logi_dj_recv_switch_to_dj_mode()")
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 57697605b2e24..dc7b0fe83478e 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1284,8 +1284,10 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
+                */
+               msleep(50);
+-              if (retval)
++              if (retval) {
++                      kfree(dj_report);
+                       return retval;
++              }
+       }
+       /*
+-- 
+2.43.0
+
diff --git a/queue-5.15/iommu-amd-fix-sysfs-leak-in-iommu-init.patch b/queue-5.15/iommu-amd-fix-sysfs-leak-in-iommu-init.patch
new file mode 100644 (file)
index 0000000..0c74c1f
--- /dev/null
@@ -0,0 +1,47 @@
+From 6d050ef8b631ec4a1ff11d0569a3e91bf7daba77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 May 2024 08:42:20 +0800
+Subject: iommu/amd: Fix sysfs leak in iommu init
+
+From: Kun(llfl) <llfl@linux.alibaba.com>
+
+[ Upstream commit a295ec52c8624883885396fde7b4df1a179627c3 ]
+
+During the iommu initialization, iommu_init_pci() adds sysfs nodes.
+However, these nodes aren't remove in free_iommu_resources() subsequently.
+
+Fixes: 39ab9555c241 ("iommu: Add sysfs bindings for struct iommu_device")
+Signed-off-by: Kun(llfl) <llfl@linux.alibaba.com>
+Reviewed-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Link: https://lore.kernel.org/r/c8e0d11c6ab1ee48299c288009cf9c5dae07b42d.1715215003.git.llfl@linux.alibaba.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/init.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index 724874ad0b2a8..70f3720d96c7e 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -1493,8 +1493,17 @@ static void __init free_pci_segments(void)
+       }
+ }
++static void __init free_sysfs(struct amd_iommu *iommu)
++{
++      if (iommu->iommu.dev) {
++              iommu_device_unregister(&iommu->iommu);
++              iommu_device_sysfs_remove(&iommu->iommu);
++      }
++}
++
+ static void __init free_iommu_one(struct amd_iommu *iommu)
+ {
++      free_sysfs(iommu);
+       free_cwwb_sem(iommu);
+       free_command_buffer(iommu);
+       free_event_buffer(iommu);
+-- 
+2.43.0
+
diff --git a/queue-5.15/iommu-amd-introduce-pci-segment-structure.patch b/queue-5.15/iommu-amd-introduce-pci-segment-structure.patch
new file mode 100644 (file)
index 0000000..22cef35
--- /dev/null
@@ -0,0 +1,182 @@
+From 2a83d6932ba008c6467f59189097400c433b49f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 17:07:52 +0530
+Subject: iommu/amd: Introduce pci segment structure
+
+From: Vasant Hegde <vasant.hegde@amd.com>
+
+[ Upstream commit 404ec4e4c169fb64da6b2a38b471c13ac0897c76 ]
+
+Newer AMD systems can support multiple PCI segments, where each segment
+contains one or more IOMMU instances. However, an IOMMU instance can only
+support a single PCI segment.
+
+Current code assumes that system contains only one pci segment (segment 0)
+and creates global data structures such as device table, rlookup table,
+etc.
+
+Introducing per PCI segment data structure, which contains segment
+specific data structures. This will eventually replace the global
+data structures.
+
+Also update `amd_iommu->pci_seg` variable to point to PCI segment
+structure instead of PCI segment ID.
+
+Co-developed-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
+Link: https://lore.kernel.org/r/20220706113825.25582-3-vasant.hegde@amd.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Stable-dep-of: a295ec52c862 ("iommu/amd: Fix sysfs leak in iommu init")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/amd_iommu_types.h | 24 ++++++++++++++-
+ drivers/iommu/amd/init.c            | 46 ++++++++++++++++++++++++++++-
+ 2 files changed, 68 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
+index 390f10060c82b..2dc025acad4ce 100644
+--- a/drivers/iommu/amd/amd_iommu_types.h
++++ b/drivers/iommu/amd/amd_iommu_types.h
+@@ -450,6 +450,11 @@ extern bool amd_iommu_irq_remap;
+ /* kmem_cache to get tables with 128 byte alignement */
+ extern struct kmem_cache *amd_iommu_irq_cache;
++/* Make iterating over all pci segment easier */
++#define for_each_pci_segment(pci_seg) \
++      list_for_each_entry((pci_seg), &amd_iommu_pci_seg_list, list)
++#define for_each_pci_segment_safe(pci_seg, next) \
++      list_for_each_entry_safe((pci_seg), (next), &amd_iommu_pci_seg_list, list)
+ /*
+  * Make iterating over all IOMMUs easier
+  */
+@@ -524,6 +529,17 @@ struct protection_domain {
+       unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
+ };
++/*
++ * This structure contains information about one PCI segment in the system.
++ */
++struct amd_iommu_pci_seg {
++      /* List with all PCI segments in the system */
++      struct list_head list;
++
++      /* PCI segment number */
++      u16 id;
++};
++
+ /*
+  * Structure where we save information about one hardware AMD IOMMU in the
+  * system.
+@@ -575,7 +591,7 @@ struct amd_iommu {
+       u16 cap_ptr;
+       /* pci domain of this IOMMU */
+-      u16 pci_seg;
++      struct amd_iommu_pci_seg *pci_seg;
+       /* start of exclusion range of that IOMMU */
+       u64 exclusion_start;
+@@ -703,6 +719,12 @@ extern struct list_head ioapic_map;
+ extern struct list_head hpet_map;
+ extern struct list_head acpihid_map;
++/*
++ * List with all PCI segments in the system. This list is not locked because
++ * it is only written at driver initialization time
++ */
++extern struct list_head amd_iommu_pci_seg_list;
++
+ /*
+  * List with all IOMMUs in the system. This list is not locked because it is
+  * only written and read at driver initialization or suspend time
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index ef855495c210e..724874ad0b2a8 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -167,6 +167,7 @@ u16 amd_iommu_last_bdf;                    /* largest PCI device id we have
+ LIST_HEAD(amd_iommu_unity_map);               /* a list of required unity mappings
+                                          we find in ACPI */
++LIST_HEAD(amd_iommu_pci_seg_list);    /* list of all PCI segments */
+ LIST_HEAD(amd_iommu_list);            /* list of all AMD IOMMUs in the
+                                          system */
+@@ -1455,6 +1456,43 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
+       return 0;
+ }
++/* Allocate PCI segment data structure */
++static struct amd_iommu_pci_seg *__init alloc_pci_segment(u16 id)
++{
++      struct amd_iommu_pci_seg *pci_seg;
++
++      pci_seg = kzalloc(sizeof(struct amd_iommu_pci_seg), GFP_KERNEL);
++      if (pci_seg == NULL)
++              return NULL;
++
++      pci_seg->id = id;
++      list_add_tail(&pci_seg->list, &amd_iommu_pci_seg_list);
++
++      return pci_seg;
++}
++
++static struct amd_iommu_pci_seg *__init get_pci_segment(u16 id)
++{
++      struct amd_iommu_pci_seg *pci_seg;
++
++      for_each_pci_segment(pci_seg) {
++              if (pci_seg->id == id)
++                      return pci_seg;
++      }
++
++      return alloc_pci_segment(id);
++}
++
++static void __init free_pci_segments(void)
++{
++      struct amd_iommu_pci_seg *pci_seg, *next;
++
++      for_each_pci_segment_safe(pci_seg, next) {
++              list_del(&pci_seg->list);
++              kfree(pci_seg);
++      }
++}
++
+ static void __init free_iommu_one(struct amd_iommu *iommu)
+ {
+       free_cwwb_sem(iommu);
+@@ -1541,8 +1579,14 @@ static void amd_iommu_ats_write_check_workaround(struct amd_iommu *iommu)
+  */
+ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
+ {
++      struct amd_iommu_pci_seg *pci_seg;
+       int ret;
++      pci_seg = get_pci_segment(h->pci_seg);
++      if (pci_seg == NULL)
++              return -ENOMEM;
++      iommu->pci_seg = pci_seg;
++
+       raw_spin_lock_init(&iommu->lock);
+       iommu->cmd_sem_val = 0;
+@@ -1563,7 +1607,6 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
+        */
+       iommu->devid   = h->devid;
+       iommu->cap_ptr = h->cap_ptr;
+-      iommu->pci_seg = h->pci_seg;
+       iommu->mmio_phys = h->mmio_phys;
+       switch (h->type) {
+@@ -2604,6 +2647,7 @@ static void __init free_iommu_resources(void)
+       amd_iommu_dev_table = NULL;
+       free_iommu_all();
++      free_pci_segments();
+ }
+ /* SB IOAPIC is always on this device in AMD systems */
+-- 
+2.43.0
+
diff --git a/queue-5.15/iommu-return-right-value-in-iommu_sva_bind_device.patch b/queue-5.15/iommu-return-right-value-in-iommu_sva_bind_device.patch
new file mode 100644 (file)
index 0000000..46268e6
--- /dev/null
@@ -0,0 +1,49 @@
+From 1afa576abc5de325c428ebd33db3cd80c98e0c49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 May 2024 12:25:28 +0800
+Subject: iommu: Return right value in iommu_sva_bind_device()
+
+From: Lu Baolu <baolu.lu@linux.intel.com>
+
+[ Upstream commit 89e8a2366e3bce584b6c01549d5019c5cda1205e ]
+
+iommu_sva_bind_device() should return either a sva bond handle or an
+ERR_PTR value in error cases. Existing drivers (idxd and uacce) only
+check the return value with IS_ERR(). This could potentially lead to
+a kernel NULL pointer dereference issue if the function returns NULL
+instead of an error pointer.
+
+In reality, this doesn't cause any problems because iommu_sva_bind_device()
+only returns NULL when the kernel is not configured with CONFIG_IOMMU_SVA.
+In this case, iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_SVA) will
+return an error, and the device drivers won't call iommu_sva_bind_device()
+at all.
+
+Fixes: 26b25a2b98e4 ("iommu: Bind process address spaces to devices")
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Reviewed-by: Vasant Hegde <vasant.hegde@amd.com>
+Link: https://lore.kernel.org/r/20240528042528.71396-1-baolu.lu@linux.intel.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/iommu.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/iommu.h b/include/linux/iommu.h
+index d2f3435e7d176..2202a665b0927 100644
+--- a/include/linux/iommu.h
++++ b/include/linux/iommu.h
+@@ -1038,7 +1038,7 @@ iommu_aux_get_pasid(struct iommu_domain *domain, struct device *dev)
+ static inline struct iommu_sva *
+ iommu_sva_bind_device(struct device *dev, struct mm_struct *mm, void *drvdata)
+ {
+-      return NULL;
++      return ERR_PTR(-ENODEV);
+ }
+ static inline void iommu_sva_unbind_device(struct iommu_sva *handle)
+-- 
+2.43.0
+
diff --git a/queue-5.15/ionic-fix-use-after-netif_napi_del.patch b/queue-5.15/ionic-fix-use-after-netif_napi_del.patch
new file mode 100644 (file)
index 0000000..f248005
--- /dev/null
@@ -0,0 +1,97 @@
+From 7e10fa2573433e04b4d9e5c557fc4db3180ab7db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jun 2024 06:04:46 +0000
+Subject: ionic: fix use after netif_napi_del()
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 79f18a41dd056115d685f3b0a419c7cd40055e13 ]
+
+When queues are started, netif_napi_add() and napi_enable() are called.
+If there are 4 queues and only 3 queues are used for the current
+configuration, only 3 queues' napi should be registered and enabled.
+The ionic_qcq_enable() checks whether the .poll pointer is not NULL for
+enabling only the using queue' napi. Unused queues' napi will not be
+registered by netif_napi_add(), so the .poll pointer indicates NULL.
+But it couldn't distinguish whether the napi was unregistered or not
+because netif_napi_del() doesn't reset the .poll pointer to NULL.
+So, ionic_qcq_enable() calls napi_enable() for the queue, which was
+unregistered by netif_napi_del().
+
+Reproducer:
+   ethtool -L <interface name> rx 1 tx 1 combined 0
+   ethtool -L <interface name> rx 0 tx 0 combined 1
+   ethtool -L <interface name> rx 0 tx 0 combined 4
+
+Splat looks like:
+kernel BUG at net/core/dev.c:6666!
+Oops: invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
+CPU: 3 PID: 1057 Comm: kworker/3:3 Not tainted 6.10.0-rc2+ #16
+Workqueue: events ionic_lif_deferred_work [ionic]
+RIP: 0010:napi_enable+0x3b/0x40
+Code: 48 89 c2 48 83 e2 f6 80 b9 61 09 00 00 00 74 0d 48 83 bf 60 01 00 00 00 74 03 80 ce 01 f0 4f
+RSP: 0018:ffffb6ed83227d48 EFLAGS: 00010246
+RAX: 0000000000000000 RBX: ffff97560cda0828 RCX: 0000000000000029
+RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff97560cda0a28
+RBP: ffffb6ed83227d50 R08: 0000000000000400 R09: 0000000000000001
+R10: 0000000000000001 R11: 0000000000000001 R12: 0000000000000000
+R13: ffff97560ce3c1a0 R14: 0000000000000000 R15: ffff975613ba0a20
+FS:  0000000000000000(0000) GS:ffff975d5f780000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f8f734ee200 CR3: 0000000103e50000 CR4: 00000000007506f0
+PKRU: 55555554
+Call Trace:
+ <TASK>
+ ? die+0x33/0x90
+ ? do_trap+0xd9/0x100
+ ? napi_enable+0x3b/0x40
+ ? do_error_trap+0x83/0xb0
+ ? napi_enable+0x3b/0x40
+ ? napi_enable+0x3b/0x40
+ ? exc_invalid_op+0x4e/0x70
+ ? napi_enable+0x3b/0x40
+ ? asm_exc_invalid_op+0x16/0x20
+ ? napi_enable+0x3b/0x40
+ ionic_qcq_enable+0xb7/0x180 [ionic 59bdfc8a035436e1c4224ff7d10789e3f14643f8]
+ ionic_start_queues+0xc4/0x290 [ionic 59bdfc8a035436e1c4224ff7d10789e3f14643f8]
+ ionic_link_status_check+0x11c/0x170 [ionic 59bdfc8a035436e1c4224ff7d10789e3f14643f8]
+ ionic_lif_deferred_work+0x129/0x280 [ionic 59bdfc8a035436e1c4224ff7d10789e3f14643f8]
+ process_one_work+0x145/0x360
+ worker_thread+0x2bb/0x3d0
+ ? __pfx_worker_thread+0x10/0x10
+ kthread+0xcc/0x100
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x2d/0x50
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1a/0x30
+
+Fixes: 0f3154e6bcb3 ("ionic: Add Tx and Rx handling")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Reviewed-by: Brett Creeley <brett.creeley@amd.com>
+Reviewed-by: Shannon Nelson <shannon.nelson@amd.com>
+Link: https://lore.kernel.org/r/20240612060446.1754392-1-ap420073@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/pensando/ionic/ionic_lif.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+index 1f84ba638e6eb..b791fba82c2fd 100644
+--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
++++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+@@ -283,10 +283,8 @@ static int ionic_qcq_enable(struct ionic_qcq *qcq)
+       if (ret)
+               return ret;
+-      if (qcq->napi.poll)
+-              napi_enable(&qcq->napi);
+-
+       if (qcq->flags & IONIC_QCQ_F_INTR) {
++              napi_enable(&qcq->napi);
+               irq_set_affinity_hint(qcq->intr.vector,
+                                     &qcq->intr.affinity_mask);
+               ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
+-- 
+2.43.0
+
diff --git a/queue-5.15/kernel.h-split-out-container_of-and-typeof_member-ma.patch b/queue-5.15/kernel.h-split-out-container_of-and-typeof_member-ma.patch
new file mode 100644 (file)
index 0000000..44606a1
--- /dev/null
@@ -0,0 +1,153 @@
+From 6d7a7df8c8f8f6f5a5572b4d451c594a7e57b7a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Nov 2021 18:32:12 -0800
+Subject: kernel.h: split out container_of() and typeof_member() macros
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit d2a8ebbf8192b84b11f1b204c4f7c602df32aeac ]
+
+kernel.h is being used as a dump for all kinds of stuff for a long time.
+Here is the attempt cleaning it up by splitting out container_of() and
+typeof_member() macros.
+
+For time being include new header back to kernel.h to avoid twisted
+indirected includes for existing users.
+
+Note, there are _a lot_ of headers and modules that include kernel.h
+solely for one of these macros and this allows to unburden compiler for
+the twisted inclusion paths and to make new code cleaner in the future.
+
+Link: https://lkml.kernel.org/r/20211013170417.87909-3-andriy.shevchenko@linux.intel.com
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: Boqun Feng <boqun.feng@gmail.com>
+Cc: Brendan Higgins <brendanhiggins@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jonathan Cameron <jic23@kernel.org>
+Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
+Cc: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Thorsten Leemhuis <regressions@leemhuis.info>
+Cc: Waiman Long <longman@redhat.com>
+Cc: Will Deacon <will@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: 1981b296f858 ("platform/x86: dell-smbios: Fix wrong token data in sysfs")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/container_of.h | 40 ++++++++++++++++++++++++++++++++++++
+ include/linux/kernel.h       | 33 +----------------------------
+ 2 files changed, 41 insertions(+), 32 deletions(-)
+ create mode 100644 include/linux/container_of.h
+
+diff --git a/include/linux/container_of.h b/include/linux/container_of.h
+new file mode 100644
+index 0000000000000..dd56019838c67
+--- /dev/null
++++ b/include/linux/container_of.h
+@@ -0,0 +1,40 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef _LINUX_CONTAINER_OF_H
++#define _LINUX_CONTAINER_OF_H
++
++#include <linux/build_bug.h>
++#include <linux/err.h>
++
++#define typeof_member(T, m)   typeof(((T*)0)->m)
++
++/**
++ * container_of - cast a member of a structure out to the containing structure
++ * @ptr:      the pointer to the member.
++ * @type:     the type of the container struct this is embedded in.
++ * @member:   the name of the member within the struct.
++ *
++ */
++#define container_of(ptr, type, member) ({                            \
++      void *__mptr = (void *)(ptr);                                   \
++      BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) &&   \
++                       !__same_type(*(ptr), void),                    \
++                       "pointer type mismatch in container_of()");    \
++      ((type *)(__mptr - offsetof(type, member))); })
++
++/**
++ * container_of_safe - cast a member of a structure out to the containing structure
++ * @ptr:      the pointer to the member.
++ * @type:     the type of the container struct this is embedded in.
++ * @member:   the name of the member within the struct.
++ *
++ * If IS_ERR_OR_NULL(ptr), ptr is returned unchanged.
++ */
++#define container_of_safe(ptr, type, member) ({                               \
++      void *__mptr = (void *)(ptr);                                   \
++      BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) &&   \
++                       !__same_type(*(ptr), void),                    \
++                       "pointer type mismatch in container_of()");    \
++      IS_ERR_OR_NULL(__mptr) ? ERR_CAST(__mptr) :                     \
++              ((type *)(__mptr - offsetof(type, member))); })
++
++#endif        /* _LINUX_CONTAINER_OF_H */
+diff --git a/include/linux/kernel.h b/include/linux/kernel.h
+index f56cd8879a594..568da581f2bac 100644
+--- a/include/linux/kernel.h
++++ b/include/linux/kernel.h
+@@ -9,6 +9,7 @@
+ #include <linux/stddef.h>
+ #include <linux/types.h>
+ #include <linux/compiler.h>
++#include <linux/container_of.h>
+ #include <linux/bitops.h>
+ #include <linux/kstrtox.h>
+ #include <linux/log2.h>
+@@ -52,8 +53,6 @@
+ }                                     \
+ )
+-#define typeof_member(T, m)   typeof(((T*)0)->m)
+-
+ #define _RET_IP_              (unsigned long)__builtin_return_address(0)
+ #define _THIS_IP_  ({ __label__ __here; __here: (unsigned long)&&__here; })
+@@ -483,36 +482,6 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
+ #define __CONCAT(a, b) a ## b
+ #define CONCATENATE(a, b) __CONCAT(a, b)
+-/**
+- * container_of - cast a member of a structure out to the containing structure
+- * @ptr:      the pointer to the member.
+- * @type:     the type of the container struct this is embedded in.
+- * @member:   the name of the member within the struct.
+- *
+- */
+-#define container_of(ptr, type, member) ({                            \
+-      void *__mptr = (void *)(ptr);                                   \
+-      BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) &&   \
+-                       !__same_type(*(ptr), void),                    \
+-                       "pointer type mismatch in container_of()");    \
+-      ((type *)(__mptr - offsetof(type, member))); })
+-
+-/**
+- * container_of_safe - cast a member of a structure out to the containing structure
+- * @ptr:      the pointer to the member.
+- * @type:     the type of the container struct this is embedded in.
+- * @member:   the name of the member within the struct.
+- *
+- * If IS_ERR_OR_NULL(ptr), ptr is returned unchanged.
+- */
+-#define container_of_safe(ptr, type, member) ({                               \
+-      void *__mptr = (void *)(ptr);                                   \
+-      BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) &&   \
+-                       !__same_type(*(ptr), void),                    \
+-                       "pointer type mismatch in container_of()");    \
+-      IS_ERR_OR_NULL(__mptr) ? ERR_CAST(__mptr) :                     \
+-              ((type *)(__mptr - offsetof(type, member))); })
+-
+ /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */
+ #ifdef CONFIG_FTRACE_MCOUNT_RECORD
+ # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD
+-- 
+2.43.0
+
diff --git a/queue-5.15/liquidio-adjust-a-null-pointer-handling-path-in-lio_.patch b/queue-5.15/liquidio-adjust-a-null-pointer-handling-path-in-lio_.patch
new file mode 100644 (file)
index 0000000..4059126
--- /dev/null
@@ -0,0 +1,69 @@
+From c4758fe3d587e1218b52109b67210243a20dbda6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jun 2024 13:11:35 +0300
+Subject: liquidio: Adjust a NULL pointer handling path in
+ lio_vf_rep_copy_packet
+
+From: Aleksandr Mishin <amishin@t-argos.ru>
+
+[ Upstream commit c44711b78608c98a3e6b49ce91678cd0917d5349 ]
+
+In lio_vf_rep_copy_packet() pg_info->page is compared to a NULL value,
+but then it is unconditionally passed to skb_add_rx_frag() which looks
+strange and could lead to null pointer dereference.
+
+lio_vf_rep_copy_packet() call trace looks like:
+       octeon_droq_process_packets
+        octeon_droq_fast_process_packets
+         octeon_droq_dispatch_pkt
+          octeon_create_recv_info
+           ...search in the dispatch_list...
+            ->disp_fn(rdisp->rinfo, ...)
+             lio_vf_rep_pkt_recv(struct octeon_recv_info *recv_info, ...)
+In this path there is no code which sets pg_info->page to NULL.
+So this check looks unneeded and doesn't solve potential problem.
+But I guess the author had reason to add a check and I have no such card
+and can't do real test.
+In addition, the code in the function liquidio_push_packet() in
+liquidio/lio_core.c does exactly the same.
+
+Based on this, I consider the most acceptable compromise solution to
+adjust this issue by moving skb_add_rx_frag() into conditional scope.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 1f233f327913 ("liquidio: switchdev support for LiquidIO NIC")
+Signed-off-by: Aleksandr Mishin <amishin@t-argos.ru>
+Reviewed-by: Simon Horman <horms@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_vf_rep.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c
+index 600de587d7a98..e70b9ccca380e 100644
+--- a/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c
++++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c
+@@ -272,13 +272,12 @@ lio_vf_rep_copy_packet(struct octeon_device *oct,
+                               pg_info->page_offset;
+                       memcpy(skb->data, va, MIN_SKB_SIZE);
+                       skb_put(skb, MIN_SKB_SIZE);
++                      skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
++                                      pg_info->page,
++                                      pg_info->page_offset + MIN_SKB_SIZE,
++                                      len - MIN_SKB_SIZE,
++                                      LIO_RXBUFFER_SZ);
+               }
+-
+-              skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
+-                              pg_info->page,
+-                              pg_info->page_offset + MIN_SKB_SIZE,
+-                              len - MIN_SKB_SIZE,
+-                              LIO_RXBUFFER_SZ);
+       } else {
+               struct octeon_skb_page_info *pg_info =
+                       ((struct octeon_skb_page_info *)(skb->cb));
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-geneve-support-ipv4-ipv6-as-inner-protocol.patch b/queue-5.15/net-geneve-support-ipv4-ipv6-as-inner-protocol.patch
new file mode 100644 (file)
index 0000000..3458fd6
--- /dev/null
@@ -0,0 +1,237 @@
+From 22a477d9afb27913859c9a0b757f579b0ec260e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Mar 2022 08:15:57 +0200
+Subject: net: geneve: support IPv4/IPv6 as inner protocol
+
+From: Eyal Birger <eyal.birger@gmail.com>
+
+[ Upstream commit 435fe1c0c1f74b682dba85641406abf4337aade6 ]
+
+This patch adds support for encapsulating IPv4/IPv6 within GENEVE.
+
+In order to use this, a new IFLA_GENEVE_INNER_PROTO_INHERIT flag needs
+to be provided at device creation. This property cannot be changed for
+the time being.
+
+In case IP traffic is received on a non-tun device the drop count is
+increased.
+
+Signed-off-by: Eyal Birger <eyal.birger@gmail.com>
+Link: https://lore.kernel.org/r/20220316061557.431872-1-eyal.birger@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: c6ae073f5903 ("geneve: Fix incorrect inner network header offset when innerprotoinherit is set")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/geneve.c         | 82 +++++++++++++++++++++++++++---------
+ include/uapi/linux/if_link.h |  1 +
+ 2 files changed, 64 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
+index 0e4ea3c0fe829..3f076dadff78b 100644
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -55,6 +55,7 @@ struct geneve_config {
+       bool                    use_udp6_rx_checksums;
+       bool                    ttl_inherit;
+       enum ifla_geneve_df     df;
++      bool                    inner_proto_inherit;
+ };
+ /* Pseudo network device */
+@@ -250,17 +251,24 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs,
+               }
+       }
+-      skb_reset_mac_header(skb);
+-      skb->protocol = eth_type_trans(skb, geneve->dev);
+-      skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
+-
+       if (tun_dst)
+               skb_dst_set(skb, &tun_dst->dst);
+-      /* Ignore packet loops (and multicast echo) */
+-      if (ether_addr_equal(eth_hdr(skb)->h_source, geneve->dev->dev_addr)) {
+-              geneve->dev->stats.rx_errors++;
+-              goto drop;
++      if (gnvh->proto_type == htons(ETH_P_TEB)) {
++              skb_reset_mac_header(skb);
++              skb->protocol = eth_type_trans(skb, geneve->dev);
++              skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
++
++              /* Ignore packet loops (and multicast echo) */
++              if (ether_addr_equal(eth_hdr(skb)->h_source,
++                                   geneve->dev->dev_addr)) {
++                      geneve->dev->stats.rx_errors++;
++                      goto drop;
++              }
++      } else {
++              skb_reset_mac_header(skb);
++              skb->dev = geneve->dev;
++              skb->pkt_type = PACKET_HOST;
+       }
+       /* Save offset of outer header relative to skb->head,
+@@ -358,6 +366,7 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
+       struct genevehdr *geneveh;
+       struct geneve_dev *geneve;
+       struct geneve_sock *gs;
++      __be16 inner_proto;
+       int opts_len;
+       /* Need UDP and Geneve header to be present */
+@@ -369,7 +378,11 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
+       if (unlikely(geneveh->ver != GENEVE_VER))
+               goto drop;
+-      if (unlikely(geneveh->proto_type != htons(ETH_P_TEB)))
++      inner_proto = geneveh->proto_type;
++
++      if (unlikely((inner_proto != htons(ETH_P_TEB) &&
++                    inner_proto != htons(ETH_P_IP) &&
++                    inner_proto != htons(ETH_P_IPV6))))
+               goto drop;
+       gs = rcu_dereference_sk_user_data(sk);
+@@ -380,9 +393,14 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
+       if (!geneve)
+               goto drop;
++      if (unlikely((!geneve->cfg.inner_proto_inherit &&
++                    inner_proto != htons(ETH_P_TEB)))) {
++              geneve->dev->stats.rx_dropped++;
++              goto drop;
++      }
++
+       opts_len = geneveh->opt_len * 4;
+-      if (iptunnel_pull_header(skb, GENEVE_BASE_HLEN + opts_len,
+-                               htons(ETH_P_TEB),
++      if (iptunnel_pull_header(skb, GENEVE_BASE_HLEN + opts_len, inner_proto,
+                                !net_eq(geneve->net, dev_net(geneve->dev)))) {
+               geneve->dev->stats.rx_dropped++;
+               goto drop;
+@@ -736,7 +754,8 @@ static int geneve_stop(struct net_device *dev)
+ }
+ static void geneve_build_header(struct genevehdr *geneveh,
+-                              const struct ip_tunnel_info *info)
++                              const struct ip_tunnel_info *info,
++                              __be16 inner_proto)
+ {
+       geneveh->ver = GENEVE_VER;
+       geneveh->opt_len = info->options_len / 4;
+@@ -744,7 +763,7 @@ static void geneve_build_header(struct genevehdr *geneveh,
+       geneveh->critical = !!(info->key.tun_flags & TUNNEL_CRIT_OPT);
+       geneveh->rsvd1 = 0;
+       tunnel_id_to_vni(info->key.tun_id, geneveh->vni);
+-      geneveh->proto_type = htons(ETH_P_TEB);
++      geneveh->proto_type = inner_proto;
+       geneveh->rsvd2 = 0;
+       if (info->key.tun_flags & TUNNEL_GENEVE_OPT)
+@@ -753,10 +772,12 @@ static void geneve_build_header(struct genevehdr *geneveh,
+ static int geneve_build_skb(struct dst_entry *dst, struct sk_buff *skb,
+                           const struct ip_tunnel_info *info,
+-                          bool xnet, int ip_hdr_len)
++                          bool xnet, int ip_hdr_len,
++                          bool inner_proto_inherit)
+ {
+       bool udp_sum = !!(info->key.tun_flags & TUNNEL_CSUM);
+       struct genevehdr *gnvh;
++      __be16 inner_proto;
+       int min_headroom;
+       int err;
+@@ -774,8 +795,9 @@ static int geneve_build_skb(struct dst_entry *dst, struct sk_buff *skb,
+               goto free_dst;
+       gnvh = __skb_push(skb, sizeof(*gnvh) + info->options_len);
+-      geneve_build_header(gnvh, info);
+-      skb_set_inner_protocol(skb, htons(ETH_P_TEB));
++      inner_proto = inner_proto_inherit ? skb->protocol : htons(ETH_P_TEB);
++      geneve_build_header(gnvh, info, inner_proto);
++      skb_set_inner_protocol(skb, inner_proto);
+       return 0;
+ free_dst:
+@@ -981,7 +1003,8 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+               }
+       }
+-      err = geneve_build_skb(&rt->dst, skb, info, xnet, sizeof(struct iphdr));
++      err = geneve_build_skb(&rt->dst, skb, info, xnet, sizeof(struct iphdr),
++                             geneve->cfg.inner_proto_inherit);
+       if (unlikely(err))
+               return err;
+@@ -1060,7 +1083,8 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+                       ttl = key->ttl;
+               ttl = ttl ? : ip6_dst_hoplimit(dst);
+       }
+-      err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr));
++      err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr),
++                             geneve->cfg.inner_proto_inherit);
+       if (unlikely(err))
+               return err;
+@@ -1410,6 +1434,14 @@ static int geneve_configure(struct net *net, struct net_device *dev,
+       dst_cache_reset(&geneve->cfg.info.dst_cache);
+       memcpy(&geneve->cfg, cfg, sizeof(*cfg));
++      if (geneve->cfg.inner_proto_inherit) {
++              dev->header_ops = NULL;
++              dev->type = ARPHRD_NONE;
++              dev->hard_header_len = 0;
++              dev->addr_len = 0;
++              dev->flags = IFF_NOARP;
++      }
++
+       err = register_netdevice(dev);
+       if (err)
+               return err;
+@@ -1583,10 +1615,18 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
+ #endif
+       }
++      if (data[IFLA_GENEVE_INNER_PROTO_INHERIT]) {
++              if (changelink) {
++                      attrtype = IFLA_GENEVE_INNER_PROTO_INHERIT;
++                      goto change_notsup;
++              }
++              cfg->inner_proto_inherit = true;
++      }
++
+       return 0;
+ change_notsup:
+       NL_SET_ERR_MSG_ATTR(extack, data[attrtype],
+-                          "Changing VNI, Port, endpoint IP address family, external, and UDP checksum attributes are not supported");
++                          "Changing VNI, Port, endpoint IP address family, external, inner_proto_inherit, and UDP checksum attributes are not supported");
+       return -EOPNOTSUPP;
+ }
+@@ -1821,6 +1861,10 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev)
+       if (nla_put_u8(skb, IFLA_GENEVE_TTL_INHERIT, ttl_inherit))
+               goto nla_put_failure;
++      if (geneve->cfg.inner_proto_inherit &&
++          nla_put_flag(skb, IFLA_GENEVE_INNER_PROTO_INHERIT))
++              goto nla_put_failure;
++
+       return 0;
+ nla_put_failure:
+diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
+index 4ac53b30b6dc9..cc126982fa3c0 100644
+--- a/include/uapi/linux/if_link.h
++++ b/include/uapi/linux/if_link.h
+@@ -776,6 +776,7 @@ enum {
+       IFLA_GENEVE_LABEL,
+       IFLA_GENEVE_TTL_INHERIT,
+       IFLA_GENEVE_DF,
++      IFLA_GENEVE_INNER_PROTO_INHERIT,
+       __IFLA_GENEVE_MAX
+ };
+ #define IFLA_GENEVE_MAX       (__IFLA_GENEVE_MAX - 1)
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-hns3-add-cond_resched-to-hns3-ring-buffer-init-p.patch b/queue-5.15/net-hns3-add-cond_resched-to-hns3-ring-buffer-init-p.patch
new file mode 100644 (file)
index 0000000..e9383fc
--- /dev/null
@@ -0,0 +1,64 @@
+From d6e7a1dc2a3f83b1b26bca4ae31a9175f5c96ba6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jun 2024 15:20:58 +0800
+Subject: net: hns3: add cond_resched() to hns3 ring buffer init process
+
+From: Jie Wang <wangjie125@huawei.com>
+
+[ Upstream commit 968fde83841a8c23558dfbd0a0c69d636db52b55 ]
+
+Currently hns3 ring buffer init process would hold cpu too long with big
+Tx/Rx ring depth. This could cause soft lockup.
+
+So this patch adds cond_resched() to the process. Then cpu can break to
+run other tasks instead of busy looping.
+
+Fixes: a723fb8efe29 ("net: hns3: refine for set ring parameters")
+Signed-off-by: Jie Wang <wangjie125@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 4 ++++
+ drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 2 ++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+index bbbafd8aa1b09..e48d33927c176 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -3342,6 +3342,9 @@ static int hns3_alloc_ring_buffers(struct hns3_enet_ring *ring)
+               ret = hns3_alloc_and_attach_buffer(ring, i);
+               if (ret)
+                       goto out_buffer_fail;
++
++              if (!(i % HNS3_RESCHED_BD_NUM))
++                      cond_resched();
+       }
+       return 0;
+@@ -4887,6 +4890,7 @@ int hns3_init_all_ring(struct hns3_nic_priv *priv)
+               }
+               u64_stats_init(&priv->ring[i].syncp);
++              cond_resched();
+       }
+       return 0;
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+index 91b656adaacb0..f60ba2ee8b8b1 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+@@ -206,6 +206,8 @@ enum hns3_nic_state {
+ #define HNS3_CQ_MODE_EQE                      1U
+ #define HNS3_CQ_MODE_CQE                      0U
++#define HNS3_RESCHED_BD_NUM                   1024
++
+ enum hns3_pkt_l2t_type {
+       HNS3_L2_TYPE_UNICAST,
+       HNS3_L2_TYPE_MULTICAST,
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-hns3-fix-kernel-crash-problem-in-concurrent-scen.patch b/queue-5.15/net-hns3-fix-kernel-crash-problem-in-concurrent-scen.patch
new file mode 100644 (file)
index 0000000..f9894a7
--- /dev/null
@@ -0,0 +1,84 @@
+From 2b94bb07aa977d96b2e70439dc6c7e38f1a51fbc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jun 2024 15:20:57 +0800
+Subject: net: hns3: fix kernel crash problem in concurrent scenario
+
+From: Yonglong Liu <liuyonglong@huawei.com>
+
+[ Upstream commit 12cda920212a49fa22d9e8b9492ac4ea013310a4 ]
+
+When link status change, the nic driver need to notify the roce
+driver to handle this event, but at this time, the roce driver
+may uninit, then cause kernel crash.
+
+To fix the problem, when link status change, need to check
+whether the roce registered, and when uninit, need to wait link
+update finish.
+
+Fixes: 45e92b7e4e27 ("net: hns3: add calling roce callback function when link status change")
+Signed-off-by: Yonglong Liu <liuyonglong@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../hisilicon/hns3/hns3pf/hclge_main.c        | 21 ++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index d58048b056781..c3690e49c3d95 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -2948,9 +2948,7 @@ static void hclge_push_link_status(struct hclge_dev *hdev)
+ static void hclge_update_link_status(struct hclge_dev *hdev)
+ {
+-      struct hnae3_handle *rhandle = &hdev->vport[0].roce;
+       struct hnae3_handle *handle = &hdev->vport[0].nic;
+-      struct hnae3_client *rclient = hdev->roce_client;
+       struct hnae3_client *client = hdev->nic_client;
+       int state;
+       int ret;
+@@ -2974,8 +2972,15 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
+               client->ops->link_status_change(handle, state);
+               hclge_config_mac_tnl_int(hdev, state);
+-              if (rclient && rclient->ops->link_status_change)
+-                      rclient->ops->link_status_change(rhandle, state);
++
++              if (test_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state)) {
++                      struct hnae3_handle *rhandle = &hdev->vport[0].roce;
++                      struct hnae3_client *rclient = hdev->roce_client;
++
++                      if (rclient && rclient->ops->link_status_change)
++                              rclient->ops->link_status_change(rhandle,
++                                                               state);
++              }
+               hclge_push_link_status(hdev);
+       }
+@@ -11431,6 +11436,12 @@ static int hclge_init_client_instance(struct hnae3_client *client,
+       return ret;
+ }
++static bool hclge_uninit_need_wait(struct hclge_dev *hdev)
++{
++      return test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) ||
++             test_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state);
++}
++
+ static void hclge_uninit_client_instance(struct hnae3_client *client,
+                                        struct hnae3_ae_dev *ae_dev)
+ {
+@@ -11439,7 +11450,7 @@ static void hclge_uninit_client_instance(struct hnae3_client *client,
+       if (hdev->roce_client) {
+               clear_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state);
+-              while (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
++              while (hclge_uninit_need_wait(hdev))
+                       msleep(HCLGE_WAIT_RESET_DONE);
+               hdev->roce_client->ops->uninit_instance(&vport->roce, 0);
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-ipv6-fix-the-rt-cache-flush-via-sysctl-using-a-p.patch b/queue-5.15/net-ipv6-fix-the-rt-cache-flush-via-sysctl-using-a-p.patch
new file mode 100644 (file)
index 0000000..204b93c
--- /dev/null
@@ -0,0 +1,53 @@
+From 94792a7caf3a613a7ac689c35604766c65219690 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jun 2024 13:28:28 +0200
+Subject: net/ipv6: Fix the RT cache flush via sysctl using a previous delay
+
+From: Petr Pavlu <petr.pavlu@suse.com>
+
+[ Upstream commit 14a20e5b4ad998793c5f43b0330d9e1388446cf3 ]
+
+The net.ipv6.route.flush system parameter takes a value which specifies
+a delay used during the flush operation for aging exception routes. The
+written value is however not used in the currently requested flush and
+instead utilized only in the next one.
+
+A problem is that ipv6_sysctl_rtcache_flush() first reads the old value
+of net->ipv6.sysctl.flush_delay into a local delay variable and then
+calls proc_dointvec() which actually updates the sysctl based on the
+provided input.
+
+Fix the problem by switching the order of the two operations.
+
+Fixes: 4990509f19e8 ("[NETNS][IPV6]: Make sysctls route per namespace.")
+Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://lore.kernel.org/r/20240607112828.30285-1-petr.pavlu@suse.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 2c60270c5798b..0ca3da0999c6a 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -6346,12 +6346,12 @@ static int ipv6_sysctl_rtcache_flush(struct ctl_table *ctl, int write,
+       if (!write)
+               return -EINVAL;
+-      net = (struct net *)ctl->extra1;
+-      delay = net->ipv6.sysctl.flush_delay;
+       ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+       if (ret)
+               return ret;
++      net = (struct net *)ctl->extra1;
++      delay = net->ipv6.sysctl.flush_delay;
+       fib6_run_gc(delay <= 0 ? 0 : (unsigned long)delay, net, delay > 0);
+       return 0;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-mlx5e-fix-features-validation-check-for-tunneled.patch b/queue-5.15/net-mlx5e-fix-features-validation-check-for-tunneled.patch
new file mode 100644 (file)
index 0000000..c2e08ef
--- /dev/null
@@ -0,0 +1,53 @@
+From 948110cffd5f7005b5f07298eea0df700fe02def Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jun 2024 23:32:49 +0300
+Subject: net/mlx5e: Fix features validation check for tunneled UDP (non-VXLAN)
+ packets
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 791b4089e326271424b78f2fae778b20e53d071b ]
+
+Move the vxlan_features_check() call to after we verified the packet is
+a tunneled VXLAN packet.
+
+Without this, tunneled UDP non-VXLAN packets (for ex. GENENVE) might
+wrongly not get offloaded.
+In some cases, it worked by chance as GENEVE header is the same size as
+VXLAN, but it is obviously incorrect.
+
+Fixes: e3cfc7e6b7bd ("net/mlx5e: TX, Add geneve tunnel stateless offload support")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 79d687c663d54..a0870da414538 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -3989,7 +3989,7 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
+               /* Verify if UDP port is being offloaded by HW */
+               if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, port))
+-                      return features;
++                      return vxlan_features_check(skb, features);
+ #if IS_ENABLED(CONFIG_GENEVE)
+               /* Support Geneve offload for default UDP port */
+@@ -4015,7 +4015,6 @@ netdev_features_t mlx5e_features_check(struct sk_buff *skb,
+       struct mlx5e_priv *priv = netdev_priv(netdev);
+       features = vlan_features_check(skb, features);
+-      features = vxlan_features_check(skb, features);
+       /* Validate if the tunneled packet is being offloaded by HW */
+       if (skb->encapsulation &&
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-sfp-always-call-sfp_sm_mod_remove-on-remove.patch b/queue-5.15/net-sfp-always-call-sfp_sm_mod_remove-on-remove.patch
new file mode 100644 (file)
index 0000000..2e9bb08
--- /dev/null
@@ -0,0 +1,45 @@
+From db3f89d4899858a2780ccbcaaf5b44b0e155beb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jun 2024 10:42:51 +0200
+Subject: net: sfp: Always call `sfp_sm_mod_remove()` on remove
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Csókás, Bence <csokas.bence@prolan.hu>
+
+[ Upstream commit e96b2933152fd87b6a41765b2f58b158fde855b6 ]
+
+If the module is in SFP_MOD_ERROR, `sfp_sm_mod_remove()` will
+not be run. As a consequence, `sfp_hwmon_remove()` is not getting
+run either, leaving a stale `hwmon` device behind. `sfp_sm_mod_remove()`
+itself checks `sfp->sm_mod_state` anyways, so this check was not
+really needed in the first place.
+
+Fixes: d2e816c0293f ("net: sfp: handle module remove outside state machine")
+Signed-off-by: "Csókás, Bence" <csokas.bence@prolan.hu>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/20240605084251.63502-1-csokas.bence@prolan.hu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/sfp.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
+index d5918605eae6f..2bb30d635bbca 100644
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -2004,8 +2004,7 @@ static void sfp_sm_module(struct sfp *sfp, unsigned int event)
+       /* Handle remove event globally, it resets this state machine */
+       if (event == SFP_E_REMOVE) {
+-              if (sfp->sm_mod_state > SFP_MOD_PROBE)
+-                      sfp_sm_mod_remove(sfp);
++              sfp_sm_mod_remove(sfp);
+               sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0);
+               return;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-stmmac-replace-priv-speed-with-the-porttransmitr.patch b/queue-5.15/net-stmmac-replace-priv-speed-with-the-porttransmitr.patch
new file mode 100644 (file)
index 0000000..fef35ae
--- /dev/null
@@ -0,0 +1,101 @@
+From 986c1b3d501857dbffd83e8a71980335aa280af2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Jun 2024 22:35:24 +0800
+Subject: net: stmmac: replace priv->speed with the portTransmitRate from the
+ tc-cbs parameters
+
+From: Xiaolei Wang <xiaolei.wang@windriver.com>
+
+[ Upstream commit be27b896529787e23a35ae4befb6337ce73fcca0 ]
+
+The current cbs parameter depends on speed after uplinking,
+which is not needed and will report a configuration error
+if the port is not initially connected. The UAPI exposed by
+tc-cbs requires userspace to recalculate the send slope anyway,
+because the formula depends on port_transmit_rate (see man tc-cbs),
+which is not an invariant from tc's perspective. Therefore, we
+use offload->sendslope and offload->idleslope to derive the
+original port_transmit_rate from the CBS formula.
+
+Fixes: 1f705bc61aee ("net: stmmac: Add support for CBS QDISC")
+Signed-off-by: Xiaolei Wang <xiaolei.wang@windriver.com>
+Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Link: https://lore.kernel.org/r/20240608143524.2065736-1-xiaolei.wang@windriver.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/stmicro/stmmac/stmmac_tc.c   | 25 ++++++++-----------
+ 1 file changed, 11 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
+index 08cffc0558743..a9b5f5ad1bac4 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
+@@ -341,10 +341,11 @@ static int tc_setup_cbs(struct stmmac_priv *priv,
+                       struct tc_cbs_qopt_offload *qopt)
+ {
+       u32 tx_queues_count = priv->plat->tx_queues_to_use;
++      s64 port_transmit_rate_kbps;
+       u32 queue = qopt->queue;
+-      u32 ptr, speed_div;
+       u32 mode_to_use;
+       u64 value;
++      u32 ptr;
+       int ret;
+       /* Queue 0 is not AVB capable */
+@@ -353,30 +354,26 @@ static int tc_setup_cbs(struct stmmac_priv *priv,
+       if (!priv->dma_cap.av)
+               return -EOPNOTSUPP;
++      port_transmit_rate_kbps = qopt->idleslope - qopt->sendslope;
++
+       /* Port Transmit Rate and Speed Divider */
+-      switch (priv->speed) {
++      switch (div_s64(port_transmit_rate_kbps, 1000)) {
+       case SPEED_10000:
+-              ptr = 32;
+-              speed_div = 10000000;
+-              break;
+       case SPEED_5000:
+               ptr = 32;
+-              speed_div = 5000000;
+               break;
+       case SPEED_2500:
+-              ptr = 8;
+-              speed_div = 2500000;
+-              break;
+       case SPEED_1000:
+               ptr = 8;
+-              speed_div = 1000000;
+               break;
+       case SPEED_100:
+               ptr = 4;
+-              speed_div = 100000;
+               break;
+       default:
+-              return -EOPNOTSUPP;
++              netdev_err(priv->dev,
++                         "Invalid portTransmitRate %lld (idleSlope - sendSlope)\n",
++                         port_transmit_rate_kbps);
++              return -EINVAL;
+       }
+       mode_to_use = priv->plat->tx_queues_cfg[queue].mode_to_use;
+@@ -396,10 +393,10 @@ static int tc_setup_cbs(struct stmmac_priv *priv,
+       }
+       /* Final adjustments for HW */
+-      value = div_s64(qopt->idleslope * 1024ll * ptr, speed_div);
++      value = div_s64(qopt->idleslope * 1024ll * ptr, port_transmit_rate_kbps);
+       priv->plat->tx_queues_cfg[queue].idle_slope = value & GENMASK(31, 0);
+-      value = div_s64(-qopt->sendslope * 1024ll * ptr, speed_div);
++      value = div_s64(-qopt->sendslope * 1024ll * ptr, port_transmit_rate_kbps);
+       priv->plat->tx_queues_cfg[queue].send_slope = value & GENMASK(31, 0);
+       value = qopt->hicredit * 1024ll * 8;
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-ipset-fix-race-between-namespace-cleanup-a.patch b/queue-5.15/netfilter-ipset-fix-race-between-namespace-cleanup-a.patch
new file mode 100644 (file)
index 0000000..ad9a567
--- /dev/null
@@ -0,0 +1,289 @@
+From e6ce1ecf7124e8d5d84072cf8d5ff1c9521f86a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Jun 2024 15:58:03 +0200
+Subject: netfilter: ipset: Fix race between namespace cleanup and gc in the
+ list:set type
+
+From: Jozsef Kadlecsik <kadlec@netfilter.org>
+
+[ Upstream commit 4e7aaa6b82d63e8ddcbfb56b4fd3d014ca586f10 ]
+
+Lion Ackermann reported that there is a race condition between namespace cleanup
+in ipset and the garbage collection of the list:set type. The namespace
+cleanup can destroy the list:set type of sets while the gc of the set type is
+waiting to run in rcu cleanup. The latter uses data from the destroyed set which
+thus leads use after free. The patch contains the following parts:
+
+- When destroying all sets, first remove the garbage collectors, then wait
+  if needed and then destroy the sets.
+- Fix the badly ordered "wait then remove gc" for the destroy a single set
+  case.
+- Fix the missing rcu locking in the list:set type in the userspace test
+  case.
+- Use proper RCU list handlings in the list:set type.
+
+The patch depends on c1193d9bbbd3 (netfilter: ipset: Add list flush to cancel_gc).
+
+Fixes: 97f7cf1cd80e (netfilter: ipset: fix performance regression in swap operation)
+Reported-by: Lion Ackermann <nnamrec@gmail.com>
+Tested-by: Lion Ackermann <nnamrec@gmail.com>
+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_core.c     | 81 +++++++++++++++------------
+ net/netfilter/ipset/ip_set_list_set.c | 30 +++++-----
+ 2 files changed, 60 insertions(+), 51 deletions(-)
+
+diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
+index 01cedf416b10a..8819c28a0e491 100644
+--- a/net/netfilter/ipset/ip_set_core.c
++++ b/net/netfilter/ipset/ip_set_core.c
+@@ -1174,23 +1174,50 @@ ip_set_setname_policy[IPSET_ATTR_CMD_MAX + 1] = {
+                                   .len = IPSET_MAXNAMELEN - 1 },
+ };
++/* In order to return quickly when destroying a single set, it is split
++ * into two stages:
++ * - Cancel garbage collector
++ * - Destroy the set itself via call_rcu()
++ */
++
+ static void
+-ip_set_destroy_set(struct ip_set *set)
++ip_set_destroy_set_rcu(struct rcu_head *head)
+ {
+-      pr_debug("set: %s\n",  set->name);
++      struct ip_set *set = container_of(head, struct ip_set, rcu);
+-      /* Must call it without holding any lock */
+       set->variant->destroy(set);
+       module_put(set->type->me);
+       kfree(set);
+ }
+ static void
+-ip_set_destroy_set_rcu(struct rcu_head *head)
++_destroy_all_sets(struct ip_set_net *inst)
+ {
+-      struct ip_set *set = container_of(head, struct ip_set, rcu);
++      struct ip_set *set;
++      ip_set_id_t i;
++      bool need_wait = false;
+-      ip_set_destroy_set(set);
++      /* First cancel gc's: set:list sets are flushed as well */
++      for (i = 0; i < inst->ip_set_max; i++) {
++              set = ip_set(inst, i);
++              if (set) {
++                      set->variant->cancel_gc(set);
++                      if (set->type->features & IPSET_TYPE_NAME)
++                              need_wait = true;
++              }
++      }
++      /* Must wait for flush to be really finished  */
++      if (need_wait)
++              rcu_barrier();
++      for (i = 0; i < inst->ip_set_max; i++) {
++              set = ip_set(inst, i);
++              if (set) {
++                      ip_set(inst, i) = NULL;
++                      set->variant->destroy(set);
++                      module_put(set->type->me);
++                      kfree(set);
++              }
++      }
+ }
+ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
+@@ -1204,11 +1231,10 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
+       if (unlikely(protocol_min_failed(attr)))
+               return -IPSET_ERR_PROTOCOL;
+-
+       /* Commands are serialized and references are
+        * protected by the ip_set_ref_lock.
+        * External systems (i.e. xt_set) must call
+-       * ip_set_put|get_nfnl_* functions, that way we
++       * ip_set_nfnl_get_* functions, that way we
+        * can safely check references here.
+        *
+        * list:set timer can only decrement the reference
+@@ -1216,8 +1242,6 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
+        * without holding the lock.
+        */
+       if (!attr[IPSET_ATTR_SETNAME]) {
+-              /* Must wait for flush to be really finished in list:set */
+-              rcu_barrier();
+               read_lock_bh(&ip_set_ref_lock);
+               for (i = 0; i < inst->ip_set_max; i++) {
+                       s = ip_set(inst, i);
+@@ -1228,15 +1252,7 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
+               }
+               inst->is_destroyed = true;
+               read_unlock_bh(&ip_set_ref_lock);
+-              for (i = 0; i < inst->ip_set_max; i++) {
+-                      s = ip_set(inst, i);
+-                      if (s) {
+-                              ip_set(inst, i) = NULL;
+-                              /* Must cancel garbage collectors */
+-                              s->variant->cancel_gc(s);
+-                              ip_set_destroy_set(s);
+-                      }
+-              }
++              _destroy_all_sets(inst);
+               /* Modified by ip_set_destroy() only, which is serialized */
+               inst->is_destroyed = false;
+       } else {
+@@ -1257,12 +1273,12 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
+               features = s->type->features;
+               ip_set(inst, i) = NULL;
+               read_unlock_bh(&ip_set_ref_lock);
++              /* Must cancel garbage collectors */
++              s->variant->cancel_gc(s);
+               if (features & IPSET_TYPE_NAME) {
+                       /* Must wait for flush to be really finished  */
+                       rcu_barrier();
+               }
+-              /* Must cancel garbage collectors */
+-              s->variant->cancel_gc(s);
+               call_rcu(&s->rcu, ip_set_destroy_set_rcu);
+       }
+       return 0;
+@@ -2365,30 +2381,25 @@ ip_set_net_init(struct net *net)
+ }
+ static void __net_exit
+-ip_set_net_exit(struct net *net)
++ip_set_net_pre_exit(struct net *net)
+ {
+       struct ip_set_net *inst = ip_set_pernet(net);
+-      struct ip_set *set = NULL;
+-      ip_set_id_t i;
+-
+       inst->is_deleted = true; /* flag for ip_set_nfnl_put */
++}
+-      nfnl_lock(NFNL_SUBSYS_IPSET);
+-      for (i = 0; i < inst->ip_set_max; i++) {
+-              set = ip_set(inst, i);
+-              if (set) {
+-                      ip_set(inst, i) = NULL;
+-                      set->variant->cancel_gc(set);
+-                      ip_set_destroy_set(set);
+-              }
+-      }
+-      nfnl_unlock(NFNL_SUBSYS_IPSET);
++static void __net_exit
++ip_set_net_exit(struct net *net)
++{
++      struct ip_set_net *inst = ip_set_pernet(net);
++
++      _destroy_all_sets(inst);
+       kvfree(rcu_dereference_protected(inst->ip_set_list, 1));
+ }
+ static struct pernet_operations ip_set_net_ops = {
+       .init   = ip_set_net_init,
++      .pre_exit = ip_set_net_pre_exit,
+       .exit   = ip_set_net_exit,
+       .id     = &ip_set_net_id,
+       .size   = sizeof(struct ip_set_net),
+diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c
+index 6bc7019982b05..e839c356bcb56 100644
+--- a/net/netfilter/ipset/ip_set_list_set.c
++++ b/net/netfilter/ipset/ip_set_list_set.c
+@@ -79,7 +79,7 @@ list_set_kadd(struct ip_set *set, const struct sk_buff *skb,
+       struct set_elem *e;
+       int ret;
+-      list_for_each_entry(e, &map->members, list) {
++      list_for_each_entry_rcu(e, &map->members, list) {
+               if (SET_WITH_TIMEOUT(set) &&
+                   ip_set_timeout_expired(ext_timeout(e, set)))
+                       continue;
+@@ -99,7 +99,7 @@ list_set_kdel(struct ip_set *set, const struct sk_buff *skb,
+       struct set_elem *e;
+       int ret;
+-      list_for_each_entry(e, &map->members, list) {
++      list_for_each_entry_rcu(e, &map->members, list) {
+               if (SET_WITH_TIMEOUT(set) &&
+                   ip_set_timeout_expired(ext_timeout(e, set)))
+                       continue;
+@@ -188,9 +188,10 @@ list_set_utest(struct ip_set *set, void *value, const struct ip_set_ext *ext,
+       struct list_set *map = set->data;
+       struct set_adt_elem *d = value;
+       struct set_elem *e, *next, *prev = NULL;
+-      int ret;
++      int ret = 0;
+-      list_for_each_entry(e, &map->members, list) {
++      rcu_read_lock();
++      list_for_each_entry_rcu(e, &map->members, list) {
+               if (SET_WITH_TIMEOUT(set) &&
+                   ip_set_timeout_expired(ext_timeout(e, set)))
+                       continue;
+@@ -201,6 +202,7 @@ list_set_utest(struct ip_set *set, void *value, const struct ip_set_ext *ext,
+               if (d->before == 0) {
+                       ret = 1;
++                      goto out;
+               } else if (d->before > 0) {
+                       next = list_next_entry(e, list);
+                       ret = !list_is_last(&e->list, &map->members) &&
+@@ -208,9 +210,11 @@ list_set_utest(struct ip_set *set, void *value, const struct ip_set_ext *ext,
+               } else {
+                       ret = prev && prev->id == d->refid;
+               }
+-              return ret;
++              goto out;
+       }
+-      return 0;
++out:
++      rcu_read_unlock();
++      return ret;
+ }
+ static void
+@@ -239,7 +243,7 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
+       /* Find where to add the new entry */
+       n = prev = next = NULL;
+-      list_for_each_entry(e, &map->members, list) {
++      list_for_each_entry_rcu(e, &map->members, list) {
+               if (SET_WITH_TIMEOUT(set) &&
+                   ip_set_timeout_expired(ext_timeout(e, set)))
+                       continue;
+@@ -316,9 +320,9 @@ list_set_udel(struct ip_set *set, void *value, const struct ip_set_ext *ext,
+ {
+       struct list_set *map = set->data;
+       struct set_adt_elem *d = value;
+-      struct set_elem *e, *next, *prev = NULL;
++      struct set_elem *e, *n, *next, *prev = NULL;
+-      list_for_each_entry(e, &map->members, list) {
++      list_for_each_entry_safe(e, n, &map->members, list) {
+               if (SET_WITH_TIMEOUT(set) &&
+                   ip_set_timeout_expired(ext_timeout(e, set)))
+                       continue;
+@@ -424,14 +428,8 @@ static void
+ list_set_destroy(struct ip_set *set)
+ {
+       struct list_set *map = set->data;
+-      struct set_elem *e, *n;
+-      list_for_each_entry_safe(e, n, &map->members, list) {
+-              list_del(&e->list);
+-              ip_set_put_byindex(map->net, e->id);
+-              ip_set_ext_destroy(set, e);
+-              kfree(e);
+-      }
++      WARN_ON_ONCE(!list_empty(&map->members));
+       kfree(map);
+       set->data = NULL;
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-use-flowlabel-flow-key-when-re-routing-man.patch b/queue-5.15/netfilter-use-flowlabel-flow-key-when-re-routing-man.patch
new file mode 100644 (file)
index 0000000..56b602c
--- /dev/null
@@ -0,0 +1,41 @@
+From 0259c5da8317eb01ce43b537caf0b764ff1c674b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jun 2024 12:23:31 +0200
+Subject: netfilter: Use flowlabel flow key when re-routing mangled packets
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 6f8f132cc7bac2ac76911e47d5baa378aafda4cb ]
+
+'ip6 dscp set $v' in an nftables outpute route chain has no effect.
+While nftables does detect the dscp change and calls the reroute hook.
+But ip6_route_me_harder never sets the dscp/flowlabel:
+flowlabel/dsfield routing rules are ignored and no reroute takes place.
+
+Thanks to Yi Chen for an excellent reproducer script that I used
+to validate this change.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: Yi Chen <yiche@redhat.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/netfilter.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
+index 118e834e91902..cd158e8fb738d 100644
+--- a/net/ipv6/netfilter.c
++++ b/net/ipv6/netfilter.c
+@@ -35,6 +35,7 @@ int ip6_route_me_harder(struct net *net, struct sock *sk_partial, struct sk_buff
+               .flowi6_uid = sock_net_uid(net, sk),
+               .daddr = iph->daddr,
+               .saddr = iph->saddr,
++              .flowlabel = ip6_flowinfo(iph),
+       };
+       int err;
+-- 
+2.43.0
+
diff --git a/queue-5.15/platform-x86-dell-smbios-base-use-sysfs_emit.patch b/queue-5.15/platform-x86-dell-smbios-base-use-sysfs_emit.patch
new file mode 100644 (file)
index 0000000..e297809
--- /dev/null
@@ -0,0 +1,46 @@
+From 299b3fe90591a83405fb1a14b45861ed130cf097 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Sep 2022 06:32:33 +0000
+Subject: platform/x86: dell-smbios-base: Use sysfs_emit()
+
+From: ye xingchen <ye.xingchen@zte.com.cn>
+
+[ Upstream commit bbfa903b4f9a0a76719f386367fed5e64187f577 ]
+
+Replace the open-code with sysfs_emit() to simplify the code.
+
+Signed-off-by: ye xingchen <ye.xingchen@zte.com.cn>
+Link: https://lore.kernel.org/r/20220923063233.239091-1-ye.xingchen@zte.com.cn
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Stable-dep-of: 1981b296f858 ("platform/x86: dell-smbios: Fix wrong token data in sysfs")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/dell/dell-smbios-base.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
+index fc086b66f70b3..e61bfaf8b5c48 100644
+--- a/drivers/platform/x86/dell/dell-smbios-base.c
++++ b/drivers/platform/x86/dell/dell-smbios-base.c
+@@ -441,7 +441,7 @@ static ssize_t location_show(struct device *dev,
+       i = match_attribute(dev, attr);
+       if (i > 0)
+-              return scnprintf(buf, PAGE_SIZE, "%08x", da_tokens[i].location);
++              return sysfs_emit(buf, "%08x", da_tokens[i].location);
+       return 0;
+ }
+@@ -455,7 +455,7 @@ static ssize_t value_show(struct device *dev,
+       i = match_attribute(dev, attr);
+       if (i > 0)
+-              return scnprintf(buf, PAGE_SIZE, "%08x", da_tokens[i].value);
++              return sysfs_emit(buf, "%08x", da_tokens[i].value);
+       return 0;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.15/platform-x86-dell-smbios-fix-wrong-token-data-in-sys.patch b/queue-5.15/platform-x86-dell-smbios-fix-wrong-token-data-in-sys.patch
new file mode 100644 (file)
index 0000000..199ada7
--- /dev/null
@@ -0,0 +1,226 @@
+From 51796ff6275645c5e3ad62f5d4e36b574cd2f24b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 May 2024 22:49:02 +0200
+Subject: platform/x86: dell-smbios: Fix wrong token data in sysfs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit 1981b296f858010eae409548fd297659b2cc570e ]
+
+When reading token data from sysfs on my Inspiron 3505, the token
+locations and values are wrong. This happens because match_attribute()
+blindly assumes that all entries in da_tokens have an associated
+entry in token_attrs.
+
+This however is not true as soon as da_tokens[] contains zeroed
+token entries. Those entries are being skipped when initialising
+token_attrs, breaking the core assumption of match_attribute().
+
+Fix this by defining an extra struct for each pair of token attributes
+and use container_of() to retrieve token information.
+
+Tested on a Dell Inspiron 3050.
+
+Fixes: 33b9ca1e53b4 ("platform/x86: dell-smbios: Add a sysfs interface for SMBIOS tokens")
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://lore.kernel.org/r/20240528204903.445546-1-W_Armin@gmx.de
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/dell/dell-smbios-base.c | 92 ++++++++------------
+ 1 file changed, 36 insertions(+), 56 deletions(-)
+
+diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c
+index e61bfaf8b5c48..86b95206cb1bd 100644
+--- a/drivers/platform/x86/dell/dell-smbios-base.c
++++ b/drivers/platform/x86/dell/dell-smbios-base.c
+@@ -11,6 +11,7 @@
+  */
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++#include <linux/container_of.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/capability.h>
+@@ -25,11 +26,16 @@ static u32 da_supported_commands;
+ static int da_num_tokens;
+ static struct platform_device *platform_device;
+ static struct calling_interface_token *da_tokens;
+-static struct device_attribute *token_location_attrs;
+-static struct device_attribute *token_value_attrs;
++static struct token_sysfs_data *token_entries;
+ static struct attribute **token_attrs;
+ static DEFINE_MUTEX(smbios_mutex);
++struct token_sysfs_data {
++      struct device_attribute location_attr;
++      struct device_attribute value_attr;
++      struct calling_interface_token *token;
++};
++
+ struct smbios_device {
+       struct list_head list;
+       struct device *device;
+@@ -416,47 +422,26 @@ static void __init find_tokens(const struct dmi_header *dm, void *dummy)
+       }
+ }
+-static int match_attribute(struct device *dev,
+-                         struct device_attribute *attr)
+-{
+-      int i;
+-
+-      for (i = 0; i < da_num_tokens * 2; i++) {
+-              if (!token_attrs[i])
+-                      continue;
+-              if (strcmp(token_attrs[i]->name, attr->attr.name) == 0)
+-                      return i/2;
+-      }
+-      dev_dbg(dev, "couldn't match: %s\n", attr->attr.name);
+-      return -EINVAL;
+-}
+-
+ static ssize_t location_show(struct device *dev,
+                            struct device_attribute *attr, char *buf)
+ {
+-      int i;
++      struct token_sysfs_data *data = container_of(attr, struct token_sysfs_data, location_attr);
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+-      i = match_attribute(dev, attr);
+-      if (i > 0)
+-              return sysfs_emit(buf, "%08x", da_tokens[i].location);
+-      return 0;
++      return sysfs_emit(buf, "%08x", data->token->location);
+ }
+ static ssize_t value_show(struct device *dev,
+                         struct device_attribute *attr, char *buf)
+ {
+-      int i;
++      struct token_sysfs_data *data = container_of(attr, struct token_sysfs_data, value_attr);
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+-      i = match_attribute(dev, attr);
+-      if (i > 0)
+-              return sysfs_emit(buf, "%08x", da_tokens[i].value);
+-      return 0;
++      return sysfs_emit(buf, "%08x", data->token->value);
+ }
+ static struct attribute_group smbios_attribute_group = {
+@@ -473,22 +458,15 @@ static int build_tokens_sysfs(struct platform_device *dev)
+ {
+       char *location_name;
+       char *value_name;
+-      size_t size;
+       int ret;
+       int i, j;
+-      /* (number of tokens  + 1 for null terminated */
+-      size = sizeof(struct device_attribute) * (da_num_tokens + 1);
+-      token_location_attrs = kzalloc(size, GFP_KERNEL);
+-      if (!token_location_attrs)
++      token_entries = kcalloc(da_num_tokens, sizeof(*token_entries), GFP_KERNEL);
++      if (!token_entries)
+               return -ENOMEM;
+-      token_value_attrs = kzalloc(size, GFP_KERNEL);
+-      if (!token_value_attrs)
+-              goto out_allocate_value;
+       /* need to store both location and value + terminator*/
+-      size = sizeof(struct attribute *) * ((2 * da_num_tokens) + 1);
+-      token_attrs = kzalloc(size, GFP_KERNEL);
++      token_attrs = kcalloc((2 * da_num_tokens) + 1, sizeof(*token_attrs), GFP_KERNEL);
+       if (!token_attrs)
+               goto out_allocate_attrs;
+@@ -496,27 +474,32 @@ static int build_tokens_sysfs(struct platform_device *dev)
+               /* skip empty */
+               if (da_tokens[i].tokenID == 0)
+                       continue;
++
++              token_entries[i].token = &da_tokens[i];
++
+               /* add location */
+               location_name = kasprintf(GFP_KERNEL, "%04x_location",
+                                         da_tokens[i].tokenID);
+               if (location_name == NULL)
+                       goto out_unwind_strings;
+-              sysfs_attr_init(&token_location_attrs[i].attr);
+-              token_location_attrs[i].attr.name = location_name;
+-              token_location_attrs[i].attr.mode = 0444;
+-              token_location_attrs[i].show = location_show;
+-              token_attrs[j++] = &token_location_attrs[i].attr;
++
++              sysfs_attr_init(&token_entries[i].location_attr.attr);
++              token_entries[i].location_attr.attr.name = location_name;
++              token_entries[i].location_attr.attr.mode = 0444;
++              token_entries[i].location_attr.show = location_show;
++              token_attrs[j++] = &token_entries[i].location_attr.attr;
+               /* add value */
+               value_name = kasprintf(GFP_KERNEL, "%04x_value",
+                                      da_tokens[i].tokenID);
+               if (value_name == NULL)
+                       goto loop_fail_create_value;
+-              sysfs_attr_init(&token_value_attrs[i].attr);
+-              token_value_attrs[i].attr.name = value_name;
+-              token_value_attrs[i].attr.mode = 0444;
+-              token_value_attrs[i].show = value_show;
+-              token_attrs[j++] = &token_value_attrs[i].attr;
++
++              sysfs_attr_init(&token_entries[i].value_attr.attr);
++              token_entries[i].value_attr.attr.name = value_name;
++              token_entries[i].value_attr.attr.mode = 0444;
++              token_entries[i].value_attr.show = value_show;
++              token_attrs[j++] = &token_entries[i].value_attr.attr;
+               continue;
+ loop_fail_create_value:
+@@ -532,14 +515,12 @@ static int build_tokens_sysfs(struct platform_device *dev)
+ out_unwind_strings:
+       while (i--) {
+-              kfree(token_location_attrs[i].attr.name);
+-              kfree(token_value_attrs[i].attr.name);
++              kfree(token_entries[i].location_attr.attr.name);
++              kfree(token_entries[i].value_attr.attr.name);
+       }
+       kfree(token_attrs);
+ out_allocate_attrs:
+-      kfree(token_value_attrs);
+-out_allocate_value:
+-      kfree(token_location_attrs);
++      kfree(token_entries);
+       return -ENOMEM;
+ }
+@@ -551,12 +532,11 @@ static void free_group(struct platform_device *pdev)
+       sysfs_remove_group(&pdev->dev.kobj,
+                               &smbios_attribute_group);
+       for (i = 0; i < da_num_tokens; i++) {
+-              kfree(token_location_attrs[i].attr.name);
+-              kfree(token_value_attrs[i].attr.name);
++              kfree(token_entries[i].location_attr.attr.name);
++              kfree(token_entries[i].value_attr.attr.name);
+       }
+       kfree(token_attrs);
+-      kfree(token_value_attrs);
+-      kfree(token_location_attrs);
++      kfree(token_entries);
+ }
+ static int __init dell_smbios_init(void)
+-- 
+2.43.0
+
index d726cbc7064388601ff837c581b2849a9351447d..0614ae9b4e04a294d73a040633c0ecd5367f0911 100644 (file)
@@ -95,3 +95,42 @@ xhci-apply-broken-streams-quirk-to-etron-ej188-xhci-host.patch
 scsi-mpt3sas-avoid-test-set_bit-operating-in-non-allocated-memory.patch
 powerpc-uaccess-fix-build-errors-seen-with-gcc-13-14.patch
 input-try-trimming-too-long-modalias-strings.patch
+clk-sifive-do-not-register-clkdevs-for-prci-clocks.patch
+sunrpc-return-proper-error-from-gss_wrap_req_priv.patch
+kernel.h-split-out-container_of-and-typeof_member-ma.patch
+platform-x86-dell-smbios-base-use-sysfs_emit.patch
+platform-x86-dell-smbios-fix-wrong-token-data-in-sys.patch
+gpio-tqmx86-fix-typo-in-kconfig-label.patch
+gpio-tqmx86-remove-unneeded-call-to-platform_set_drv.patch
+gpio-tqmx86-introduce-shadow-register-for-gpio-outpu.patch
+genirq-allow-the-pm-device-to-originate-from-irq-dom.patch
+gpio-tpmx86-move-pm-device-over-to-irq-domain.patch
+gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch
+gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch
+gpio-add-helpers-to-ease-the-transition-towards-immu.patch
+gpio-tqmx86-convert-to-immutable-irq_chip.patch
+gpio-tqmx86-store-irq-trigger-type-and-unmask-status.patch
+gpio-tqmx86-fix-broken-irq_type_edge_both-interrupt-.patch
+hid-core-remove-unnecessary-warn_on-in-implement.patch
+iommu-amd-introduce-pci-segment-structure.patch
+iommu-amd-fix-sysfs-leak-in-iommu-init.patch
+iommu-return-right-value-in-iommu_sva_bind_device.patch
+hid-logitech-dj-fix-memory-leak-in-logi_dj_recv_swit.patch
+drm-vmwgfx-3d-disabled-should-not-effect-stdu-memory.patch
+net-sfp-always-call-sfp_sm_mod_remove-on-remove.patch
+net-hns3-fix-kernel-crash-problem-in-concurrent-scen.patch
+net-hns3-add-cond_resched-to-hns3-ring-buffer-init-p.patch
+liquidio-adjust-a-null-pointer-handling-path-in-lio_.patch
+drm-komeda-check-for-error-valued-pointer.patch
+drm-bridge-panel-fix-runtime-warning-on-panel-bridge.patch
+tcp-fix-race-in-tcp_v6_syn_recv_sock.patch
+net-geneve-support-ipv4-ipv6-as-inner-protocol.patch
+geneve-fix-incorrect-inner-network-header-offset-whe.patch
+net-mlx5e-fix-features-validation-check-for-tunneled.patch
+bluetooth-l2cap-fix-rejecting-l2cap_conn_param_updat.patch
+netfilter-ipset-fix-race-between-namespace-cleanup-a.patch
+netfilter-use-flowlabel-flow-key-when-re-routing-man.patch
+net-stmmac-replace-priv-speed-with-the-porttransmitr.patch
+net-ipv6-fix-the-rt-cache-flush-via-sysctl-using-a-p.patch
+ionic-fix-use-after-netif_napi_del.patch
+af_unix-read-with-msg_peek-loops-if-the-first-unread.patch
diff --git a/queue-5.15/sunrpc-return-proper-error-from-gss_wrap_req_priv.patch b/queue-5.15/sunrpc-return-proper-error-from-gss_wrap_req_priv.patch
new file mode 100644 (file)
index 0000000..c9f16ce
--- /dev/null
@@ -0,0 +1,40 @@
+From 92e836c84e388d16f481e12103500b0b0d2cb502 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 May 2024 16:47:16 +0800
+Subject: SUNRPC: return proper error from gss_wrap_req_priv
+
+From: Chen Hanxiao <chenhx.fnst@fujitsu.com>
+
+[ Upstream commit 33c94d7e3cb84f6d130678d6d59ba475a6c489cf ]
+
+don't return 0 if snd_buf->len really greater than snd_buf->buflen
+
+Signed-off-by: Chen Hanxiao <chenhx.fnst@fujitsu.com>
+Fixes: 0c77668ddb4e ("SUNRPC: Introduce trace points in rpc_auth_gss.ko")
+Reviewed-by: Benjamin Coddington <bcodding@redhat.com>
+Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/auth_gss/auth_gss.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
+index 2ff66a6a7e54c..7ce4a6b7cfae6 100644
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -1855,8 +1855,10 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
+       offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
+       maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages);
+       /* slack space should prevent this ever happening: */
+-      if (unlikely(snd_buf->len > snd_buf->buflen))
++      if (unlikely(snd_buf->len > snd_buf->buflen)) {
++              status = -EIO;
+               goto wrap_failed;
++      }
+       /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
+        * done anyway, so it's safe to put the request on the wire: */
+       if (maj_stat == GSS_S_CONTEXT_EXPIRED)
+-- 
+2.43.0
+
diff --git a/queue-5.15/tcp-fix-race-in-tcp_v6_syn_recv_sock.patch b/queue-5.15/tcp-fix-race-in-tcp_v6_syn_recv_sock.patch
new file mode 100644 (file)
index 0000000..e2049a7
--- /dev/null
@@ -0,0 +1,54 @@
+From 08b1020b8872acde665d8f403430b074297b8e10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jun 2024 15:46:51 +0000
+Subject: tcp: fix race in tcp_v6_syn_recv_sock()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit d37fe4255abe8e7b419b90c5847e8ec2b8debb08 ]
+
+tcp_v6_syn_recv_sock() calls ip6_dst_store() before
+inet_sk(newsk)->pinet6 has been set up.
+
+This means ip6_dst_store() writes over the parent (listener)
+np->dst_cookie.
+
+This is racy because multiple threads could share the same
+parent and their final np->dst_cookie could be wrong.
+
+Move ip6_dst_store() call after inet_sk(newsk)->pinet6
+has been changed and after the copy of parent ipv6_pinfo.
+
+Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/tcp_ipv6.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index c18fdddbfa09d..c1f1fa6e33161 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1331,7 +1331,6 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
+        */
+       newsk->sk_gso_type = SKB_GSO_TCPV6;
+-      ip6_dst_store(newsk, dst, NULL, NULL);
+       inet6_sk_rx_dst_set(newsk, skb);
+       inet_sk(newsk)->pinet6 = tcp_inet6_sk(newsk);
+@@ -1342,6 +1341,8 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
+       memcpy(newnp, np, sizeof(struct ipv6_pinfo));
++      ip6_dst_store(newsk, dst, NULL, NULL);
++
+       newsk->sk_v6_daddr = ireq->ir_v6_rmt_addr;
+       newnp->saddr = ireq->ir_v6_loc_addr;
+       newsk->sk_v6_rcv_saddr = ireq->ir_v6_loc_addr;
+-- 
+2.43.0
+