--- /dev/null
+From a5372ceb0f0990d3e51f4f6d7d05a18d854c9a80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <mkl@pengutronix.de>
+
+[ 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 <mailhol.vincent@wanadoo.fr>
+[mkl: mention stats in subject and description, too]
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Stable-dep-of: c1f3f9797c1f ("can: netlink: can_changelink(): fix NULL pointer deref of struct can_priv::do_set_mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 4538e7c4622dcdaee5721dbb395774a0279dd646 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <mkl@pengutronix.de>
+
+[ 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 <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Stable-dep-of: c1f3f9797c1f ("can: netlink: can_changelink(): fix NULL pointer deref of struct can_priv::do_set_mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 39fcb32f54fe5fe526d41597b7493fbe5dc9e73a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <mkl@pengutronix.de>
+
+[ 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 <andrey.lalaev@gmail.com>
+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 <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From f764d72f0978de55de4c15c0093100326e3e5c7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <dianders@chromium.org>
+
+[ 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 <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202506301704.0SBj6ply-lkp@intel.com/
+Reviewed-by: Devarsh Thakkar <devarsht@ti.com>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://lore.kernel.org/r/20250714130631.1.I1cfae3222e344a3b3c770d079ee6b6f7f3b5d636@changeid
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 4a355a46ff46f58db9c549da5bb6694541693d01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Sep 2023 15:27:57 +0800
+Subject: i40e: Add rx_missed_errors for buffer exhaustion
+
+From: Yajun Deng <yajun.deng@linux.dev>
+
+[ 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 <yajun.deng@linux.dev>
+Tested-by: Arpana Arland <arpanax.arland@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: 50b2af451597 ("i40e: report VF tx_dropped with tx_errors instead of tx_discards")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 228f9fbff4b3747e218bf4699f1224c2259db6cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <dechen@redhat.com>
+
+[ 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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 <dechen@redhat.com>
+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 <horms@kernel.org>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 4c9985f5138da31c2a8e1a27b0681499a909aa1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Jun 2025 09:29:18 +1000
+Subject: i40e: When removing VF MAC filters, only check PF-set MAC
+
+From: Jamie Bainbridge <jamie.bainbridge@gmail.com>
+
+[ 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 <jamie.bainbridge@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 1e6185d0aac0b96f236f803b6f547c021d580de2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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) <hxzene@gmail.com>
+
+[ 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:
+ <TASK>
+ __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
+ </TASK>
+
+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) <hxzene@gmail.com>
+Link: https://patch.msgid.link/20250717012843.880423-1-hxzene@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 <linux/seq_file.h>
+ #include <linux/export.h>
+ #include <linux/etherdevice.h>
++#include <linux/refcount.h>
+
+ 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
+
--- /dev/null
+From 76a1a7ee1157ab3b77c225e2fdcac7d576a96bfd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jul 2025 20:54:23 +0800
+Subject: net: hns3: default enable tx bounce buffer when smmu enabled
+
+From: Jijie Shao <shaojijie@huawei.com>
+
+[ 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 <wangpeiyang1@huawei.com>
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 49ade8630f36 ("net: hns3: default enable tx bounce buffer when smmu enabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../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 <linux/irq.h>
+ #include <linux/ip.h>
+ #include <linux/ipv6.h>
++#include <linux/iommu.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/skbuff.h>
+@@ -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
+
--- /dev/null
+From 3039d03b05587ba59fc6ad1e098c1f19e17d4a71 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jul 2025 20:54:21 +0800
+Subject: net: hns3: disable interrupt when ptp init failed
+
+From: Yonglong Liu <liuyonglong@huawei.com>
+
+[ 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 <liuyonglong@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250722125423.1270673-3-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 6cff320b552abea2d9d79e3e2d04a155f3d1d4be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jul 2025 20:54:20 +0800
+Subject: net: hns3: fix concurrent setting vlan filter issue
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ 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 <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250722125423.1270673-2-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../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
+
--- /dev/null
+From bc1cdab2d55c1b5dce526c86af817a17ce805d95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jul 2025 20:54:22 +0800
+Subject: net: hns3: fixed vf get max channels bug
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ 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 <shenjian15@huawei.com>
+Signed-off-by: Hao Lan <lanhao@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250722125423.1270673-4-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From fc1536ee446a99bfabdd83f250dba5b96758346d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <shshitrit@nvidia.com>
+
+[ 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 <shshitrit@nvidia.com>
+Reviewed-by: Mark Bloch <mbloch@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/1752753970-261832-3-git-send-email-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../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
+
--- /dev/null
+From b290c2def81732eac0fa7561edfff445178e0a2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jul 2025 15:06:09 +0300
+Subject: net/mlx5: Fix memory leak in cmd_exec()
+
+From: Chiara Meiohas <cmeiohas@nvidia.com>
+
+[ 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 <atereshkin@nvidia.com>
+Signed-off-by: Chiara Meiohas <cmeiohas@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Vlad Dumitrescu <vdumitrescu@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/1752753970-261832-2-git-send-email-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 4b8031db6ed9566625a665b13316486fd17af14d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <xmei5@asu.edu>
+
+[ 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 <dan.carpenter@linaro.org>
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Link: https://patch.msgid.link/4a04e0cc-a64b-44e7-9213-2880ed641d77@sabinyo.mountain
+Reviewed-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/20250717230128.159766-1-xmei5@asu.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
--- /dev/null
+From 10dc672cdcb6bffb1418ed6c03815841639384c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jul 2025 18:18:17 +0200
+Subject: s390/ism: fix concurrency management in ism_cmd()
+
+From: Halil Pasic <pasic@linux.ibm.com>
+
+[ 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 <Aliaksei.Makarau@ibm.com>
+Tested-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
+Tested-by: Aliaksei Makarau <Aliaksei.Makarau@ibm.com>
+Signed-off-by: Halil Pasic <pasic@linux.ibm.com>
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250722161817.1298473-1-wintera@linux.ibm.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
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
--- /dev/null
+From ff6833835931808ab571076bf1b26cb5630a3f08 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <eyal.birger@gmail.com>
+
+[ 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] <TASK>
+[ 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] </TASK>
+
+Fixes: abc340b38ba2 ("xfrm: interface: support collect metadata mode")
+Reported-by: Lonial Con <kongln9170@gmail.com>
+Signed-off-by: Eyal Birger <eyal.birger@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+