From de492cc2708be702d99e51494fbcfec8333f8ded Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Mon, 17 Jun 2024 07:30:32 -0400 Subject: [PATCH] Fixes for 5.15 Signed-off-by: Sasha Levin --- ...h-msg_peek-loops-if-the-first-unread.patch | 85 ++++++ ...fix-rejecting-l2cap_conn_param_updat.patch | 108 +++++++ ...not-register-clkdevs-for-prci-clocks.patch | 62 ++++ ...-fix-runtime-warning-on-panel-bridge.patch | 51 ++++ ...omeda-check-for-error-valued-pointer.patch | 37 +++ ...sabled-should-not-effect-stdu-memory.patch | 45 +++ ...rect-inner-network-header-offset-whe.patch | 106 +++++++ ...-pm-device-to-originate-from-irq-dom.patch | 122 ++++++++ ...-to-ease-the-transition-towards-immu.patch | 54 ++++ ...le-with-irqchips-marked-as-immutable.patch | 89 ++++++ ...e-the-gpiochip_irq_re-ql-res-helpers.patch | 70 +++++ ...86-move-pm-device-over-to-irq-domain.patch | 44 +++ ...tqmx86-convert-to-immutable-irq_chip.patch | 108 +++++++ ...broken-irq_type_edge_both-interrupt-.patch | 114 +++++++ ...pio-tqmx86-fix-typo-in-kconfig-label.patch | 38 +++ ...oduce-shadow-register-for-gpio-outpu.patch | 89 ++++++ ...ve-unneeded-call-to-platform_set_drv.patch | 40 +++ ...e-irq-trigger-type-and-unmask-status.patch | 137 +++++++++ ...ove-unnecessary-warn_on-in-implement.patch | 67 ++++ ...fix-memory-leak-in-logi_dj_recv_swit.patch | 41 +++ ...mmu-amd-fix-sysfs-leak-in-iommu-init.patch | 47 +++ ...-amd-introduce-pci-segment-structure.patch | 182 +++++++++++ ...right-value-in-iommu_sva_bind_device.patch | 49 +++ .../ionic-fix-use-after-netif_napi_del.patch | 97 ++++++ ...ut-container_of-and-typeof_member-ma.patch | 153 ++++++++++ ...a-null-pointer-handling-path-in-lio_.patch | 69 +++++ ...-support-ipv4-ipv6-as-inner-protocol.patch | 237 ++++++++++++++ ...d_resched-to-hns3-ring-buffer-init-p.patch | 64 ++++ ...nel-crash-problem-in-concurrent-scen.patch | 84 +++++ ...-rt-cache-flush-via-sysctl-using-a-p.patch | 53 ++++ ...atures-validation-check-for-tunneled.patch | 53 ++++ ...ays-call-sfp_sm_mod_remove-on-remove.patch | 45 +++ ...ce-priv-speed-with-the-porttransmitr.patch | 101 ++++++ ...fix-race-between-namespace-cleanup-a.patch | 289 ++++++++++++++++++ ...owlabel-flow-key-when-re-routing-man.patch | 41 +++ ...-x86-dell-smbios-base-use-sysfs_emit.patch | 46 +++ ...l-smbios-fix-wrong-token-data-in-sys.patch | 226 ++++++++++++++ queue-5.15/series | 39 +++ ...-proper-error-from-gss_wrap_req_priv.patch | 40 +++ ...tcp-fix-race-in-tcp_v6_syn_recv_sock.patch | 54 ++++ 40 files changed, 3476 insertions(+) create mode 100644 queue-5.15/af_unix-read-with-msg_peek-loops-if-the-first-unread.patch create mode 100644 queue-5.15/bluetooth-l2cap-fix-rejecting-l2cap_conn_param_updat.patch create mode 100644 queue-5.15/clk-sifive-do-not-register-clkdevs-for-prci-clocks.patch create mode 100644 queue-5.15/drm-bridge-panel-fix-runtime-warning-on-panel-bridge.patch create mode 100644 queue-5.15/drm-komeda-check-for-error-valued-pointer.patch create mode 100644 queue-5.15/drm-vmwgfx-3d-disabled-should-not-effect-stdu-memory.patch create mode 100644 queue-5.15/geneve-fix-incorrect-inner-network-header-offset-whe.patch create mode 100644 queue-5.15/genirq-allow-the-pm-device-to-originate-from-irq-dom.patch create mode 100644 queue-5.15/gpio-add-helpers-to-ease-the-transition-towards-immu.patch create mode 100644 queue-5.15/gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch create mode 100644 queue-5.15/gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch create mode 100644 queue-5.15/gpio-tpmx86-move-pm-device-over-to-irq-domain.patch create mode 100644 queue-5.15/gpio-tqmx86-convert-to-immutable-irq_chip.patch create mode 100644 queue-5.15/gpio-tqmx86-fix-broken-irq_type_edge_both-interrupt-.patch create mode 100644 queue-5.15/gpio-tqmx86-fix-typo-in-kconfig-label.patch create mode 100644 queue-5.15/gpio-tqmx86-introduce-shadow-register-for-gpio-outpu.patch create mode 100644 queue-5.15/gpio-tqmx86-remove-unneeded-call-to-platform_set_drv.patch create mode 100644 queue-5.15/gpio-tqmx86-store-irq-trigger-type-and-unmask-status.patch create mode 100644 queue-5.15/hid-core-remove-unnecessary-warn_on-in-implement.patch create mode 100644 queue-5.15/hid-logitech-dj-fix-memory-leak-in-logi_dj_recv_swit.patch create mode 100644 queue-5.15/iommu-amd-fix-sysfs-leak-in-iommu-init.patch create mode 100644 queue-5.15/iommu-amd-introduce-pci-segment-structure.patch create mode 100644 queue-5.15/iommu-return-right-value-in-iommu_sva_bind_device.patch create mode 100644 queue-5.15/ionic-fix-use-after-netif_napi_del.patch create mode 100644 queue-5.15/kernel.h-split-out-container_of-and-typeof_member-ma.patch create mode 100644 queue-5.15/liquidio-adjust-a-null-pointer-handling-path-in-lio_.patch create mode 100644 queue-5.15/net-geneve-support-ipv4-ipv6-as-inner-protocol.patch create mode 100644 queue-5.15/net-hns3-add-cond_resched-to-hns3-ring-buffer-init-p.patch create mode 100644 queue-5.15/net-hns3-fix-kernel-crash-problem-in-concurrent-scen.patch create mode 100644 queue-5.15/net-ipv6-fix-the-rt-cache-flush-via-sysctl-using-a-p.patch create mode 100644 queue-5.15/net-mlx5e-fix-features-validation-check-for-tunneled.patch create mode 100644 queue-5.15/net-sfp-always-call-sfp_sm_mod_remove-on-remove.patch create mode 100644 queue-5.15/net-stmmac-replace-priv-speed-with-the-porttransmitr.patch create mode 100644 queue-5.15/netfilter-ipset-fix-race-between-namespace-cleanup-a.patch create mode 100644 queue-5.15/netfilter-use-flowlabel-flow-key-when-re-routing-man.patch create mode 100644 queue-5.15/platform-x86-dell-smbios-base-use-sysfs_emit.patch create mode 100644 queue-5.15/platform-x86-dell-smbios-fix-wrong-token-data-in-sys.patch create mode 100644 queue-5.15/sunrpc-return-proper-error-from-gss_wrap_req_priv.patch create mode 100644 queue-5.15/tcp-fix-race-in-tcp_v6_syn_recv_sock.patch 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 index 00000000000..f327a2ccb54 --- /dev/null +++ b/queue-5.15/af_unix-read-with-msg_peek-loops-if-the-first-unread.patch @@ -0,0 +1,85 @@ +From cfa8617f46189537fb7143ec8603cf4f7db08fce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Kuniyuki Iwashima +Link: https://lore.kernel.org/r/20240611084639.2248934-1-Rao.Shoaib@oracle.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..3be1aee10e9 --- /dev/null +++ b/queue-5.15/bluetooth-l2cap-fix-rejecting-l2cap_conn_param_updat.patch @@ -0,0 +1,108 @@ +From f9fe6807cd1d219cb2bfd9e70acdb413d25dbdf1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 May 2024 16:03:07 -0400 +Subject: Bluetooth: L2CAP: Fix rejecting L2CAP_CONN_PARAM_UPDATE_REQ + +From: Luiz Augusto von Dentz + +[ 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 +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..e7c3bf90685 --- /dev/null +++ b/queue-5.15/clk-sifive-do-not-register-clkdevs-for-prci-clocks.patch @@ -0,0 +1,62 @@ +From 2b329e40c49c250209ec05e1e86a02e2d684bf33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 May 2024 17:14:12 -0700 +Subject: clk: sifive: Do not register clkdevs for PRCI clocks + +From: Samuel Holland + +[ 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 +Closes: https://lore.kernel.org/linux-clk/7eda7621-0dde-4153-89e4-172e4c095d01@roeck-us.net/ +Suggested-by: Russell King +Signed-off-by: Samuel Holland +Link: https://lore.kernel.org/r/20240528001432.1200403-1-samuel.holland@sifive.com +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + 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 + #include + #include + #include +@@ -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 index 00000000000..0f7c2ca4b23 --- /dev/null +++ b/queue-5.15/drm-bridge-panel-fix-runtime-warning-on-panel-bridge.patch @@ -0,0 +1,51 @@ +From 6a90206af6441f14396cc37aca56ef4a5cbeb6b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Jun 2024 11:27:39 +0100 +Subject: drm/bridge/panel: Fix runtime warning on panel bridge release + +From: Adam Miotk + +[ 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 +Signed-off-by: Maxime Ripard +Link: https://patchwork.freedesktop.org/patch/msgid/20240610102739.139852-1-adam.miotk@arm.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..1cbe8582c0b --- /dev/null +++ b/queue-5.15/drm-komeda-check-for-error-valued-pointer.patch @@ -0,0 +1,37 @@ +From fec62843d3d15c56da8d09164cbf37440d6ebab1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Jun 2024 11:20:56 +0100 +Subject: drm/komeda: check for error-valued pointer + +From: Amjad Ouled-Ameur + +[ 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 +Signed-off-by: Maxime Ripard +Link: https://patchwork.freedesktop.org/patch/msgid/20240610102056.40406-1-amjad.ouled-ameur@arm.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..602d6a16fc7 --- /dev/null +++ b/queue-5.15/drm-vmwgfx-3d-disabled-should-not-effect-stdu-memory.patch @@ -0,0 +1,45 @@ +From 3c0217ff0e22f54401f9929fbbc82d9dcbaf0286 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 May 2024 13:47:18 -0500 +Subject: drm/vmwgfx: 3D disabled should not effect STDU memory limits + +From: Ian Forbes + +[ 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 +Signed-off-by: Zack Rusin +Link: https://patchwork.freedesktop.org/patch/msgid/20240521184720.767-3-ian.forbes@broadcom.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..5feb7ab9edd --- /dev/null +++ b/queue-5.15/geneve-fix-incorrect-inner-network-header-offset-whe.patch @@ -0,0 +1,106 @@ +From 800814a7df99f26dd955e9a8e65d85a5ce418e57 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Jun 2024 23:32:48 +0300 +Subject: geneve: Fix incorrect inner network header offset when + innerprotoinherit is set + +From: Gal Pressman + +[ 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 +Signed-off-by: Tariq Toukan +Reviewed-by: Wojciech Drewek +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a496c5c9649 --- /dev/null +++ b/queue-5.15/genirq-allow-the-pm-device-to-originate-from-irq-dom.patch @@ -0,0 +1,122 @@ +From b87525165dae63e1b49e64c38848199b7e00b719 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Feb 2022 12:02:59 +0000 +Subject: genirq: Allow the PM device to originate from irq domain + +From: Marc Zyngier + +[ 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 +Reviewed-by: Geert Uytterhoeven +Tested-by: Geert Uytterhoeven +Tested-by: Tony Lindgren +Acked-by: Bartosz Golaszewski +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 +--- + 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 index 00000000000..e8b8db265db --- /dev/null +++ b/queue-5.15/gpio-add-helpers-to-ease-the-transition-towards-immu.patch @@ -0,0 +1,54 @@ +From c411d53be49d2d1077438662267c7f084dc3ba34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Apr 2022 15:18:39 +0100 +Subject: gpio: Add helpers to ease the transition towards immutable irq_chip + +From: Marc Zyngier + +[ 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 +Reviewed-by: Bartosz Golaszewski +Signed-off-by: Marc Zyngier +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 +--- + 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 index 00000000000..fc670b81089 --- /dev/null +++ b/queue-5.15/gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch @@ -0,0 +1,89 @@ +From 2c04ad8df019c95f15df956c6a7e956d7c5aee2e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Apr 2022 15:18:37 +0100 +Subject: gpio: Don't fiddle with irqchips marked as immutable + +From: Marc Zyngier + +[ 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 +Reviewed-by: Bartosz Golaszewski +Signed-off-by: Marc Zyngier +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 +--- + 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 +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 index 00000000000..c64b0d00a71 --- /dev/null +++ b/queue-5.15/gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch @@ -0,0 +1,70 @@ +From 334f6b83bffa3d0ea9e1849a3604a20adb5190a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Apr 2022 15:18:38 +0100 +Subject: gpio: Expose the gpiochip_irq_re[ql]res helpers + +From: Marc Zyngier + +[ 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 +Reviewed-by: Bartosz Golaszewski +Signed-off-by: Marc Zyngier +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 +--- + 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 index 00000000000..ca4907077c1 --- /dev/null +++ b/queue-5.15/gpio-tpmx86-move-pm-device-over-to-irq-domain.patch @@ -0,0 +1,44 @@ +From 5152f2434b824ef78f204af311af419c45a7da21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Feb 2022 12:03:07 +0000 +Subject: gpio: tpmx86: Move PM device over to irq domain + +From: Marc Zyngier + +[ Upstream commit 924610607f191bee4379bc3775b0fd025ad7e922 ] + +Move the reference to the device over to the irq domain. + +Signed-off-by: Marc Zyngier +Acked-by: Bartosz Golaszewski +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 +--- + 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 index 00000000000..963097244ec --- /dev/null +++ b/queue-5.15/gpio-tqmx86-convert-to-immutable-irq_chip.patch @@ -0,0 +1,108 @@ +From a201198bf9e9221693f5911c94f96b7b5b72ee22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Mar 2023 10:55:12 +0100 +Subject: gpio: tqmx86: Convert to immutable irq_chip + +From: Linus Walleij + +[ Upstream commit 8e43827b6ae727a745ce7a8cc19184b28905a965 ] + +Convert the driver to immutable irq-chip with a bit of +intuition. + +Cc: Marc Zyngier +Signed-off-by: Linus Walleij +Reviewed-by: Marc Zyngier +Signed-off-by: Bartosz Golaszewski +Stable-dep-of: 08af509efdf8 ("gpio: tqmx86: store IRQ trigger type and unmask status separately") +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + #include + + #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 index 00000000000..94eecef065f --- /dev/null +++ b/queue-5.15/gpio-tqmx86-fix-broken-irq_type_edge_both-interrupt-.patch @@ -0,0 +1,114 @@ +From 135e150c7b5356868851c3770f03ba6f820a6289 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 May 2024 12:20:02 +0200 +Subject: gpio: tqmx86: fix broken IRQ_TYPE_EDGE_BOTH interrupt type + +From: Matthias Schiffer + +[ 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 +Signed-off-by: Gregor Herburger +Signed-off-by: Matthias Schiffer +Link: https://lore.kernel.org/r/515324f0491c4d44f4ef49f170354aca002d81ef.1717063994.git.matthias.schiffer@ew.tq-group.com +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..6c75d5f83b2 --- /dev/null +++ b/queue-5.15/gpio-tqmx86-fix-typo-in-kconfig-label.patch @@ -0,0 +1,38 @@ +From ed4fd04406cca1ea310c050ffbe8951ac721f8d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 May 2024 12:19:59 +0200 +Subject: gpio: tqmx86: fix typo in Kconfig label + +From: Gregor Herburger + +[ 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 +Signed-off-by: Matthias Schiffer +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/e0e38c9944ad6d281d9a662a45d289b88edc808e.1717063994.git.matthias.schiffer@ew.tq-group.com +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..ae37469119d --- /dev/null +++ b/queue-5.15/gpio-tqmx86-introduce-shadow-register-for-gpio-outpu.patch @@ -0,0 +1,89 @@ +From 1cc4fa426d3b52405e0ad25e8145619bec69aac2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 May 2024 12:20:00 +0200 +Subject: gpio: tqmx86: introduce shadow register for GPIO output value + +From: Matthias Schiffer + +[ 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 +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/d0555933becd45fa92a85675d26e4d59343ddc01.1717063994.git.matthias.schiffer@ew.tq-group.com +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + 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 + */ + ++#include + #include + #include + #include +@@ -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 index 00000000000..37146cfe577 --- /dev/null +++ b/queue-5.15/gpio-tqmx86-remove-unneeded-call-to-platform_set_drv.patch @@ -0,0 +1,40 @@ +From 43f7494a9d3f5f4c7e14e1da229a8262775bf4e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Aug 2023 23:38:39 +0300 +Subject: gpio: tqmx86: remove unneeded call to platform_set_drvdata() + +From: Andrei Coardos + +[ 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 +Signed-off-by: Andrei Coardos +Reviewed-by: Andy Shevchenko +Signed-off-by: Bartosz Golaszewski +Stable-dep-of: 9d6a811b522b ("gpio: tqmx86: introduce shadow register for GPIO output value") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..7ceb27da6e6 --- /dev/null +++ b/queue-5.15/gpio-tqmx86-store-irq-trigger-type-and-unmask-status.patch @@ -0,0 +1,137 @@ +From 5674c759de450d40158d8935e4f7dc431cd2bc03 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 May 2024 12:20:01 +0200 +Subject: gpio: tqmx86: store IRQ trigger type and unmask status separately + +From: Matthias Schiffer + +[ 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 +Link: https://lore.kernel.org/r/6aa4f207f77cb58ef64ffb947e91949b0f753ccd.1717063994.git.matthias.schiffer@ew.tq-group.com +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..ea0ef4124e1 --- /dev/null +++ b/queue-5.15/hid-core-remove-unnecessary-warn_on-in-implement.patch @@ -0,0 +1,67 @@ +From 51aaefc1d1ab2f15a66613782a903452bec2d068 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 May 2024 07:19:14 -0700 +Subject: HID: core: remove unnecessary WARN_ON() in implement() + +From: Nikita Zhandarovich + +[ 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: + + __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: +Suggested-by: Alan Stern +Signed-off-by: Nikita Zhandarovich +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..e0343a6485f --- /dev/null +++ b/queue-5.15/hid-logitech-dj-fix-memory-leak-in-logi_dj_recv_swit.patch @@ -0,0 +1,41 @@ +From e630a9ab88af5ad535d621e72679246cae1c5856 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..0c74c1fc8a7 --- /dev/null +++ b/queue-5.15/iommu-amd-fix-sysfs-leak-in-iommu-init.patch @@ -0,0 +1,47 @@ +From 6d050ef8b631ec4a1ff11d0569a3e91bf7daba77 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 May 2024 08:42:20 +0800 +Subject: iommu/amd: Fix sysfs leak in iommu init + +From: Kun(llfl) + +[ 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) +Reviewed-by: Suravee Suthikulpanit +Link: https://lore.kernel.org/r/c8e0d11c6ab1ee48299c288009cf9c5dae07b42d.1715215003.git.llfl@linux.alibaba.com +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..22cef356f51 --- /dev/null +++ b/queue-5.15/iommu-amd-introduce-pci-segment-structure.patch @@ -0,0 +1,182 @@ +From 2a83d6932ba008c6467f59189097400c433b49f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Jul 2022 17:07:52 +0530 +Subject: iommu/amd: Introduce pci segment structure + +From: Vasant Hegde + +[ 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 +Signed-off-by: Suravee Suthikulpanit +Signed-off-by: Vasant Hegde +Link: https://lore.kernel.org/r/20220706113825.25582-3-vasant.hegde@amd.com +Signed-off-by: Joerg Roedel +Stable-dep-of: a295ec52c862 ("iommu/amd: Fix sysfs leak in iommu init") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..46268e6b528 --- /dev/null +++ b/queue-5.15/iommu-return-right-value-in-iommu_sva_bind_device.patch @@ -0,0 +1,49 @@ +From 1afa576abc5de325c428ebd33db3cd80c98e0c49 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 May 2024 12:25:28 +0800 +Subject: iommu: Return right value in iommu_sva_bind_device() + +From: Lu Baolu + +[ 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 +Reviewed-by: Jean-Philippe Brucker +Reviewed-by: Kevin Tian +Reviewed-by: Vasant Hegde +Link: https://lore.kernel.org/r/20240528042528.71396-1-baolu.lu@linux.intel.com +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..f2480058858 --- /dev/null +++ b/queue-5.15/ionic-fix-use-after-netif_napi_del.patch @@ -0,0 +1,97 @@ +From 7e10fa2573433e04b4d9e5c557fc4db3180ab7db Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Jun 2024 06:04:46 +0000 +Subject: ionic: fix use after netif_napi_del() + +From: Taehee Yoo + +[ 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 rx 1 tx 1 combined 0 + ethtool -L rx 0 tx 0 combined 1 + ethtool -L 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: + + ? 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 +Reviewed-by: Brett Creeley +Reviewed-by: Shannon Nelson +Link: https://lore.kernel.org/r/20240612060446.1754392-1-ap420073@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..44606a1f5b6 --- /dev/null +++ b/queue-5.15/kernel.h-split-out-container_of-and-typeof_member-ma.patch @@ -0,0 +1,153 @@ +From 6d7a7df8c8f8f6f5a5572b4d451c594a7e57b7a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Nov 2021 18:32:12 -0800 +Subject: kernel.h: split out container_of() and typeof_member() macros + +From: Andy Shevchenko + +[ 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 +Cc: Boqun Feng +Cc: Brendan Higgins +Cc: Ingo Molnar +Cc: Jonathan Cameron +Cc: Laurent Pinchart +Cc: Mauro Carvalho Chehab +Cc: Miguel Ojeda +Cc: Peter Zijlstra +Cc: Rasmus Villemoes +Cc: Sakari Ailus +Cc: Thomas Gleixner +Cc: Thorsten Leemhuis +Cc: Waiman Long +Cc: Will Deacon +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Stable-dep-of: 1981b296f858 ("platform/x86: dell-smbios: Fix wrong token data in sysfs") +Signed-off-by: Sasha Levin +--- + 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 ++#include ++ ++#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 + #include + #include ++#include + #include + #include + #include +@@ -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 index 00000000000..4059126f6c2 --- /dev/null +++ b/queue-5.15/liquidio-adjust-a-null-pointer-handling-path-in-lio_.patch @@ -0,0 +1,69 @@ +From c4758fe3d587e1218b52109b67210243a20dbda6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..3458fd6b144 --- /dev/null +++ b/queue-5.15/net-geneve-support-ipv4-ipv6-as-inner-protocol.patch @@ -0,0 +1,237 @@ +From 22a477d9afb27913859c9a0b757f579b0ec260e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Mar 2022 08:15:57 +0200 +Subject: net: geneve: support IPv4/IPv6 as inner protocol + +From: Eyal Birger + +[ 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 +Link: https://lore.kernel.org/r/20220316061557.431872-1-eyal.birger@gmail.com +Signed-off-by: Paolo Abeni +Stable-dep-of: c6ae073f5903 ("geneve: Fix incorrect inner network header offset when innerprotoinherit is set") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..e9383fc9075 --- /dev/null +++ b/queue-5.15/net-hns3-add-cond_resched-to-hns3-ring-buffer-init-p.patch @@ -0,0 +1,64 @@ +From d6e7a1dc2a3f83b1b26bca4ae31a9175f5c96ba6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Jun 2024 15:20:58 +0800 +Subject: net: hns3: add cond_resched() to hns3 ring buffer init process + +From: Jie Wang + +[ 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 +Signed-off-by: Jijie Shao +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..f9894a779fc --- /dev/null +++ b/queue-5.15/net-hns3-fix-kernel-crash-problem-in-concurrent-scen.patch @@ -0,0 +1,84 @@ +From 2b94bb07aa977d96b2e70439dc6c7e38f1a51fbc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Jun 2024 15:20:57 +0800 +Subject: net: hns3: fix kernel crash problem in concurrent scenario + +From: Yonglong Liu + +[ 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 +Signed-off-by: Jijie Shao +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..204b93c96d1 --- /dev/null +++ b/queue-5.15/net-ipv6-fix-the-rt-cache-flush-via-sysctl-using-a-p.patch @@ -0,0 +1,53 @@ +From 94792a7caf3a613a7ac689c35604766c65219690 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: David Ahern +Link: https://lore.kernel.org/r/20240607112828.30285-1-petr.pavlu@suse.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..c2e08ef140a --- /dev/null +++ b/queue-5.15/net-mlx5e-fix-features-validation-check-for-tunneled.patch @@ -0,0 +1,53 @@ +From 948110cffd5f7005b5f07298eea0df700fe02def Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Dragos Tatulea +Signed-off-by: Tariq Toukan +Reviewed-by: Wojciech Drewek +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..2e9bb0885df --- /dev/null +++ b/queue-5.15/net-sfp-always-call-sfp_sm_mod_remove-on-remove.patch @@ -0,0 +1,45 @@ +From db3f89d4899858a2780ccbcaaf5b44b0e155beb9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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" +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/20240605084251.63502-1-csokas.bence@prolan.hu +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..fef35ae7305 --- /dev/null +++ b/queue-5.15/net-stmmac-replace-priv-speed-with-the-porttransmitr.patch @@ -0,0 +1,101 @@ +From 986c1b3d501857dbffd83e8a71980335aa280af2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Wojciech Drewek +Reviewed-by: Vladimir Oltean +Link: https://lore.kernel.org/r/20240608143524.2065736-1-xiaolei.wang@windriver.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..ad9a56719d2 --- /dev/null +++ b/queue-5.15/netfilter-ipset-fix-race-between-namespace-cleanup-a.patch @@ -0,0 +1,289 @@ +From e6ce1ecf7124e8d5d84072cf8d5ff1c9521f86a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Tested-by: Lion Ackermann +Signed-off-by: Jozsef Kadlecsik +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..56b602c29b5 --- /dev/null +++ b/queue-5.15/netfilter-use-flowlabel-flow-key-when-re-routing-man.patch @@ -0,0 +1,41 @@ +From 0259c5da8317eb01ce43b537caf0b764ff1c674b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Jun 2024 12:23:31 +0200 +Subject: netfilter: Use flowlabel flow key when re-routing mangled packets + +From: Florian Westphal + +[ 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 +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..e2978099478 --- /dev/null +++ b/queue-5.15/platform-x86-dell-smbios-base-use-sysfs_emit.patch @@ -0,0 +1,46 @@ +From 299b3fe90591a83405fb1a14b45861ed130cf097 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Sep 2022 06:32:33 +0000 +Subject: platform/x86: dell-smbios-base: Use sysfs_emit() + +From: ye xingchen + +[ Upstream commit bbfa903b4f9a0a76719f386367fed5e64187f577 ] + +Replace the open-code with sysfs_emit() to simplify the code. + +Signed-off-by: ye xingchen +Link: https://lore.kernel.org/r/20220923063233.239091-1-ye.xingchen@zte.com.cn +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Stable-dep-of: 1981b296f858 ("platform/x86: dell-smbios: Fix wrong token data in sysfs") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..199ada7d15e --- /dev/null +++ b/queue-5.15/platform-x86-dell-smbios-fix-wrong-token-data-in-sys.patch @@ -0,0 +1,226 @@ +From 51796ff6275645c5e3ad62f5d4e36b574cd2f24b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Ilpo Järvinen +Link: https://lore.kernel.org/r/20240528204903.445546-1-W_Armin@gmx.de +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Sasha Levin +--- + 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 + #include + #include + #include +@@ -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 + diff --git a/queue-5.15/series b/queue-5.15/series index d726cbc7064..0614ae9b4e0 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -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 index 00000000000..c9f16ce2e56 --- /dev/null +++ b/queue-5.15/sunrpc-return-proper-error-from-gss_wrap_req_priv.patch @@ -0,0 +1,40 @@ +From 92e836c84e388d16f481e12103500b0b0d2cb502 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 May 2024 16:47:16 +0800 +Subject: SUNRPC: return proper error from gss_wrap_req_priv + +From: Chen Hanxiao + +[ Upstream commit 33c94d7e3cb84f6d130678d6d59ba475a6c489cf ] + +don't return 0 if snd_buf->len really greater than snd_buf->buflen + +Signed-off-by: Chen Hanxiao +Fixes: 0c77668ddb4e ("SUNRPC: Introduce trace points in rpc_auth_gss.ko") +Reviewed-by: Benjamin Coddington +Reviewed-by: Chuck Lever +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..e2049a78d68 --- /dev/null +++ b/queue-5.15/tcp-fix-race-in-tcp_v6_syn_recv_sock.patch @@ -0,0 +1,54 @@ +From 08b1020b8872acde665d8f403430b074297b8e10 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Jun 2024 15:46:51 +0000 +Subject: tcp: fix race in tcp_v6_syn_recv_sock() + +From: Eric Dumazet + +[ 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 +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 + -- 2.47.3