From 45b8eecd7a084c3eebf6de3c318fcd172d63f250 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Fri, 25 Jul 2025 11:06:05 -0400 Subject: [PATCH] Fixes for 6.6 Signed-off-by: Sasha Levin --- ...art-move-debug-message-and-stats-aft.patch | 54 ++++ ...art-reverse-logic-to-remove-need-for.patch | 47 ++++ ...changelink-fix-null-pointer-deref-of.patch | 119 +++++++++ ...65dsi86-remove-extra-semicolon-in-ti.patch | 40 +++ ..._missed_errors-for-buffer-exhaustion.patch | 120 +++++++++ ...x_dropped-with-tx_errors-instead-of-.patch | 108 ++++++++ ...ng-vf-mac-filters-only-check-pf-set-.patch | 59 +++++ ...x-use-after-free-in-aarp-proxy-probe.patch | 185 +++++++++++++ ...-enable-tx-bounce-buffer-when-smmu-e.patch | 125 +++++++++ ...sable-interrupt-when-ptp-init-failed.patch | 66 +++++ ...concurrent-setting-vlan-filter-issue.patch | 105 ++++++++ ...t-hns3-fixed-vf-get-max-channels-bug.patch | 45 ++++ ...h-fix-peer-miss-rules-to-use-peer-es.patch | 245 ++++++++++++++++++ ...net-mlx5-fix-memory-leak-in-cmd_exec.patch | 47 ++++ ...q-avoid-triggering-might_sleep-in-at.patch | 74 ++++++ ...ix-concurrency-management-in-ism_cmd.patch | 100 +++++++ queue-6.6/series | 17 ++ ...ix-use-after-free-after-changing-col.patch | 97 +++++++ 18 files changed, 1653 insertions(+) create mode 100644 queue-6.6/can-dev-can_restart-move-debug-message-and-stats-aft.patch create mode 100644 queue-6.6/can-dev-can_restart-reverse-logic-to-remove-need-for.patch create mode 100644 queue-6.6/can-netlink-can_changelink-fix-null-pointer-deref-of.patch create mode 100644 queue-6.6/drm-bridge-ti-sn65dsi86-remove-extra-semicolon-in-ti.patch create mode 100644 queue-6.6/i40e-add-rx_missed_errors-for-buffer-exhaustion.patch create mode 100644 queue-6.6/i40e-report-vf-tx_dropped-with-tx_errors-instead-of-.patch create mode 100644 queue-6.6/i40e-when-removing-vf-mac-filters-only-check-pf-set-.patch create mode 100644 queue-6.6/net-appletalk-fix-use-after-free-in-aarp-proxy-probe.patch create mode 100644 queue-6.6/net-hns3-default-enable-tx-bounce-buffer-when-smmu-e.patch create mode 100644 queue-6.6/net-hns3-disable-interrupt-when-ptp-init-failed.patch create mode 100644 queue-6.6/net-hns3-fix-concurrent-setting-vlan-filter-issue.patch create mode 100644 queue-6.6/net-hns3-fixed-vf-get-max-channels-bug.patch create mode 100644 queue-6.6/net-mlx5-e-switch-fix-peer-miss-rules-to-use-peer-es.patch create mode 100644 queue-6.6/net-mlx5-fix-memory-leak-in-cmd_exec.patch create mode 100644 queue-6.6/net-sched-sch_qfq-avoid-triggering-might_sleep-in-at.patch create mode 100644 queue-6.6/s390-ism-fix-concurrency-management-in-ism_cmd.patch create mode 100644 queue-6.6/xfrm-interface-fix-use-after-free-after-changing-col.patch diff --git a/queue-6.6/can-dev-can_restart-move-debug-message-and-stats-aft.patch b/queue-6.6/can-dev-can_restart-move-debug-message-and-stats-aft.patch new file mode 100644 index 0000000000..d265834c30 --- /dev/null +++ b/queue-6.6/can-dev-can_restart-move-debug-message-and-stats-aft.patch @@ -0,0 +1,54 @@ +From a5372ceb0f0990d3e51f4f6d7d05a18d854c9a80 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 10:18:02 +0200 +Subject: can: dev: can_restart(): move debug message and stats after + successful restart + +From: Marc Kleine-Budde + +[ Upstream commit f0e0c809c0be05fe865b9ac128ef3ee35c276021 ] + +Move the debug message "restarted" and the CAN restart stats_after_ +the successful restart of the CAN device, because the restart may +fail. + +While there update the error message from printing the error number to +printing symbolic error names. + +Link: https://lore.kernel.org/all/20231005-can-dev-fix-can-restart-v2-4-91b5c1fd922c@pengutronix.de +Reviewed-by: Vincent Mailhol +[mkl: mention stats in subject and description, too] +Signed-off-by: Marc Kleine-Budde +Stable-dep-of: c1f3f9797c1f ("can: netlink: can_changelink(): fix NULL pointer deref of struct can_priv::do_set_mode") +Signed-off-by: Sasha Levin +--- + drivers/net/can/dev/dev.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c +index 6c1ceb8ce6c4b..88f345966c991 100644 +--- a/drivers/net/can/dev/dev.c ++++ b/drivers/net/can/dev/dev.c +@@ -147,15 +147,15 @@ static void can_restart(struct net_device *dev) + netif_rx(skb); + } + +- netdev_dbg(dev, "restarted\n"); +- priv->can_stats.restarts++; +- + /* Now restart the device */ + netif_carrier_on(dev); + err = priv->do_set_mode(dev, CAN_MODE_START); + if (err) { +- netdev_err(dev, "Error %d during restart", err); ++ netdev_err(dev, "Restart failed, error %pe\n", ERR_PTR(err)); + netif_carrier_off(dev); ++ } else { ++ netdev_dbg(dev, "Restarted\n"); ++ priv->can_stats.restarts++; + } + } + +-- +2.39.5 + diff --git a/queue-6.6/can-dev-can_restart-reverse-logic-to-remove-need-for.patch b/queue-6.6/can-dev-can_restart-reverse-logic-to-remove-need-for.patch new file mode 100644 index 0000000000..ccb23687d4 --- /dev/null +++ b/queue-6.6/can-dev-can_restart-reverse-logic-to-remove-need-for.patch @@ -0,0 +1,47 @@ +From 4538e7c4622dcdaee5721dbb395774a0279dd646 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 09:47:38 +0200 +Subject: can: dev: can_restart(): reverse logic to remove need for goto + +From: Marc Kleine-Budde + +[ Upstream commit 8f3ec204d340af183fb2bb21b8e797ac2ed012b2 ] + +Reverse the logic in the if statement and eliminate the need for a +goto to simplify code readability. + +Link: https://lore.kernel.org/all/20231005-can-dev-fix-can-restart-v2-3-91b5c1fd922c@pengutronix.de +Reviewed-by: Vincent Mailhol +Signed-off-by: Marc Kleine-Budde +Stable-dep-of: c1f3f9797c1f ("can: netlink: can_changelink(): fix NULL pointer deref of struct can_priv::do_set_mode") +Signed-off-by: Sasha Levin +--- + drivers/net/can/dev/dev.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c +index 7d9a7c92d4cf6..6c1ceb8ce6c4b 100644 +--- a/drivers/net/can/dev/dev.c ++++ b/drivers/net/can/dev/dev.c +@@ -142,14 +142,11 @@ static void can_restart(struct net_device *dev) + + /* send restart message upstream */ + skb = alloc_can_err_skb(dev, &cf); +- if (!skb) +- goto restart; +- +- cf->can_id |= CAN_ERR_RESTARTED; +- +- netif_rx(skb); ++ if (skb) { ++ cf->can_id |= CAN_ERR_RESTARTED; ++ netif_rx(skb); ++ } + +-restart: + netdev_dbg(dev, "restarted\n"); + priv->can_stats.restarts++; + +-- +2.39.5 + diff --git a/queue-6.6/can-netlink-can_changelink-fix-null-pointer-deref-of.patch b/queue-6.6/can-netlink-can_changelink-fix-null-pointer-deref-of.patch new file mode 100644 index 0000000000..2c7f0c8470 --- /dev/null +++ b/queue-6.6/can-netlink-can_changelink-fix-null-pointer-deref-of.patch @@ -0,0 +1,119 @@ +From 39fcb32f54fe5fe526d41597b7493fbe5dc9e73a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Jul 2025 22:35:46 +0200 +Subject: can: netlink: can_changelink(): fix NULL pointer deref of struct + can_priv::do_set_mode + +From: Marc Kleine-Budde + +[ Upstream commit c1f3f9797c1f44a762e6f5f72520b2e520537b52 ] + +Andrei Lalaev reported a NULL pointer deref when a CAN device is +restarted from Bus Off and the driver does not implement the struct +can_priv::do_set_mode callback. + +There are 2 code path that call struct can_priv::do_set_mode: +- directly by a manual restart from the user space, via + can_changelink() +- delayed automatic restart after bus off (deactivated by default) + +To prevent the NULL pointer deference, refuse a manual restart or +configure the automatic restart delay in can_changelink() and report +the error via extack to user space. + +As an additional safety measure let can_restart() return an error if +can_priv::do_set_mode is not set instead of dereferencing it +unchecked. + +Reported-by: Andrei Lalaev +Closes: https://lore.kernel.org/all/20250714175520.307467-1-andrey.lalaev@gmail.com +Fixes: 39549eef3587 ("can: CAN Network device driver and Netlink interface") +Link: https://patch.msgid.link/20250718-fix-nullptr-deref-do_set_mode-v1-1-0b520097bb96@pengutronix.de +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/dev/dev.c | 12 +++++++++--- + drivers/net/can/dev/netlink.c | 12 ++++++++++++ + 2 files changed, 21 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c +index 88f345966c991..6018444a76b9b 100644 +--- a/drivers/net/can/dev/dev.c ++++ b/drivers/net/can/dev/dev.c +@@ -125,13 +125,16 @@ void can_change_state(struct net_device *dev, struct can_frame *cf, + EXPORT_SYMBOL_GPL(can_change_state); + + /* CAN device restart for bus-off recovery */ +-static void can_restart(struct net_device *dev) ++static int can_restart(struct net_device *dev) + { + struct can_priv *priv = netdev_priv(dev); + struct sk_buff *skb; + struct can_frame *cf; + int err; + ++ if (!priv->do_set_mode) ++ return -EOPNOTSUPP; ++ + if (netif_carrier_ok(dev)) + netdev_err(dev, "Attempt to restart for bus-off recovery, but carrier is OK?\n"); + +@@ -153,10 +156,14 @@ static void can_restart(struct net_device *dev) + if (err) { + netdev_err(dev, "Restart failed, error %pe\n", ERR_PTR(err)); + netif_carrier_off(dev); ++ ++ return err; + } else { + netdev_dbg(dev, "Restarted\n"); + priv->can_stats.restarts++; + } ++ ++ return 0; + } + + static void can_restart_work(struct work_struct *work) +@@ -181,9 +188,8 @@ int can_restart_now(struct net_device *dev) + return -EBUSY; + + cancel_delayed_work_sync(&priv->restart_work); +- can_restart(dev); + +- return 0; ++ return can_restart(dev); + } + + /* CAN bus-off +diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c +index 01aacdcda2606..abe8dc051d94f 100644 +--- a/drivers/net/can/dev/netlink.c ++++ b/drivers/net/can/dev/netlink.c +@@ -285,6 +285,12 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[], + } + + if (data[IFLA_CAN_RESTART_MS]) { ++ if (!priv->do_set_mode) { ++ NL_SET_ERR_MSG(extack, ++ "Device doesn't support restart from Bus Off"); ++ return -EOPNOTSUPP; ++ } ++ + /* Do not allow changing restart delay while running */ + if (dev->flags & IFF_UP) + return -EBUSY; +@@ -292,6 +298,12 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[], + } + + if (data[IFLA_CAN_RESTART]) { ++ if (!priv->do_set_mode) { ++ NL_SET_ERR_MSG(extack, ++ "Device doesn't support restart from Bus Off"); ++ return -EOPNOTSUPP; ++ } ++ + /* Do not allow a restart while not running */ + if (!(dev->flags & IFF_UP)) + return -EINVAL; +-- +2.39.5 + diff --git a/queue-6.6/drm-bridge-ti-sn65dsi86-remove-extra-semicolon-in-ti.patch b/queue-6.6/drm-bridge-ti-sn65dsi86-remove-extra-semicolon-in-ti.patch new file mode 100644 index 0000000000..b1d99cdea1 --- /dev/null +++ b/queue-6.6/drm-bridge-ti-sn65dsi86-remove-extra-semicolon-in-ti.patch @@ -0,0 +1,40 @@ +From f764d72f0978de55de4c15c0093100326e3e5c7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Jul 2025 13:06:32 -0700 +Subject: drm/bridge: ti-sn65dsi86: Remove extra semicolon in + ti_sn_bridge_probe() + +From: Douglas Anderson + +[ Upstream commit 15a7ca747d9538c2ad8b0c81dd4c1261e0736c82 ] + +As reported by the kernel test robot, a recent patch introduced an +unnecessary semicolon. Remove it. + +Fixes: 55e8ff842051 ("drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202506301704.0SBj6ply-lkp@intel.com/ +Reviewed-by: Devarsh Thakkar +Signed-off-by: Douglas Anderson +Link: https://lore.kernel.org/r/20250714130631.1.I1cfae3222e344a3b3c770d079ee6b6f7f3b5d636@changeid +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/ti-sn65dsi86.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c +index 002f8aaa509bc..59cbff209acd6 100644 +--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c ++++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c +@@ -1352,7 +1352,7 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev, + regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, + HPD_DISABLE, 0); + mutex_unlock(&pdata->comms_mutex); +- }; ++ } + + drm_bridge_add(&pdata->bridge); + +-- +2.39.5 + diff --git a/queue-6.6/i40e-add-rx_missed_errors-for-buffer-exhaustion.patch b/queue-6.6/i40e-add-rx_missed_errors-for-buffer-exhaustion.patch new file mode 100644 index 0000000000..c95f204229 --- /dev/null +++ b/queue-6.6/i40e-add-rx_missed_errors-for-buffer-exhaustion.patch @@ -0,0 +1,120 @@ +From 4a355a46ff46f58db9c549da5bb6694541693d01 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 15:27:57 +0800 +Subject: i40e: Add rx_missed_errors for buffer exhaustion + +From: Yajun Deng + +[ Upstream commit 5337d294973331660e84e41836a54014de22e5b0 ] + +As the comment in struct rtnl_link_stats64, rx_dropped should not +include packets dropped by the device due to buffer exhaustion. +They are counted in rx_missed_errors, procfs folds those two counters +together. + +Add rx_missed_errors for buffer exhaustion, rx_missed_errors corresponds +to rx_discards, rx_dropped corresponds to rx_discards_other. + +Signed-off-by: Yajun Deng +Tested-by: Arpana Arland (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: 50b2af451597 ("i40e: report VF tx_dropped with tx_errors instead of tx_discards") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 3 ++- + drivers/net/ethernet/intel/i40e/i40e_main.c | 18 +++++++----------- + .../net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 2 +- + 3 files changed, 10 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +index 4e90570ba7803..a89f7ca510fdb 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +@@ -246,6 +246,7 @@ static const struct i40e_stats i40e_gstrings_net_stats[] = { + I40E_NETDEV_STAT(rx_errors), + I40E_NETDEV_STAT(tx_errors), + I40E_NETDEV_STAT(rx_dropped), ++ I40E_NETDEV_STAT(rx_missed_errors), + I40E_NETDEV_STAT(tx_dropped), + I40E_NETDEV_STAT(collisions), + I40E_NETDEV_STAT(rx_length_errors), +@@ -322,7 +323,7 @@ static const struct i40e_stats i40e_gstrings_stats[] = { + I40E_PF_STAT("port.rx_broadcast", stats.eth.rx_broadcast), + I40E_PF_STAT("port.tx_broadcast", stats.eth.tx_broadcast), + I40E_PF_STAT("port.tx_errors", stats.eth.tx_errors), +- I40E_PF_STAT("port.rx_dropped", stats.eth.rx_discards), ++ I40E_PF_STAT("port.rx_discards", stats.eth.rx_discards), + I40E_PF_STAT("port.tx_dropped_link_down", stats.tx_dropped_link_down), + I40E_PF_STAT("port.rx_crc_errors", stats.crc_errors), + I40E_PF_STAT("port.illegal_bytes", stats.illegal_bytes), +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index 806cec458a072..b749aa3e783ff 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -509,6 +509,7 @@ static void i40e_get_netdev_stats_struct(struct net_device *netdev, + stats->tx_dropped = vsi_stats->tx_dropped; + stats->rx_errors = vsi_stats->rx_errors; + stats->rx_dropped = vsi_stats->rx_dropped; ++ stats->rx_missed_errors = vsi_stats->rx_missed_errors; + stats->rx_crc_errors = vsi_stats->rx_crc_errors; + stats->rx_length_errors = vsi_stats->rx_length_errors; + } +@@ -700,17 +701,13 @@ i40e_stats_update_rx_discards(struct i40e_vsi *vsi, struct i40e_hw *hw, + struct i40e_eth_stats *stat_offset, + struct i40e_eth_stats *stat) + { +- u64 rx_rdpc, rx_rxerr; +- + i40e_stat_update32(hw, I40E_GLV_RDPC(stat_idx), offset_loaded, +- &stat_offset->rx_discards, &rx_rdpc); ++ &stat_offset->rx_discards, &stat->rx_discards); + i40e_stat_update64(hw, + I40E_GL_RXERR1H(i40e_compute_pci_to_hw_id(vsi, hw)), + I40E_GL_RXERR1L(i40e_compute_pci_to_hw_id(vsi, hw)), + offset_loaded, &stat_offset->rx_discards_other, +- &rx_rxerr); +- +- stat->rx_discards = rx_rdpc + rx_rxerr; ++ &stat->rx_discards_other); + } + + /** +@@ -732,9 +729,6 @@ void i40e_update_eth_stats(struct i40e_vsi *vsi) + i40e_stat_update32(hw, I40E_GLV_TEPC(stat_idx), + vsi->stat_offsets_loaded, + &oes->tx_errors, &es->tx_errors); +- i40e_stat_update32(hw, I40E_GLV_RDPC(stat_idx), +- vsi->stat_offsets_loaded, +- &oes->rx_discards, &es->rx_discards); + i40e_stat_update32(hw, I40E_GLV_RUPP(stat_idx), + vsi->stat_offsets_loaded, + &oes->rx_unknown_protocol, &es->rx_unknown_protocol); +@@ -991,8 +985,10 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) + ns->tx_errors = es->tx_errors; + ons->multicast = oes->rx_multicast; + ns->multicast = es->rx_multicast; +- ons->rx_dropped = oes->rx_discards; +- ns->rx_dropped = es->rx_discards; ++ ons->rx_dropped = oes->rx_discards_other; ++ ns->rx_dropped = es->rx_discards_other; ++ ons->rx_missed_errors = oes->rx_discards; ++ ns->rx_missed_errors = es->rx_discards; + ons->tx_dropped = oes->tx_discards; + ns->tx_dropped = es->tx_discards; + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 80036942dc764..18720e9c24f73 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -5010,7 +5010,7 @@ int i40e_get_vf_stats(struct net_device *netdev, int vf_id, + vf_stats->tx_bytes = stats->tx_bytes; + vf_stats->broadcast = stats->rx_broadcast; + vf_stats->multicast = stats->rx_multicast; +- vf_stats->rx_dropped = stats->rx_discards; ++ vf_stats->rx_dropped = stats->rx_discards + stats->rx_discards_other; + vf_stats->tx_dropped = stats->tx_discards; + + return 0; +-- +2.39.5 + diff --git a/queue-6.6/i40e-report-vf-tx_dropped-with-tx_errors-instead-of-.patch b/queue-6.6/i40e-report-vf-tx_dropped-with-tx_errors-instead-of-.patch new file mode 100644 index 0000000000..b6cdcac6bb --- /dev/null +++ b/queue-6.6/i40e-report-vf-tx_dropped-with-tx_errors-instead-of-.patch @@ -0,0 +1,108 @@ +From 228f9fbff4b3747e218bf4699f1224c2259db6cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Jun 2025 15:52:40 -0400 +Subject: i40e: report VF tx_dropped with tx_errors instead of tx_discards + +From: Dennis Chen + +[ Upstream commit 50b2af451597ca6eefe9d4543f8bbf8de8aa00e7 ] + +Currently the tx_dropped field in VF stats is not updated correctly +when reading stats from the PF. This is because it reads from +i40e_eth_stats.tx_discards which seems to be unused for per VSI stats, +as it is not updated by i40e_update_eth_stats() and the corresponding +register, GLV_TDPC, is not implemented[1]. + +Use i40e_eth_stats.tx_errors instead, which is actually updated by +i40e_update_eth_stats() by reading from GLV_TEPC. + +To test, create a VF and try to send bad packets through it: + +$ echo 1 > /sys/class/net/enp2s0f0/device/sriov_numvfs +$ cat test.py +from scapy.all import * + +vlan_pkt = Ether(dst="ff:ff:ff:ff:ff:ff") / Dot1Q(vlan=999) / IP(dst="192.168.0.1") / ICMP() +ttl_pkt = IP(dst="8.8.8.8", ttl=0) / ICMP() + +print("Send packet with bad VLAN tag") +sendp(vlan_pkt, iface="enp2s0f0v0") +print("Send packet with TTL=0") +sendp(ttl_pkt, iface="enp2s0f0v0") +$ ip -s link show dev enp2s0f0 +16: enp2s0f0: mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 + link/ether 3c:ec:ef:b7:e0:ac brd ff:ff:ff:ff:ff:ff + RX: bytes packets errors dropped missed mcast + 0 0 0 0 0 0 + TX: bytes packets errors dropped carrier collsns + 0 0 0 0 0 0 + vf 0 link/ether e2:c6:fd:c1:1e:92 brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off + RX: bytes packets mcast bcast dropped + 0 0 0 0 0 + TX: bytes packets dropped + 0 0 0 +$ python test.py +Send packet with bad VLAN tag +. +Sent 1 packets. +Send packet with TTL=0 +. +Sent 1 packets. +$ ip -s link show dev enp2s0f0 +16: enp2s0f0: mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 + link/ether 3c:ec:ef:b7:e0:ac brd ff:ff:ff:ff:ff:ff + RX: bytes packets errors dropped missed mcast + 0 0 0 0 0 0 + TX: bytes packets errors dropped carrier collsns + 0 0 0 0 0 0 + vf 0 link/ether e2:c6:fd:c1:1e:92 brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off + RX: bytes packets mcast bcast dropped + 0 0 0 0 0 + TX: bytes packets dropped + 0 0 0 + +A packet with non-existent VLAN tag and a packet with TTL = 0 are sent, +but tx_dropped is not incremented. + +After patch: + +$ ip -s link show dev enp2s0f0 +19: enp2s0f0: mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 + link/ether 3c:ec:ef:b7:e0:ac brd ff:ff:ff:ff:ff:ff + RX: bytes packets errors dropped missed mcast + 0 0 0 0 0 0 + TX: bytes packets errors dropped carrier collsns + 0 0 0 0 0 0 + vf 0 link/ether 4a:b7:3d:37:f7:56 brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off + RX: bytes packets mcast bcast dropped + 0 0 0 0 0 + TX: bytes packets dropped + 0 0 2 + +Fixes: dc645daef9af5bcbd9c ("i40e: implement VF stats NDO") +Signed-off-by: Dennis Chen +Link: https://www.intel.com/content/www/us/en/content-details/596333/intel-ethernet-controller-x710-tm4-at2-carlsville-datasheet.html +Reviewed-by: Simon Horman +Tested-by: Rafal Romanowski +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 18720e9c24f73..b233ae45d89c2 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -5011,7 +5011,7 @@ int i40e_get_vf_stats(struct net_device *netdev, int vf_id, + vf_stats->broadcast = stats->rx_broadcast; + vf_stats->multicast = stats->rx_multicast; + vf_stats->rx_dropped = stats->rx_discards + stats->rx_discards_other; +- vf_stats->tx_dropped = stats->tx_discards; ++ vf_stats->tx_dropped = stats->tx_errors; + + return 0; + } +-- +2.39.5 + diff --git a/queue-6.6/i40e-when-removing-vf-mac-filters-only-check-pf-set-.patch b/queue-6.6/i40e-when-removing-vf-mac-filters-only-check-pf-set-.patch new file mode 100644 index 0000000000..20a07693b8 --- /dev/null +++ b/queue-6.6/i40e-when-removing-vf-mac-filters-only-check-pf-set-.patch @@ -0,0 +1,59 @@ +From 4c9985f5138da31c2a8e1a27b0681499a909aa1a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Jun 2025 09:29:18 +1000 +Subject: i40e: When removing VF MAC filters, only check PF-set MAC + +From: Jamie Bainbridge + +[ Upstream commit 5a0df02999dbe838c3feed54b1d59e9445f68b89 ] + +When the PF is processing an Admin Queue message to delete a VF's MACs +from the MAC filter, we currently check if the PF set the MAC and if +the VF is trusted. + +This results in undesirable behaviour, where if a trusted VF with a +PF-set MAC sets itself down (which sends an AQ message to delete the +VF's MAC filters) then the VF MAC is erased from the interface. + +This results in the VF losing its PF-set MAC which should not happen. + +There is no need to check for trust at all, because an untrusted VF +cannot change its own MAC. The only check needed is whether the PF set +the MAC. If the PF set the MAC, then don't erase the MAC on link-down. + +Resolve this by changing the deletion check only for PF-set MAC. + +(the out-of-tree driver has also intentionally removed the check for VF +trust here with OOT driver version 2.26.8, this changes the Linux kernel +driver behaviour and comment to match the OOT driver behaviour) + +Fixes: ea2a1cfc3b201 ("i40e: Fix VF MAC filter removal") +Signed-off-by: Jamie Bainbridge +Reviewed-by: Simon Horman +Tested-by: Rafal Romanowski +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index b233ae45d89c2..6d7a4f2c3a49b 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -3143,10 +3143,10 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg) + const u8 *addr = al->list[i].addr; + + /* Allow to delete VF primary MAC only if it was not set +- * administratively by PF or if VF is trusted. ++ * administratively by PF. + */ + if (ether_addr_equal(addr, vf->default_lan_addr.addr)) { +- if (i40e_can_vf_change_mac(vf)) ++ if (!vf->pf_set_mac) + was_unimac_deleted = true; + else + continue; +-- +2.39.5 + diff --git a/queue-6.6/net-appletalk-fix-use-after-free-in-aarp-proxy-probe.patch b/queue-6.6/net-appletalk-fix-use-after-free-in-aarp-proxy-probe.patch new file mode 100644 index 0000000000..9808c2e7c5 --- /dev/null +++ b/queue-6.6/net-appletalk-fix-use-after-free-in-aarp-proxy-probe.patch @@ -0,0 +1,185 @@ +From 1e6185d0aac0b96f236f803b6f547c021d580de2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Jul 2025 01:28:43 +0000 +Subject: net: appletalk: Fix use-after-free in AARP proxy probe +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kito Xu (veritas501) + +[ Upstream commit 6c4a92d07b0850342d3becf2e608f805e972467c ] + +The AARP proxy‐probe routine (aarp_proxy_probe_network) sends a probe, +releases the aarp_lock, sleeps, then re-acquires the lock. During that +window an expire timer thread (__aarp_expire_timer) can remove and +kfree() the same entry, leading to a use-after-free. + +race condition: + + cpu 0 | cpu 1 + atalk_sendmsg() | atif_proxy_probe_device() + aarp_send_ddp() | aarp_proxy_probe_network() + mod_timer() | lock(aarp_lock) // LOCK!! + timeout around 200ms | alloc(aarp_entry) + and then call | proxies[hash] = aarp_entry + aarp_expire_timeout() | aarp_send_probe() + | unlock(aarp_lock) // UNLOCK!! + lock(aarp_lock) // LOCK!! | msleep(100); + __aarp_expire_timer(&proxies[ct]) | + free(aarp_entry) | + unlock(aarp_lock) // UNLOCK!! | + | lock(aarp_lock) // LOCK!! + | UAF aarp_entry !! + +================================================================== +BUG: KASAN: slab-use-after-free in aarp_proxy_probe_network+0x560/0x630 net/appletalk/aarp.c:493 +Read of size 4 at addr ffff8880123aa360 by task repro/13278 + +CPU: 3 UID: 0 PID: 13278 Comm: repro Not tainted 6.15.2 #3 PREEMPT(full) +Call Trace: + + __dump_stack lib/dump_stack.c:94 [inline] + dump_stack_lvl+0x116/0x1b0 lib/dump_stack.c:120 + print_address_description mm/kasan/report.c:408 [inline] + print_report+0xc1/0x630 mm/kasan/report.c:521 + kasan_report+0xca/0x100 mm/kasan/report.c:634 + aarp_proxy_probe_network+0x560/0x630 net/appletalk/aarp.c:493 + atif_proxy_probe_device net/appletalk/ddp.c:332 [inline] + atif_ioctl+0xb58/0x16c0 net/appletalk/ddp.c:857 + atalk_ioctl+0x198/0x2f0 net/appletalk/ddp.c:1818 + sock_do_ioctl+0xdc/0x260 net/socket.c:1190 + sock_ioctl+0x239/0x6a0 net/socket.c:1311 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:906 [inline] + __se_sys_ioctl fs/ioctl.c:892 [inline] + __x64_sys_ioctl+0x194/0x200 fs/ioctl.c:892 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xcb/0x250 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + + +Allocated: + aarp_alloc net/appletalk/aarp.c:382 [inline] + aarp_proxy_probe_network+0xd8/0x630 net/appletalk/aarp.c:468 + atif_proxy_probe_device net/appletalk/ddp.c:332 [inline] + atif_ioctl+0xb58/0x16c0 net/appletalk/ddp.c:857 + atalk_ioctl+0x198/0x2f0 net/appletalk/ddp.c:1818 + +Freed: + kfree+0x148/0x4d0 mm/slub.c:4841 + __aarp_expire net/appletalk/aarp.c:90 [inline] + __aarp_expire_timer net/appletalk/aarp.c:261 [inline] + aarp_expire_timeout+0x480/0x6e0 net/appletalk/aarp.c:317 + +The buggy address belongs to the object at ffff8880123aa300 + which belongs to the cache kmalloc-192 of size 192 +The buggy address is located 96 bytes inside of + freed 192-byte region [ffff8880123aa300, ffff8880123aa3c0) + +Memory state around the buggy address: + ffff8880123aa200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + ffff8880123aa280: 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc fc +>ffff8880123aa300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ^ + ffff8880123aa380: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc + ffff8880123aa400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +================================================================== + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kito Xu (veritas501) +Link: https://patch.msgid.link/20250717012843.880423-1-hxzene@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/appletalk/aarp.c | 24 +++++++++++++++++++++--- + 1 file changed, 21 insertions(+), 3 deletions(-) + +diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c +index c7236daa24152..0d7c14a496681 100644 +--- a/net/appletalk/aarp.c ++++ b/net/appletalk/aarp.c +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + + int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME; + int sysctl_aarp_tick_time = AARP_TICK_TIME; +@@ -44,6 +45,7 @@ int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME; + /* Lists of aarp entries */ + /** + * struct aarp_entry - AARP entry ++ * @refcnt: Reference count + * @last_sent: Last time we xmitted the aarp request + * @packet_queue: Queue of frames wait for resolution + * @status: Used for proxy AARP +@@ -55,6 +57,7 @@ int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME; + * @next: Next entry in chain + */ + struct aarp_entry { ++ refcount_t refcnt; + /* These first two are only used for unresolved entries */ + unsigned long last_sent; + struct sk_buff_head packet_queue; +@@ -79,6 +82,17 @@ static DEFINE_RWLOCK(aarp_lock); + /* Used to walk the list and purge/kick entries. */ + static struct timer_list aarp_timer; + ++static inline void aarp_entry_get(struct aarp_entry *a) ++{ ++ refcount_inc(&a->refcnt); ++} ++ ++static inline void aarp_entry_put(struct aarp_entry *a) ++{ ++ if (refcount_dec_and_test(&a->refcnt)) ++ kfree(a); ++} ++ + /* + * Delete an aarp queue + * +@@ -87,7 +101,7 @@ static struct timer_list aarp_timer; + static void __aarp_expire(struct aarp_entry *a) + { + skb_queue_purge(&a->packet_queue); +- kfree(a); ++ aarp_entry_put(a); + } + + /* +@@ -380,9 +394,11 @@ static void aarp_purge(void) + static struct aarp_entry *aarp_alloc(void) + { + struct aarp_entry *a = kmalloc(sizeof(*a), GFP_ATOMIC); ++ if (!a) ++ return NULL; + +- if (a) +- skb_queue_head_init(&a->packet_queue); ++ refcount_set(&a->refcnt, 1); ++ skb_queue_head_init(&a->packet_queue); + return a; + } + +@@ -508,6 +524,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa) + entry->dev = atif->dev; + + write_lock_bh(&aarp_lock); ++ aarp_entry_get(entry); + + hash = sa->s_node % (AARP_HASH_SIZE - 1); + entry->next = proxies[hash]; +@@ -533,6 +550,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa) + retval = 1; + } + ++ aarp_entry_put(entry); + write_unlock_bh(&aarp_lock); + out: + return retval; +-- +2.39.5 + diff --git a/queue-6.6/net-hns3-default-enable-tx-bounce-buffer-when-smmu-e.patch b/queue-6.6/net-hns3-default-enable-tx-bounce-buffer-when-smmu-e.patch new file mode 100644 index 0000000000..239b2f72d3 --- /dev/null +++ b/queue-6.6/net-hns3-default-enable-tx-bounce-buffer-when-smmu-e.patch @@ -0,0 +1,125 @@ +From 76a1a7ee1157ab3b77c225e2fdcac7d576a96bfd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Jul 2025 20:54:23 +0800 +Subject: net: hns3: default enable tx bounce buffer when smmu enabled + +From: Jijie Shao + +[ Upstream commit e6ab19443b36a45ebfb392775cb17d6a78dd07ea ] + +The SMMU engine on HIP09 chip has a hardware issue. +SMMU pagetable prefetch features may prefetch and use a invalid PTE +even the PTE is valid at that time. This will cause the device trigger +fake pagefaults. The solution is to avoid prefetching by adding a +SYNC command when smmu mapping a iova. But the performance of nic has a +sharp drop. Then we do this workaround, always enable tx bounce buffer, +avoid mapping/unmapping on TX path. + +This issue only affects HNS3, so we always enable +tx bounce buffer when smmu enabled to improve performance. + +Fixes: 295ba232a8c3 ("net: hns3: add device version to replace pci revision") +Signed-off-by: Peiyang Wang +Signed-off-by: Jian Shen +Signed-off-by: Jijie Shao +Signed-off-by: Paolo Abeni +Stable-dep-of: 49ade8630f36 ("net: hns3: default enable tx bounce buffer when smmu enabled") +Signed-off-by: Sasha Levin +--- + .../net/ethernet/hisilicon/hns3/hns3_enet.c | 31 +++++++++++++++++++ + .../net/ethernet/hisilicon/hns3/hns3_enet.h | 2 ++ + 2 files changed, 33 insertions(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +index 0ed01f4d68061..dbf44a17987eb 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1039,6 +1040,8 @@ static bool hns3_can_use_tx_sgl(struct hns3_enet_ring *ring, + static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring) + { + u32 alloc_size = ring->tqp->handle->kinfo.tx_spare_buf_size; ++ struct net_device *netdev = ring_to_netdev(ring); ++ struct hns3_nic_priv *priv = netdev_priv(netdev); + struct hns3_tx_spare *tx_spare; + struct page *page; + dma_addr_t dma; +@@ -1080,6 +1083,7 @@ static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring) + tx_spare->buf = page_address(page); + tx_spare->len = PAGE_SIZE << order; + ring->tx_spare = tx_spare; ++ ring->tx_copybreak = priv->tx_copybreak; + return; + + dma_mapping_error: +@@ -4879,6 +4883,30 @@ static void hns3_nic_dealloc_vector_data(struct hns3_nic_priv *priv) + devm_kfree(&pdev->dev, priv->tqp_vector); + } + ++static void hns3_update_tx_spare_buf_config(struct hns3_nic_priv *priv) ++{ ++#define HNS3_MIN_SPARE_BUF_SIZE (2 * 1024 * 1024) ++#define HNS3_MAX_PACKET_SIZE (64 * 1024) ++ ++ struct iommu_domain *domain = iommu_get_domain_for_dev(priv->dev); ++ struct hnae3_ae_dev *ae_dev = hns3_get_ae_dev(priv->ae_handle); ++ struct hnae3_handle *handle = priv->ae_handle; ++ ++ if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3) ++ return; ++ ++ if (!(domain && iommu_is_dma_domain(domain))) ++ return; ++ ++ priv->min_tx_copybreak = HNS3_MAX_PACKET_SIZE; ++ priv->min_tx_spare_buf_size = HNS3_MIN_SPARE_BUF_SIZE; ++ ++ if (priv->tx_copybreak < priv->min_tx_copybreak) ++ priv->tx_copybreak = priv->min_tx_copybreak; ++ if (handle->kinfo.tx_spare_buf_size < priv->min_tx_spare_buf_size) ++ handle->kinfo.tx_spare_buf_size = priv->min_tx_spare_buf_size; ++} ++ + static void hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv, + unsigned int ring_type) + { +@@ -5113,6 +5141,7 @@ int hns3_init_all_ring(struct hns3_nic_priv *priv) + int i, j; + int ret; + ++ hns3_update_tx_spare_buf_config(priv); + for (i = 0; i < ring_num; i++) { + ret = hns3_alloc_ring_memory(&priv->ring[i]); + if (ret) { +@@ -5317,6 +5346,8 @@ static int hns3_client_init(struct hnae3_handle *handle) + priv->ae_handle = handle; + priv->tx_timeout_count = 0; + priv->max_non_tso_bd_num = ae_dev->dev_specs.max_non_tso_bd_num; ++ priv->min_tx_copybreak = 0; ++ priv->min_tx_spare_buf_size = 0; + set_bit(HNS3_NIC_STATE_DOWN, &priv->state); + + handle->msg_enable = netif_msg_init(debug, DEFAULT_MSG_LEVEL); +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +index d36c4ed16d8dd..caf7a4df85852 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +@@ -596,6 +596,8 @@ struct hns3_nic_priv { + struct hns3_enet_coalesce rx_coal; + u32 tx_copybreak; + u32 rx_copybreak; ++ u32 min_tx_copybreak; ++ u32 min_tx_spare_buf_size; + }; + + union l3_hdr_info { +-- +2.39.5 + diff --git a/queue-6.6/net-hns3-disable-interrupt-when-ptp-init-failed.patch b/queue-6.6/net-hns3-disable-interrupt-when-ptp-init-failed.patch new file mode 100644 index 0000000000..2107d2737d --- /dev/null +++ b/queue-6.6/net-hns3-disable-interrupt-when-ptp-init-failed.patch @@ -0,0 +1,66 @@ +From 3039d03b05587ba59fc6ad1e098c1f19e17d4a71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Jul 2025 20:54:21 +0800 +Subject: net: hns3: disable interrupt when ptp init failed + +From: Yonglong Liu + +[ Upstream commit cde304655f25d94a996c45b0f9956e7dcc2bc4c0 ] + +When ptp init failed, we'd better disable the interrupt and clear the +flag, to avoid early report interrupt at next probe. + +Fixes: 0bf5eb788512 ("net: hns3: add support for PTP") +Signed-off-by: Yonglong Liu +Signed-off-by: Jijie Shao +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250722125423.1270673-3-shaojijie@huawei.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c +index 9a806ac727cf5..c1e88e67ebb65 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c +@@ -497,14 +497,14 @@ int hclge_ptp_init(struct hclge_dev *hdev) + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to init freq, ret = %d\n", ret); +- goto out; ++ goto out_clear_int; + } + + ret = hclge_ptp_set_ts_mode(hdev, &hdev->ptp->ts_cfg); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to init ts mode, ret = %d\n", ret); +- goto out; ++ goto out_clear_int; + } + + ktime_get_real_ts64(&ts); +@@ -512,7 +512,7 @@ int hclge_ptp_init(struct hclge_dev *hdev) + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to init ts time, ret = %d\n", ret); +- goto out; ++ goto out_clear_int; + } + + set_bit(HCLGE_STATE_PTP_EN, &hdev->state); +@@ -520,6 +520,9 @@ int hclge_ptp_init(struct hclge_dev *hdev) + + return 0; + ++out_clear_int: ++ clear_bit(HCLGE_PTP_FLAG_EN, &hdev->ptp->flags); ++ hclge_ptp_int_en(hdev, false); + out: + hclge_ptp_destroy_clock(hdev); + +-- +2.39.5 + diff --git a/queue-6.6/net-hns3-fix-concurrent-setting-vlan-filter-issue.patch b/queue-6.6/net-hns3-fix-concurrent-setting-vlan-filter-issue.patch new file mode 100644 index 0000000000..a317d026a9 --- /dev/null +++ b/queue-6.6/net-hns3-fix-concurrent-setting-vlan-filter-issue.patch @@ -0,0 +1,105 @@ +From 6cff320b552abea2d9d79e3e2d04a155f3d1d4be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Jul 2025 20:54:20 +0800 +Subject: net: hns3: fix concurrent setting vlan filter issue + +From: Jian Shen + +[ Upstream commit 4555f8f8b6aa46940f55feb6a07704c2935b6d6e ] + +The vport->req_vlan_fltr_en may be changed concurrently by function +hclge_sync_vlan_fltr_state() called in periodic work task and +function hclge_enable_vport_vlan_filter() called by user configuration. +It may cause the user configuration inoperative. Fixes it by protect +the vport->req_vlan_fltr by vport_lock. + +Fixes: 2ba306627f59 ("net: hns3: add support for modify VLAN filter state") +Signed-off-by: Jian Shen +Signed-off-by: Jijie Shao +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250722125423.1270673-2-shaojijie@huawei.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../hisilicon/hns3/hns3pf/hclge_main.c | 36 +++++++++++-------- + 1 file changed, 21 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 4d318af748a0b..789f72d1067f8 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -9493,33 +9493,36 @@ static bool hclge_need_enable_vport_vlan_filter(struct hclge_vport *vport) + return false; + } + +-int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en) ++static int __hclge_enable_vport_vlan_filter(struct hclge_vport *vport, ++ bool request_en) + { +- struct hclge_dev *hdev = vport->back; + bool need_en; + int ret; + +- mutex_lock(&hdev->vport_lock); +- +- vport->req_vlan_fltr_en = request_en; +- + need_en = hclge_need_enable_vport_vlan_filter(vport); +- if (need_en == vport->cur_vlan_fltr_en) { +- mutex_unlock(&hdev->vport_lock); ++ if (need_en == vport->cur_vlan_fltr_en) + return 0; +- } + + ret = hclge_set_vport_vlan_filter(vport, need_en); +- if (ret) { +- mutex_unlock(&hdev->vport_lock); ++ if (ret) + return ret; +- } + + vport->cur_vlan_fltr_en = need_en; + ++ return 0; ++} ++ ++int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en) ++{ ++ struct hclge_dev *hdev = vport->back; ++ int ret; ++ ++ mutex_lock(&hdev->vport_lock); ++ vport->req_vlan_fltr_en = request_en; ++ ret = __hclge_enable_vport_vlan_filter(vport, request_en); + mutex_unlock(&hdev->vport_lock); + +- return 0; ++ return ret; + } + + static int hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable) +@@ -10540,16 +10543,19 @@ static void hclge_sync_vlan_fltr_state(struct hclge_dev *hdev) + &vport->state)) + continue; + +- ret = hclge_enable_vport_vlan_filter(vport, +- vport->req_vlan_fltr_en); ++ mutex_lock(&hdev->vport_lock); ++ ret = __hclge_enable_vport_vlan_filter(vport, ++ vport->req_vlan_fltr_en); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to sync vlan filter state for vport%u, ret = %d\n", + vport->vport_id, ret); + set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE, + &vport->state); ++ mutex_unlock(&hdev->vport_lock); + return; + } ++ mutex_unlock(&hdev->vport_lock); + } + } + +-- +2.39.5 + diff --git a/queue-6.6/net-hns3-fixed-vf-get-max-channels-bug.patch b/queue-6.6/net-hns3-fixed-vf-get-max-channels-bug.patch new file mode 100644 index 0000000000..b85aace752 --- /dev/null +++ b/queue-6.6/net-hns3-fixed-vf-get-max-channels-bug.patch @@ -0,0 +1,45 @@ +From bc1cdab2d55c1b5dce526c86af817a17ce805d95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Jul 2025 20:54:22 +0800 +Subject: net: hns3: fixed vf get max channels bug + +From: Jian Shen + +[ Upstream commit b3e75c0bcc53f647311960bc1b0970b9b480ca5a ] + +Currently, the queried maximum of vf channels is the maximum of channels +supported by each TC. However, the actual maximum of channels is +the maximum of channels supported by the device. + +Fixes: 849e46077689 ("net: hns3: add ethtool_ops.get_channels support for VF") +Signed-off-by: Jian Shen +Signed-off-by: Hao Lan +Signed-off-by: Jijie Shao +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250722125423.1270673-4-shaojijie@huawei.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index 1ba0b57c7a72d..68a9aeeed3da0 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -3029,11 +3029,7 @@ static void hclgevf_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) + + static u32 hclgevf_get_max_channels(struct hclgevf_dev *hdev) + { +- struct hnae3_handle *nic = &hdev->nic; +- struct hnae3_knic_private_info *kinfo = &nic->kinfo; +- +- return min_t(u32, hdev->rss_size_max, +- hdev->num_tqps / kinfo->tc_info.num_tc); ++ return min(hdev->rss_size_max, hdev->num_tqps); + } + + /** +-- +2.39.5 + diff --git a/queue-6.6/net-mlx5-e-switch-fix-peer-miss-rules-to-use-peer-es.patch b/queue-6.6/net-mlx5-e-switch-fix-peer-miss-rules-to-use-peer-es.patch new file mode 100644 index 0000000000..104ae7b2e8 --- /dev/null +++ b/queue-6.6/net-mlx5-e-switch-fix-peer-miss-rules-to-use-peer-es.patch @@ -0,0 +1,245 @@ +From fc1536ee446a99bfabdd83f250dba5b96758346d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Jul 2025 15:06:10 +0300 +Subject: net/mlx5: E-Switch, Fix peer miss rules to use peer eswitch + +From: Shahar Shitrit + +[ Upstream commit 5b4c56ad4da0aa00b258ab50b1f5775b7d3108c7 ] + +In the original design, it is assumed local and peer eswitches have the +same number of vfs. However, in new firmware, local and peer eswitches +can have different number of vfs configured by mlxconfig. In such +configuration, it is incorrect to derive the number of vfs from the +local device's eswitch. + +Fix this by updating the peer miss rules add and delete functions to use +the peer device's eswitch and vf count instead of the local device's +information, ensuring correct behavior regardless of vf configuration +differences. + +Fixes: ac004b832128 ("net/mlx5e: E-Switch, Add peer miss rules") +Signed-off-by: Shahar Shitrit +Reviewed-by: Mark Bloch +Signed-off-by: Tariq Toukan +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/1752753970-261832-3-git-send-email-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../mellanox/mlx5/core/eswitch_offloads.c | 108 +++++++++--------- + 1 file changed, 54 insertions(+), 54 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +index 326c72b3df867..86fb8197594f5 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +@@ -1170,19 +1170,19 @@ static void esw_set_peer_miss_rule_source_port(struct mlx5_eswitch *esw, + static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + struct mlx5_core_dev *peer_dev) + { ++ struct mlx5_eswitch *peer_esw = peer_dev->priv.eswitch; + struct mlx5_flow_destination dest = {}; + struct mlx5_flow_act flow_act = {0}; + struct mlx5_flow_handle **flows; +- /* total vports is the same for both e-switches */ +- int nvports = esw->total_vports; + struct mlx5_flow_handle *flow; ++ struct mlx5_vport *peer_vport; + struct mlx5_flow_spec *spec; +- struct mlx5_vport *vport; + int err, pfindex; + unsigned long i; + void *misc; + +- if (!MLX5_VPORT_MANAGER(esw->dev) && !mlx5_core_is_ecpf_esw_manager(esw->dev)) ++ if (!MLX5_VPORT_MANAGER(peer_dev) && ++ !mlx5_core_is_ecpf_esw_manager(peer_dev)) + return 0; + + spec = kvzalloc(sizeof(*spec), GFP_KERNEL); +@@ -1191,7 +1191,7 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + + peer_miss_rules_setup(esw, peer_dev, spec, &dest); + +- flows = kvcalloc(nvports, sizeof(*flows), GFP_KERNEL); ++ flows = kvcalloc(peer_esw->total_vports, sizeof(*flows), GFP_KERNEL); + if (!flows) { + err = -ENOMEM; + goto alloc_flows_err; +@@ -1201,10 +1201,10 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + misc = MLX5_ADDR_OF(fte_match_param, spec->match_value, + misc_parameters); + +- if (mlx5_core_is_ecpf_esw_manager(esw->dev)) { +- vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_PF); +- esw_set_peer_miss_rule_source_port(esw, peer_dev->priv.eswitch, +- spec, MLX5_VPORT_PF); ++ if (mlx5_core_is_ecpf_esw_manager(peer_dev)) { ++ peer_vport = mlx5_eswitch_get_vport(peer_esw, MLX5_VPORT_PF); ++ esw_set_peer_miss_rule_source_port(esw, peer_esw, spec, ++ MLX5_VPORT_PF); + + flow = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw), + spec, &flow_act, &dest, 1); +@@ -1212,11 +1212,11 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + err = PTR_ERR(flow); + goto add_pf_flow_err; + } +- flows[vport->index] = flow; ++ flows[peer_vport->index] = flow; + } + +- if (mlx5_ecpf_vport_exists(esw->dev)) { +- vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_ECPF); ++ if (mlx5_ecpf_vport_exists(peer_dev)) { ++ peer_vport = mlx5_eswitch_get_vport(peer_esw, MLX5_VPORT_ECPF); + MLX5_SET(fte_match_set_misc, misc, source_port, MLX5_VPORT_ECPF); + flow = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw), + spec, &flow_act, &dest, 1); +@@ -1224,13 +1224,14 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + err = PTR_ERR(flow); + goto add_ecpf_flow_err; + } +- flows[vport->index] = flow; ++ flows[peer_vport->index] = flow; + } + +- mlx5_esw_for_each_vf_vport(esw, i, vport, mlx5_core_max_vfs(esw->dev)) { ++ mlx5_esw_for_each_vf_vport(peer_esw, i, peer_vport, ++ mlx5_core_max_vfs(peer_dev)) { + esw_set_peer_miss_rule_source_port(esw, +- peer_dev->priv.eswitch, +- spec, vport->vport); ++ peer_esw, ++ spec, peer_vport->vport); + + flow = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw), + spec, &flow_act, &dest, 1); +@@ -1238,22 +1239,22 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + err = PTR_ERR(flow); + goto add_vf_flow_err; + } +- flows[vport->index] = flow; ++ flows[peer_vport->index] = flow; + } + +- if (mlx5_core_ec_sriov_enabled(esw->dev)) { +- mlx5_esw_for_each_ec_vf_vport(esw, i, vport, mlx5_core_max_ec_vfs(esw->dev)) { +- if (i >= mlx5_core_max_ec_vfs(peer_dev)) +- break; +- esw_set_peer_miss_rule_source_port(esw, peer_dev->priv.eswitch, +- spec, vport->vport); ++ if (mlx5_core_ec_sriov_enabled(peer_dev)) { ++ mlx5_esw_for_each_ec_vf_vport(peer_esw, i, peer_vport, ++ mlx5_core_max_ec_vfs(peer_dev)) { ++ esw_set_peer_miss_rule_source_port(esw, peer_esw, ++ spec, ++ peer_vport->vport); + flow = mlx5_add_flow_rules(esw->fdb_table.offloads.slow_fdb, + spec, &flow_act, &dest, 1); + if (IS_ERR(flow)) { + err = PTR_ERR(flow); + goto add_ec_vf_flow_err; + } +- flows[vport->index] = flow; ++ flows[peer_vport->index] = flow; + } + } + +@@ -1270,25 +1271,27 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + return 0; + + add_ec_vf_flow_err: +- mlx5_esw_for_each_ec_vf_vport(esw, i, vport, mlx5_core_max_ec_vfs(esw->dev)) { +- if (!flows[vport->index]) ++ mlx5_esw_for_each_ec_vf_vport(peer_esw, i, peer_vport, ++ mlx5_core_max_ec_vfs(peer_dev)) { ++ if (!flows[peer_vport->index]) + continue; +- mlx5_del_flow_rules(flows[vport->index]); ++ mlx5_del_flow_rules(flows[peer_vport->index]); + } + add_vf_flow_err: +- mlx5_esw_for_each_vf_vport(esw, i, vport, mlx5_core_max_vfs(esw->dev)) { +- if (!flows[vport->index]) ++ mlx5_esw_for_each_vf_vport(peer_esw, i, peer_vport, ++ mlx5_core_max_vfs(peer_dev)) { ++ if (!flows[peer_vport->index]) + continue; +- mlx5_del_flow_rules(flows[vport->index]); ++ mlx5_del_flow_rules(flows[peer_vport->index]); + } +- if (mlx5_ecpf_vport_exists(esw->dev)) { +- vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_ECPF); +- mlx5_del_flow_rules(flows[vport->index]); ++ if (mlx5_ecpf_vport_exists(peer_dev)) { ++ peer_vport = mlx5_eswitch_get_vport(peer_esw, MLX5_VPORT_ECPF); ++ mlx5_del_flow_rules(flows[peer_vport->index]); + } + add_ecpf_flow_err: +- if (mlx5_core_is_ecpf_esw_manager(esw->dev)) { +- vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_PF); +- mlx5_del_flow_rules(flows[vport->index]); ++ if (mlx5_core_is_ecpf_esw_manager(peer_dev)) { ++ peer_vport = mlx5_eswitch_get_vport(peer_esw, MLX5_VPORT_PF); ++ mlx5_del_flow_rules(flows[peer_vport->index]); + } + add_pf_flow_err: + esw_warn(esw->dev, "FDB: Failed to add peer miss flow rule err %d\n", err); +@@ -1301,37 +1304,34 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + static void esw_del_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + struct mlx5_core_dev *peer_dev) + { ++ struct mlx5_eswitch *peer_esw = peer_dev->priv.eswitch; + u16 peer_index = mlx5_get_dev_index(peer_dev); + struct mlx5_flow_handle **flows; +- struct mlx5_vport *vport; ++ struct mlx5_vport *peer_vport; + unsigned long i; + + flows = esw->fdb_table.offloads.peer_miss_rules[peer_index]; + if (!flows) + return; + +- if (mlx5_core_ec_sriov_enabled(esw->dev)) { +- mlx5_esw_for_each_ec_vf_vport(esw, i, vport, mlx5_core_max_ec_vfs(esw->dev)) { +- /* The flow for a particular vport could be NULL if the other ECPF +- * has fewer or no VFs enabled +- */ +- if (!flows[vport->index]) +- continue; +- mlx5_del_flow_rules(flows[vport->index]); +- } ++ if (mlx5_core_ec_sriov_enabled(peer_dev)) { ++ mlx5_esw_for_each_ec_vf_vport(peer_esw, i, peer_vport, ++ mlx5_core_max_ec_vfs(peer_dev)) ++ mlx5_del_flow_rules(flows[peer_vport->index]); + } + +- mlx5_esw_for_each_vf_vport(esw, i, vport, mlx5_core_max_vfs(esw->dev)) +- mlx5_del_flow_rules(flows[vport->index]); ++ mlx5_esw_for_each_vf_vport(peer_esw, i, peer_vport, ++ mlx5_core_max_vfs(peer_dev)) ++ mlx5_del_flow_rules(flows[peer_vport->index]); + +- if (mlx5_ecpf_vport_exists(esw->dev)) { +- vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_ECPF); +- mlx5_del_flow_rules(flows[vport->index]); ++ if (mlx5_ecpf_vport_exists(peer_dev)) { ++ peer_vport = mlx5_eswitch_get_vport(peer_esw, MLX5_VPORT_ECPF); ++ mlx5_del_flow_rules(flows[peer_vport->index]); + } + +- if (mlx5_core_is_ecpf_esw_manager(esw->dev)) { +- vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_PF); +- mlx5_del_flow_rules(flows[vport->index]); ++ if (mlx5_core_is_ecpf_esw_manager(peer_dev)) { ++ peer_vport = mlx5_eswitch_get_vport(peer_esw, MLX5_VPORT_PF); ++ mlx5_del_flow_rules(flows[peer_vport->index]); + } + + kvfree(flows); +-- +2.39.5 + diff --git a/queue-6.6/net-mlx5-fix-memory-leak-in-cmd_exec.patch b/queue-6.6/net-mlx5-fix-memory-leak-in-cmd_exec.patch new file mode 100644 index 0000000000..ede585e3cc --- /dev/null +++ b/queue-6.6/net-mlx5-fix-memory-leak-in-cmd_exec.patch @@ -0,0 +1,47 @@ +From b290c2def81732eac0fa7561edfff445178e0a2a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Jul 2025 15:06:09 +0300 +Subject: net/mlx5: Fix memory leak in cmd_exec() + +From: Chiara Meiohas + +[ Upstream commit 3afa3ae3db52e3c216d77bd5907a5a86833806cc ] + +If cmd_exec() is called with callback and mlx5_cmd_invoke() returns an +error, resources allocated in cmd_exec() will not be freed. + +Fix the code to release the resources if mlx5_cmd_invoke() returns an +error. + +Fixes: f086470122d5 ("net/mlx5: cmdif, Return value improvements") +Reported-by: Alex Tereshkin +Signed-off-by: Chiara Meiohas +Reviewed-by: Moshe Shemesh +Signed-off-by: Vlad Dumitrescu +Signed-off-by: Tariq Toukan +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/1752753970-261832-2-git-send-email-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +index 3e6bd27f6315d..5a2126679415c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +@@ -1916,8 +1916,8 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out, + + err = mlx5_cmd_invoke(dev, inb, outb, out, out_size, callback, context, + pages_queue, token, force_polling); +- if (callback) +- return err; ++ if (callback && !err) ++ return 0; + + if (err > 0) /* Failed in FW, command didn't execute */ + err = deliv_status_to_err(err); +-- +2.39.5 + diff --git a/queue-6.6/net-sched-sch_qfq-avoid-triggering-might_sleep-in-at.patch b/queue-6.6/net-sched-sch_qfq-avoid-triggering-might_sleep-in-at.patch new file mode 100644 index 0000000000..d347a7c204 --- /dev/null +++ b/queue-6.6/net-sched-sch_qfq-avoid-triggering-might_sleep-in-at.patch @@ -0,0 +1,74 @@ +From 4b8031db6ed9566625a665b13316486fd17af14d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Jul 2025 16:01:28 -0700 +Subject: net/sched: sch_qfq: Avoid triggering might_sleep in atomic context in + qfq_delete_class + +From: Xiang Mei + +[ Upstream commit cf074eca0065bc5142e6004ae236bb35a2687fdf ] + +might_sleep could be trigger in the atomic context in qfq_delete_class. + +qfq_destroy_class was moved into atomic context locked +by sch_tree_lock to avoid a race condition bug on +qfq_aggregate. However, might_sleep could be triggered by +qfq_destroy_class, which introduced sleeping in atomic context (path: +qfq_destroy_class->qdisc_put->__qdisc_destroy->lockdep_unregister_key +->might_sleep). + +Considering the race is on the qfq_aggregate objects, keeping +qfq_rm_from_agg in the lock but moving the left part out can solve +this issue. + +Fixes: 5e28d5a3f774 ("net/sched: sch_qfq: Fix race condition on qfq_aggregate") +Reported-by: Dan Carpenter +Signed-off-by: Xiang Mei +Link: https://patch.msgid.link/4a04e0cc-a64b-44e7-9213-2880ed641d77@sabinyo.mountain +Reviewed-by: Cong Wang +Reviewed-by: Dan Carpenter +Link: https://patch.msgid.link/20250717230128.159766-1-xmei5@asu.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/sched/sch_qfq.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c +index a2b321fec13c1..c3f9a6375b4ea 100644 +--- a/net/sched/sch_qfq.c ++++ b/net/sched/sch_qfq.c +@@ -539,9 +539,6 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, + + static void qfq_destroy_class(struct Qdisc *sch, struct qfq_class *cl) + { +- struct qfq_sched *q = qdisc_priv(sch); +- +- qfq_rm_from_agg(q, cl); + gen_kill_estimator(&cl->rate_est); + qdisc_put(cl->qdisc); + kfree(cl); +@@ -562,10 +559,11 @@ static int qfq_delete_class(struct Qdisc *sch, unsigned long arg, + + qdisc_purge_queue(cl->qdisc); + qdisc_class_hash_remove(&q->clhash, &cl->common); +- qfq_destroy_class(sch, cl); ++ qfq_rm_from_agg(q, cl); + + sch_tree_unlock(sch); + ++ qfq_destroy_class(sch, cl); + return 0; + } + +@@ -1506,6 +1504,7 @@ static void qfq_destroy_qdisc(struct Qdisc *sch) + for (i = 0; i < q->clhash.hashsize; i++) { + hlist_for_each_entry_safe(cl, next, &q->clhash.hash[i], + common.hnode) { ++ qfq_rm_from_agg(q, cl); + qfq_destroy_class(sch, cl); + } + } +-- +2.39.5 + diff --git a/queue-6.6/s390-ism-fix-concurrency-management-in-ism_cmd.patch b/queue-6.6/s390-ism-fix-concurrency-management-in-ism_cmd.patch new file mode 100644 index 0000000000..169198b4f1 --- /dev/null +++ b/queue-6.6/s390-ism-fix-concurrency-management-in-ism_cmd.patch @@ -0,0 +1,100 @@ +From 10dc672cdcb6bffb1418ed6c03815841639384c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Jul 2025 18:18:17 +0200 +Subject: s390/ism: fix concurrency management in ism_cmd() + +From: Halil Pasic + +[ Upstream commit 897e8601b9cff1d054cdd53047f568b0e1995726 ] + +The s390x ISM device data sheet clearly states that only one +request-response sequence is allowable per ISM function at any point in +time. Unfortunately as of today the s390/ism driver in Linux does not +honor that requirement. This patch aims to rectify that. + +This problem was discovered based on Aliaksei's bug report which states +that for certain workloads the ISM functions end up entering error state +(with PEC 2 as seen from the logs) after a while and as a consequence +connections handled by the respective function break, and for future +connection requests the ISM device is not considered -- given it is in a +dysfunctional state. During further debugging PEC 3A was observed as +well. + +A kernel message like +[ 1211.244319] zpci: 061a:00:00.0: Event 0x2 reports an error for PCI function 0x61a +is a reliable indicator of the stated function entering error state +with PEC 2. Let me also point out that a kernel message like +[ 1211.244325] zpci: 061a:00:00.0: The ism driver bound to the device does not support error recovery +is a reliable indicator that the ISM function won't be auto-recovered +because the ISM driver currently lacks support for it. + +On a technical level, without this synchronization, commands (inputs to +the FW) may be partially or fully overwritten (corrupted) by another CPU +trying to issue commands on the same function. There is hard evidence that +this can lead to DMB token values being used as DMB IOVAs, leading to +PEC 2 PCI events indicating invalid DMA. But this is only one of the +failure modes imaginable. In theory even completely losing one command +and executing another one twice and then trying to interpret the outputs +as if the command we intended to execute was actually executed and not +the other one is also possible. Frankly, I don't feel confident about +providing an exhaustive list of possible consequences. + +Fixes: 684b89bc39ce ("s390/ism: add device driver for internal shared memory") +Reported-by: Aliaksei Makarau +Tested-by: Mahanta Jambigi +Tested-by: Aliaksei Makarau +Signed-off-by: Halil Pasic +Reviewed-by: Alexandra Winter +Signed-off-by: Alexandra Winter +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250722161817.1298473-1-wintera@linux.ibm.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/s390/net/ism_drv.c | 3 +++ + include/linux/ism.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c +index af0d90beba638..76ba36c83e522 100644 +--- a/drivers/s390/net/ism_drv.c ++++ b/drivers/s390/net/ism_drv.c +@@ -130,6 +130,7 @@ static int ism_cmd(struct ism_dev *ism, void *cmd) + struct ism_req_hdr *req = cmd; + struct ism_resp_hdr *resp = cmd; + ++ spin_lock(&ism->cmd_lock); + __ism_write_cmd(ism, req + 1, sizeof(*req), req->len - sizeof(*req)); + __ism_write_cmd(ism, req, 0, sizeof(*req)); + +@@ -143,6 +144,7 @@ static int ism_cmd(struct ism_dev *ism, void *cmd) + } + __ism_read_cmd(ism, resp + 1, sizeof(*resp), resp->len - sizeof(*resp)); + out: ++ spin_unlock(&ism->cmd_lock); + return resp->ret; + } + +@@ -630,6 +632,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) + return -ENOMEM; + + spin_lock_init(&ism->lock); ++ spin_lock_init(&ism->cmd_lock); + dev_set_drvdata(&pdev->dev, ism); + ism->pdev = pdev; + ism->dev.parent = &pdev->dev; +diff --git a/include/linux/ism.h b/include/linux/ism.h +index 9a4c204df3da1..04e2fc1973ce4 100644 +--- a/include/linux/ism.h ++++ b/include/linux/ism.h +@@ -28,6 +28,7 @@ struct ism_dmb { + + struct ism_dev { + spinlock_t lock; /* protects the ism device */ ++ spinlock_t cmd_lock; /* serializes cmds */ + struct list_head list; + struct pci_dev *pdev; + +-- +2.39.5 + diff --git a/queue-6.6/series b/queue-6.6/series index 191394b4c8..5d500b16bf 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -8,3 +8,20 @@ regmap-fix-potential-memory-leak-of-regmap_bus.patch x86-hyperv-fix-usage-of-cpu_online_mask-to-get-valid.patch platform-x86-fix-initialization-order-for-firmware_a.patch staging-vchiq_arm-make-vchiq_shutdown-never-fail.patch +xfrm-interface-fix-use-after-free-after-changing-col.patch +net-mlx5-fix-memory-leak-in-cmd_exec.patch +net-mlx5-e-switch-fix-peer-miss-rules-to-use-peer-es.patch +i40e-add-rx_missed_errors-for-buffer-exhaustion.patch +i40e-report-vf-tx_dropped-with-tx_errors-instead-of-.patch +i40e-when-removing-vf-mac-filters-only-check-pf-set-.patch +net-appletalk-fix-use-after-free-in-aarp-proxy-probe.patch +net-sched-sch_qfq-avoid-triggering-might_sleep-in-at.patch +can-dev-can_restart-reverse-logic-to-remove-need-for.patch +can-dev-can_restart-move-debug-message-and-stats-aft.patch +can-netlink-can_changelink-fix-null-pointer-deref-of.patch +drm-bridge-ti-sn65dsi86-remove-extra-semicolon-in-ti.patch +s390-ism-fix-concurrency-management-in-ism_cmd.patch +net-hns3-fix-concurrent-setting-vlan-filter-issue.patch +net-hns3-disable-interrupt-when-ptp-init-failed.patch +net-hns3-fixed-vf-get-max-channels-bug.patch +net-hns3-default-enable-tx-bounce-buffer-when-smmu-e.patch diff --git a/queue-6.6/xfrm-interface-fix-use-after-free-after-changing-col.patch b/queue-6.6/xfrm-interface-fix-use-after-free-after-changing-col.patch new file mode 100644 index 0000000000..2af0628e83 --- /dev/null +++ b/queue-6.6/xfrm-interface-fix-use-after-free-after-changing-col.patch @@ -0,0 +1,97 @@ +From ff6833835931808ab571076bf1b26cb5630a3f08 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Jul 2025 10:02:58 -0700 +Subject: xfrm: interface: fix use-after-free after changing collect_md xfrm + interface + +From: Eyal Birger + +[ Upstream commit a90b2a1aaacbcf0f91d7e4868ad6c51c5dee814b ] + +collect_md property on xfrm interfaces can only be set on device creation, +thus xfrmi_changelink() should fail when called on such interfaces. + +The check to enforce this was done only in the case where the xi was +returned from xfrmi_locate() which doesn't look for the collect_md +interface, and thus the validation was never reached. + +Calling changelink would thus errornously place the special interface xi +in the xfrmi_net->xfrmi hash, but since it also exists in the +xfrmi_net->collect_md_xfrmi pointer it would lead to a double free when +the net namespace was taken down [1]. + +Change the check to use the xi from netdev_priv which is available earlier +in the function to prevent changes in xfrm collect_md interfaces. + +[1] resulting oops: +[ 8.516540] kernel BUG at net/core/dev.c:12029! +[ 8.516552] Oops: invalid opcode: 0000 [#1] SMP NOPTI +[ 8.516559] CPU: 0 UID: 0 PID: 12 Comm: kworker/u80:0 Not tainted 6.15.0-virtme #5 PREEMPT(voluntary) +[ 8.516565] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 +[ 8.516569] Workqueue: netns cleanup_net +[ 8.516579] RIP: 0010:unregister_netdevice_many_notify+0x101/0xab0 +[ 8.516590] Code: 90 0f 0b 90 48 8b b0 78 01 00 00 48 8b 90 80 01 00 00 48 89 56 08 48 89 32 4c 89 80 78 01 00 00 48 89 b8 80 01 00 00 eb ac 90 <0f> 0b 48 8b 45 00 4c 8d a0 88 fe ff ff 48 39 c5 74 5c 41 80 bc 24 +[ 8.516593] RSP: 0018:ffffa93b8006bd30 EFLAGS: 00010206 +[ 8.516598] RAX: ffff98fe4226e000 RBX: ffffa93b8006bd58 RCX: ffffa93b8006bc60 +[ 8.516601] RDX: 0000000000000004 RSI: 0000000000000000 RDI: dead000000000122 +[ 8.516603] RBP: ffffa93b8006bdd8 R08: dead000000000100 R09: ffff98fe4133c100 +[ 8.516605] R10: 0000000000000000 R11: 00000000000003d2 R12: ffffa93b8006be00 +[ 8.516608] R13: ffffffff96c1a510 R14: ffffffff96c1a510 R15: ffffa93b8006be00 +[ 8.516615] FS: 0000000000000000(0000) GS:ffff98fee73b7000(0000) knlGS:0000000000000000 +[ 8.516619] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 8.516622] CR2: 00007fcd2abd0700 CR3: 000000003aa40000 CR4: 0000000000752ef0 +[ 8.516625] PKRU: 55555554 +[ 8.516627] Call Trace: +[ 8.516632] +[ 8.516635] ? rtnl_is_locked+0x15/0x20 +[ 8.516641] ? unregister_netdevice_queue+0x29/0xf0 +[ 8.516650] ops_undo_list+0x1f2/0x220 +[ 8.516659] cleanup_net+0x1ad/0x2e0 +[ 8.516664] process_one_work+0x160/0x380 +[ 8.516673] worker_thread+0x2aa/0x3c0 +[ 8.516679] ? __pfx_worker_thread+0x10/0x10 +[ 8.516686] kthread+0xfb/0x200 +[ 8.516690] ? __pfx_kthread+0x10/0x10 +[ 8.516693] ? __pfx_kthread+0x10/0x10 +[ 8.516697] ret_from_fork+0x82/0xf0 +[ 8.516705] ? __pfx_kthread+0x10/0x10 +[ 8.516709] ret_from_fork_asm+0x1a/0x30 +[ 8.516718] + +Fixes: abc340b38ba2 ("xfrm: interface: support collect metadata mode") +Reported-by: Lonial Con +Signed-off-by: Eyal Birger +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + net/xfrm/xfrm_interface_core.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/net/xfrm/xfrm_interface_core.c b/net/xfrm/xfrm_interface_core.c +index e21cc71095bb2..ca6db1e960ce6 100644 +--- a/net/xfrm/xfrm_interface_core.c ++++ b/net/xfrm/xfrm_interface_core.c +@@ -880,7 +880,7 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], + return -EINVAL; + } + +- if (p.collect_md) { ++ if (p.collect_md || xi->p.collect_md) { + NL_SET_ERR_MSG(extack, "collect_md can't be changed"); + return -EINVAL; + } +@@ -891,11 +891,6 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], + } else { + if (xi->dev != dev) + return -EEXIST; +- if (xi->p.collect_md) { +- NL_SET_ERR_MSG(extack, +- "device can't be changed to collect_md"); +- return -EINVAL; +- } + } + + return xfrmi_update(xi, &p); +-- +2.39.5 + -- 2.47.2