--- /dev/null
+From 0efc01b16af650ac136764817f290620e798517e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 13:12:54 -0500
+Subject: Bluetooth: hci_event: Fix enabling passive scanning
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 0bdd88971519cfa8a76d1a4dde182e74cfbd5d5c ]
+
+Passive scanning shall only be enabled when disconnecting LE links,
+otherwise it may start result in triggering scanning when e.g. an ISO
+link disconnects:
+
+> HCI Event: LE Meta Event (0x3e) plen 29
+ LE Connected Isochronous Stream Established (0x19)
+ Status: Success (0x00)
+ Connection Handle: 257
+ CIG Synchronization Delay: 0 us (0x000000)
+ CIS Synchronization Delay: 0 us (0x000000)
+ Central to Peripheral Latency: 10000 us (0x002710)
+ Peripheral to Central Latency: 10000 us (0x002710)
+ Central to Peripheral PHY: LE 2M (0x02)
+ Peripheral to Central PHY: LE 2M (0x02)
+ Number of Subevents: 1
+ Central to Peripheral Burst Number: 1
+ Peripheral to Central Burst Number: 1
+ Central to Peripheral Flush Timeout: 2
+ Peripheral to Central Flush Timeout: 2
+ Central to Peripheral MTU: 320
+ Peripheral to Central MTU: 160
+ ISO Interval: 10.00 msec (0x0008)
+...
+> HCI Event: Disconnect Complete (0x05) plen 4
+ Status: Success (0x00)
+ Handle: 257
+ Reason: Remote User Terminated Connection (0x13)
+< HCI Command: LE Set Extended Scan Enable (0x08|0x0042) plen 6
+ Extended scan: Enabled (0x01)
+ Filter duplicates: Enabled (0x01)
+ Duration: 0 msec (0x0000)
+ Period: 0.00 sec (0x0000)
+
+Fixes: 9fcb18ef3acb ("Bluetooth: Introduce LE auto connect options")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 37 ++++++++++++++++++++++---------------
+ 1 file changed, 22 insertions(+), 15 deletions(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 01e51e1dc9b33..1e689d8c00a50 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3394,23 +3394,30 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, void *data,
+ hci_update_scan(hdev);
+ }
+
+- params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
+- if (params) {
+- switch (params->auto_connect) {
+- case HCI_AUTO_CONN_LINK_LOSS:
+- if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
++ /* Re-enable passive scanning if disconnected device is marked
++ * as auto-connectable.
++ */
++ if (conn->type == LE_LINK) {
++ params = hci_conn_params_lookup(hdev, &conn->dst,
++ conn->dst_type);
++ if (params) {
++ switch (params->auto_connect) {
++ case HCI_AUTO_CONN_LINK_LOSS:
++ if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
++ break;
++ fallthrough;
++
++ case HCI_AUTO_CONN_DIRECT:
++ case HCI_AUTO_CONN_ALWAYS:
++ hci_pend_le_list_del_init(params);
++ hci_pend_le_list_add(params,
++ &hdev->pend_le_conns);
++ hci_update_passive_scan(hdev);
+ break;
+- fallthrough;
+
+- case HCI_AUTO_CONN_DIRECT:
+- case HCI_AUTO_CONN_ALWAYS:
+- hci_pend_le_list_del_init(params);
+- hci_pend_le_list_add(params, &hdev->pend_le_conns);
+- hci_update_passive_scan(hdev);
+- break;
+-
+- default:
+- break;
++ default:
++ break;
++ }
+ }
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 09cb99fa967e64680ffd704345a0914bcfa18ddf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 02:39:22 +0000
+Subject: bonding: fix incorrect MAC address setting to receive NS messages
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit 0c5e145a350de3b38cd5ae77a401b12c46fb7c1d ]
+
+When validation on the backup slave is enabled, we need to validate the
+Neighbor Solicitation (NS) messages received on the backup slave. To
+receive these messages, the correct destination MAC address must be added
+to the slave. However, the target in bonding is a unicast address, which
+we cannot use directly. Instead, we should first convert it to a
+Solicited-Node Multicast Address and then derive the corresponding MAC
+address.
+
+Fix the incorrect MAC address setting on both slave_set_ns_maddr() and
+slave_set_ns_maddrs(). Since the two function names are similar. Add
+some description for the functions. Also only use one mac_addr variable
+in slave_set_ns_maddr() to save some code and logic.
+
+Fixes: 8eb36164d1a6 ("bonding: add ns target multicast address to slave device")
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250306023923.38777-2-liuhangbin@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_options.c | 55 +++++++++++++++++++++++++-----
+ 1 file changed, 47 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
+index 8c326e41b8d63..6d003c0ef6698 100644
+--- a/drivers/net/bonding/bond_options.c
++++ b/drivers/net/bonding/bond_options.c
+@@ -1226,10 +1226,28 @@ static bool slave_can_set_ns_maddr(const struct bonding *bond, struct slave *sla
+ slave->dev->flags & IFF_MULTICAST;
+ }
+
++/**
++ * slave_set_ns_maddrs - add/del all NS mac addresses for slave
++ * @bond: bond device
++ * @slave: slave device
++ * @add: add or remove all the NS mac addresses
++ *
++ * This function tries to add or delete all the NS mac addresses on the slave
++ *
++ * Note, the IPv6 NS target address is the unicast address in Neighbor
++ * Solicitation (NS) message. The dest address of NS message should be
++ * solicited-node multicast address of the target. The dest mac of NS message
++ * is converted from the solicited-node multicast address.
++ *
++ * This function is called when
++ * * arp_validate changes
++ * * enslaving, releasing new slaves
++ */
+ static void slave_set_ns_maddrs(struct bonding *bond, struct slave *slave, bool add)
+ {
+ struct in6_addr *targets = bond->params.ns_targets;
+ char slot_maddr[MAX_ADDR_LEN];
++ struct in6_addr mcaddr;
+ int i;
+
+ if (!slave_can_set_ns_maddr(bond, slave))
+@@ -1239,7 +1257,8 @@ static void slave_set_ns_maddrs(struct bonding *bond, struct slave *slave, bool
+ if (ipv6_addr_any(&targets[i]))
+ break;
+
+- if (!ndisc_mc_map(&targets[i], slot_maddr, slave->dev, 0)) {
++ addrconf_addr_solict_mult(&targets[i], &mcaddr);
++ if (!ndisc_mc_map(&mcaddr, slot_maddr, slave->dev, 0)) {
+ if (add)
+ dev_mc_add(slave->dev, slot_maddr);
+ else
+@@ -1262,23 +1281,43 @@ void bond_slave_ns_maddrs_del(struct bonding *bond, struct slave *slave)
+ slave_set_ns_maddrs(bond, slave, false);
+ }
+
++/**
++ * slave_set_ns_maddr - set new NS mac address for slave
++ * @bond: bond device
++ * @slave: slave device
++ * @target: the new IPv6 target
++ * @slot: the old IPv6 target in the slot
++ *
++ * This function tries to replace the old mac address to new one on the slave.
++ *
++ * Note, the target/slot IPv6 address is the unicast address in Neighbor
++ * Solicitation (NS) message. The dest address of NS message should be
++ * solicited-node multicast address of the target. The dest mac of NS message
++ * is converted from the solicited-node multicast address.
++ *
++ * This function is called when
++ * * An IPv6 NS target is added or removed.
++ */
+ static void slave_set_ns_maddr(struct bonding *bond, struct slave *slave,
+ struct in6_addr *target, struct in6_addr *slot)
+ {
+- char target_maddr[MAX_ADDR_LEN], slot_maddr[MAX_ADDR_LEN];
++ char mac_addr[MAX_ADDR_LEN];
++ struct in6_addr mcast_addr;
+
+ if (!bond->params.arp_validate || !slave_can_set_ns_maddr(bond, slave))
+ return;
+
+- /* remove the previous maddr from slave */
++ /* remove the previous mac addr from slave */
++ addrconf_addr_solict_mult(slot, &mcast_addr);
+ if (!ipv6_addr_any(slot) &&
+- !ndisc_mc_map(slot, slot_maddr, slave->dev, 0))
+- dev_mc_del(slave->dev, slot_maddr);
++ !ndisc_mc_map(&mcast_addr, mac_addr, slave->dev, 0))
++ dev_mc_del(slave->dev, mac_addr);
+
+- /* add new maddr on slave if target is set */
++ /* add new mac addr on slave if target is set */
++ addrconf_addr_solict_mult(target, &mcast_addr);
+ if (!ipv6_addr_any(target) &&
+- !ndisc_mc_map(target, target_maddr, slave->dev, 0))
+- dev_mc_add(slave->dev, target_maddr);
++ !ndisc_mc_map(&mcast_addr, mac_addr, slave->dev, 0))
++ dev_mc_add(slave->dev, mac_addr);
+ }
+
+ static void _bond_options_ns_ip6_target_set(struct bonding *bond, int slot,
+--
+2.39.5
+
--- /dev/null
+From b61e44b8079f95ebef22c30a4490e417b8cbdb9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Mar 2025 20:52:08 -0700
+Subject: Drivers: hv: vmbus: Don't release fb_mmio resource in
+ vmbus_free_mmio()
+
+From: Michael Kelley <mhklinux@outlook.com>
+
+[ Upstream commit 73fe9073c0cc28056cb9de0c8a516dac070f1d1f ]
+
+The VMBus driver manages the MMIO space it owns via the hyperv_mmio
+resource tree. Because the synthetic video framebuffer portion of the
+MMIO space is initially setup by the Hyper-V host for each guest, the
+VMBus driver does an early reserve of that portion of MMIO space in the
+hyperv_mmio resource tree. It saves a pointer to that resource in
+fb_mmio. When a VMBus driver requests MMIO space and passes "true"
+for the "fb_overlap_ok" argument, the reserved framebuffer space is
+used if possible. In that case it's not necessary to do another request
+against the "shadow" hyperv_mmio resource tree because that resource
+was already requested in the early reserve steps.
+
+However, the vmbus_free_mmio() function currently does no special
+handling for the fb_mmio resource. When a framebuffer device is
+removed, or the driver is unbound, the current code for
+vmbus_free_mmio() releases the reserved resource, leaving fb_mmio
+pointing to memory that has been freed. If the same or another
+driver is subsequently bound to the device, vmbus_allocate_mmio()
+checks against fb_mmio, and potentially gets garbage. Furthermore
+a second unbind operation produces this "nonexistent resource" error
+because of the unbalanced behavior between vmbus_allocate_mmio() and
+vmbus_free_mmio():
+
+[ 55.499643] resource: Trying to free nonexistent
+ resource <0x00000000f0000000-0x00000000f07fffff>
+
+Fix this by adding logic to vmbus_free_mmio() to recognize when
+MMIO space in the fb_mmio reserved area would be released, and don't
+release it. This filtering ensures the fb_mmio resource always exists,
+and makes vmbus_free_mmio() more parallel with vmbus_allocate_mmio().
+
+Fixes: be000f93e5d7 ("drivers:hv: Track allocations of children of hv_vmbus in private resource tree")
+Signed-off-by: Michael Kelley <mhklinux@outlook.com>
+Tested-by: Saurabh Sengar <ssengar@linux.microsoft.com>
+Reviewed-by: Saurabh Sengar <ssengar@linux.microsoft.com>
+Link: https://lore.kernel.org/r/20250310035208.275764-1-mhklinux@outlook.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Message-ID: <20250310035208.275764-1-mhklinux@outlook.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/vmbus_drv.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index 756aebf324735..c54d759b07384 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -2242,12 +2242,25 @@ void vmbus_free_mmio(resource_size_t start, resource_size_t size)
+ struct resource *iter;
+
+ mutex_lock(&hyperv_mmio_lock);
++
++ /*
++ * If all bytes of the MMIO range to be released are within the
++ * special case fb_mmio shadow region, skip releasing the shadow
++ * region since no corresponding __request_region() was done
++ * in vmbus_allocate_mmio().
++ */
++ if (fb_mmio && start >= fb_mmio->start &&
++ (start + size - 1 <= fb_mmio->end))
++ goto skip_shadow_release;
++
+ for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+ if ((iter->start >= start + size) || (iter->end <= start))
+ continue;
+
+ __release_region(iter, start, size);
+ }
++
++skip_shadow_release:
+ release_mem_region(start, size);
+ mutex_unlock(&hyperv_mmio_lock);
+
+--
+2.39.5
+
--- /dev/null
+From fefb60cc8450091a0ec935b2e04c142894d2bac7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 11:34:41 -0800
+Subject: drm/hyperv: Fix address space leak when Hyper-V DRM device is removed
+
+From: Michael Kelley <mhklinux@outlook.com>
+
+[ Upstream commit aed709355fd05ef747e1af24a1d5d78cd7feb81e ]
+
+When a Hyper-V DRM device is probed, the driver allocates MMIO space for
+the vram, and maps it cacheable. If the device removed, or in the error
+path for device probing, the MMIO space is released but no unmap is done.
+Consequently the kernel address space for the mapping is leaked.
+
+Fix this by adding iounmap() calls in the device removal path, and in the
+error path during device probing.
+
+Fixes: f1f63cbb705d ("drm/hyperv: Fix an error handling path in hyperv_vmbus_probe()")
+Fixes: a0ab5abced55 ("drm/hyperv : Removing the restruction of VRAM allocation with PCI bar size")
+Signed-off-by: Michael Kelley <mhklinux@outlook.com>
+Reviewed-by: Saurabh Sengar <ssengar@linux.microsoft.com>
+Tested-by: Saurabh Sengar <ssengar@linux.microsoft.com>
+Link: https://lore.kernel.org/r/20250210193441.2414-1-mhklinux@outlook.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Message-ID: <20250210193441.2414-1-mhklinux@outlook.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/hyperv/hyperv_drm_drv.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
+index 8026118c6e033..8a7933f5c6ebe 100644
+--- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
++++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
+@@ -157,6 +157,7 @@ static int hyperv_vmbus_probe(struct hv_device *hdev,
+ return 0;
+
+ err_free_mmio:
++ iounmap(hv->vram);
+ vmbus_free_mmio(hv->mem->start, hv->fb_size);
+ err_vmbus_close:
+ vmbus_close(hdev->channel);
+@@ -175,6 +176,7 @@ static void hyperv_vmbus_remove(struct hv_device *hdev)
+ vmbus_close(hdev->channel);
+ hv_set_drvdata(hdev, NULL);
+
++ iounmap(hv->vram);
+ vmbus_free_mmio(hv->mem->start, hv->fb_size);
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 709d4e26841afc15a57b3416696a472a0266983c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 16:30:03 +0530
+Subject: dt-bindings: display: rockchip-vop: Document rv1126 vop
+
+From: Jagan Teki <jagan@edgeble.ai>
+
+[ Upstream commit aadbaac84fc95efa800e4c73ae86fefb8c86288b ]
+
+The VOP on Rockchip's RV1126 SoC is different from other SoC's
+VOP implementations, so add a separate compatible for it.
+
+Signed-off-by: Jagan Teki <jagan@edgeble.ai>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230731110012.2913742-6-jagan@edgeble.ai
+Stable-dep-of: ea2f45ab0e53 ("fbdev: hyperv_fb: Allow graceful removal of framebuffer")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../devicetree/bindings/display/rockchip/rockchip-vop.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml
+index df61cb5f5c54b..b339b7e708c65 100644
+--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml
++++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml
+@@ -31,6 +31,7 @@ properties:
+ - rockchip,rk3368-vop
+ - rockchip,rk3399-vop-big
+ - rockchip,rk3399-vop-lit
++ - rockchip,rv1126-vop
+
+ reg:
+ minItems: 1
+--
+2.39.5
+
--- /dev/null
+From d20d8661bb6eeca363b9829f6daa37cdf59d823d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Mar 2025 13:42:15 +0000
+Subject: eth: bnxt: do not update checksum in bnxt_xdp_build_skb()
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit c03e7d05aa0e2f7e9a9ce5ad8a12471a53f941dc ]
+
+The bnxt_rx_pkt() updates ip_summed value at the end if checksum offload
+is enabled.
+When the XDP-MB program is attached and it returns XDP_PASS, the
+bnxt_xdp_build_skb() is called to update skb_shared_info.
+The main purpose of bnxt_xdp_build_skb() is to update skb_shared_info,
+but it updates ip_summed value too if checksum offload is enabled.
+This is actually duplicate work.
+
+When the bnxt_rx_pkt() updates ip_summed value, it checks if ip_summed
+is CHECKSUM_NONE or not.
+It means that ip_summed should be CHECKSUM_NONE at this moment.
+But ip_summed may already be updated to CHECKSUM_UNNECESSARY in the
+XDP-MB-PASS path.
+So the by skb_checksum_none_assert() WARNS about it.
+
+This is duplicate work and updating ip_summed in the
+bnxt_xdp_build_skb() is not needed.
+
+Splat looks like:
+WARNING: CPU: 3 PID: 5782 at ./include/linux/skbuff.h:5155 bnxt_rx_pkt+0x479b/0x7610 [bnxt_en]
+Modules linked in: bnxt_re bnxt_en rdma_ucm rdma_cm iw_cm ib_cm ib_uverbs veth xt_nat xt_tcpudp xt_conntrack nft_chain_nat xt_MASQUERADE nf_]
+CPU: 3 UID: 0 PID: 5782 Comm: socat Tainted: G W 6.14.0-rc4+ #27
+Tainted: [W]=WARN
+Hardware name: ASUS System Product Name/PRIME Z690-P D4, BIOS 0603 11/01/2021
+RIP: 0010:bnxt_rx_pkt+0x479b/0x7610 [bnxt_en]
+Code: 54 24 0c 4c 89 f1 4c 89 ff c1 ea 1f ff d3 0f 1f 00 49 89 c6 48 85 c0 0f 84 4c e5 ff ff 48 89 c7 e8 ca 3d a0 c8 e9 8f f4 ff ff <0f> 0b f
+RSP: 0018:ffff88881ba09928 EFLAGS: 00010202
+RAX: 0000000000000000 RBX: 00000000c7590303 RCX: 0000000000000000
+RDX: 1ffff1104e7d1610 RSI: 0000000000000001 RDI: ffff8881c91300b8
+RBP: ffff88881ba09b28 R08: ffff888273e8b0d0 R09: ffff888273e8b070
+R10: ffff888273e8b010 R11: ffff888278b0f000 R12: ffff888273e8b080
+R13: ffff8881c9130e00 R14: ffff8881505d3800 R15: ffff888273e8b000
+FS: 00007f5a2e7be080(0000) GS:ffff88881ba00000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007fff2e708ff8 CR3: 000000013e3b0000 CR4: 00000000007506f0
+PKRU: 55555554
+Call Trace:
+ <IRQ>
+ ? __warn+0xcd/0x2f0
+ ? bnxt_rx_pkt+0x479b/0x7610
+ ? report_bug+0x326/0x3c0
+ ? handle_bug+0x53/0xa0
+ ? exc_invalid_op+0x14/0x50
+ ? asm_exc_invalid_op+0x16/0x20
+ ? bnxt_rx_pkt+0x479b/0x7610
+ ? bnxt_rx_pkt+0x3e41/0x7610
+ ? __pfx_bnxt_rx_pkt+0x10/0x10
+ ? napi_complete_done+0x2cf/0x7d0
+ __bnxt_poll_work+0x4e8/0x1220
+ ? __pfx___bnxt_poll_work+0x10/0x10
+ ? __pfx_mark_lock.part.0+0x10/0x10
+ bnxt_poll_p5+0x36a/0xfa0
+ ? __pfx_bnxt_poll_p5+0x10/0x10
+ __napi_poll.constprop.0+0xa0/0x440
+ net_rx_action+0x899/0xd00
+...
+
+Following ping.py patch adds xdp-mb-pass case. so ping.py is going
+to be able to reproduce this issue.
+
+Fixes: 1dc4c557bfed ("bnxt: adding bnxt_xdp_build_skb to build skb from multibuffer xdp_buff")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Link: https://patch.msgid.link/20250309134219.91670-5-ap420073@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 3 ++-
+ drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 11 ++---------
+ drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h | 3 +--
+ 3 files changed, 5 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index c440f4d8d43a2..915ef1062d714 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -1958,7 +1958,8 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+ if (!skb)
+ goto oom_next_rx;
+ } else {
+- skb = bnxt_xdp_build_skb(bp, skb, agg_bufs, rxr->page_pool, &xdp, rxcmp1);
++ skb = bnxt_xdp_build_skb(bp, skb, agg_bufs,
++ rxr->page_pool, &xdp);
+ if (!skb) {
+ /* we should be able to free the old skb here */
+ bnxt_xdp_buff_frags_free(rxr, &xdp);
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+index 2845796f782c2..758f51366ef03 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+@@ -462,20 +462,13 @@ int bnxt_xdp(struct net_device *dev, struct netdev_bpf *xdp)
+
+ struct sk_buff *
+ bnxt_xdp_build_skb(struct bnxt *bp, struct sk_buff *skb, u8 num_frags,
+- struct page_pool *pool, struct xdp_buff *xdp,
+- struct rx_cmp_ext *rxcmp1)
++ struct page_pool *pool, struct xdp_buff *xdp)
+ {
+ struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);
+
+ if (!skb)
+ return NULL;
+- skb_checksum_none_assert(skb);
+- if (RX_CMP_L4_CS_OK(rxcmp1)) {
+- if (bp->dev->features & NETIF_F_RXCSUM) {
+- skb->ip_summed = CHECKSUM_UNNECESSARY;
+- skb->csum_level = RX_CMP_ENCAP(rxcmp1);
+- }
+- }
++
+ xdp_update_skb_shared_info(skb, num_frags,
+ sinfo->xdp_frags_size,
+ BNXT_RX_PAGE_SIZE * sinfo->nr_frags,
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
+index 5e412c5655ba5..9f5829a0adeb1 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
+@@ -33,6 +33,5 @@ void bnxt_xdp_buff_frags_free(struct bnxt_rx_ring_info *rxr,
+ struct xdp_buff *xdp);
+ struct sk_buff *bnxt_xdp_build_skb(struct bnxt *bp, struct sk_buff *skb,
+ u8 num_frags, struct page_pool *pool,
+- struct xdp_buff *xdp,
+- struct rx_cmp_ext *rxcmp1);
++ struct xdp_buff *xdp);
+ #endif
+--
+2.39.5
+
--- /dev/null
+From 1def1216b3d3bdcb1a38742910191d4dd015dd31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Sep 2023 10:52:03 +0200
+Subject: fbdev/core: Unexport logo helpers
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit fa671e4f1556e2c18e5443f777a75ae041290068 ]
+
+The interfaces for the fbdev logo are not used outside of the fbdev
+module. Hence declare the fbdev logo functions in the internal header
+file and remove their symbol exports. Only build the functions if
+CONFIG_LOGO has been selected.
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Acked-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230907085408.9354-5-tzimmermann@suse.de
+Stable-dep-of: ea2f45ab0e53 ("fbdev: hyperv_fb: Allow graceful removal of framebuffer")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/core/fb_internal.h | 16 ++++++++++++++++
+ drivers/video/fbdev/core/fbmem.c | 5 -----
+ include/linux/fb.h | 5 -----
+ 3 files changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/video/fbdev/core/fb_internal.h b/drivers/video/fbdev/core/fb_internal.h
+index 4c8d509a00265..1116faefa0347 100644
+--- a/drivers/video/fbdev/core/fb_internal.h
++++ b/drivers/video/fbdev/core/fb_internal.h
+@@ -21,6 +21,22 @@ static inline void fb_unregister_chrdev(void)
+ #endif
+
+ /* fbmem.c */
++#if defined(CONFIG_LOGO)
++extern bool fb_center_logo;
++extern int fb_logo_count;
++int fb_prepare_logo(struct fb_info *fb_info, int rotate);
++int fb_show_logo(struct fb_info *fb_info, int rotate);
++#else
++static inline int fb_prepare_logo(struct fb_info *info, int rotate)
++{
++ return 0;
++}
++static inline int fb_show_logo(struct fb_info *info, int rotate)
++{
++ return 0;
++}
++#endif /* CONFIG_LOGO */
++
+ extern struct class *fb_class;
+ extern struct mutex registration_lock;
+ extern struct fb_info *registered_fb[FB_MAX];
+diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
+index ee44a46a66be1..0d0003bcdd933 100644
+--- a/drivers/video/fbdev/core/fbmem.c
++++ b/drivers/video/fbdev/core/fbmem.c
+@@ -695,12 +695,7 @@ int fb_show_logo(struct fb_info *info, int rotate)
+
+ return y;
+ }
+-#else
+-int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; }
+-int fb_show_logo(struct fb_info *info, int rotate) { return 0; }
+ #endif /* CONFIG_LOGO */
+-EXPORT_SYMBOL(fb_prepare_logo);
+-EXPORT_SYMBOL(fb_show_logo);
+
+ int
+ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
+diff --git a/include/linux/fb.h b/include/linux/fb.h
+index 322b4d20afa55..16a9a0a0894d9 100644
+--- a/include/linux/fb.h
++++ b/include/linux/fb.h
+@@ -591,8 +591,6 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
+ /* fbmem.c */
+ extern int register_framebuffer(struct fb_info *fb_info);
+ extern void unregister_framebuffer(struct fb_info *fb_info);
+-extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
+-extern int fb_show_logo(struct fb_info *fb_info, int rotate);
+ extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
+ extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx,
+ u32 height, u32 shift_high, u32 shift_low, u32 mod);
+@@ -603,9 +601,6 @@ extern int fb_get_color_depth(struct fb_var_screeninfo *var,
+ extern int fb_get_options(const char *name, char **option);
+ extern int fb_new_modelist(struct fb_info *info);
+
+-extern bool fb_center_logo;
+-extern int fb_logo_count;
+-
+ static inline void lock_fb_info(struct fb_info *info)
+ {
+ mutex_lock(&info->lock);
+--
+2.39.5
+
--- /dev/null
+From ba1f857547f7d8dfd9b50a9be168cd344dcb484b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Mar 2025 08:16:31 -0800
+Subject: fbdev: hyperv_fb: Allow graceful removal of framebuffer
+
+From: Saurabh Sengar <ssengar@linux.microsoft.com>
+
+[ Upstream commit ea2f45ab0e53b255f72c85ccd99e2b394fc5fceb ]
+
+When a Hyper-V framebuffer device is unbind, hyperv_fb driver tries to
+release the framebuffer forcefully. If this framebuffer is in use it
+produce the following WARN and hence this framebuffer is never released.
+
+[ 44.111220] WARNING: CPU: 35 PID: 1882 at drivers/video/fbdev/core/fb_info.c:70 framebuffer_release+0x2c/0x40
+< snip >
+[ 44.111289] Call Trace:
+[ 44.111290] <TASK>
+[ 44.111291] ? show_regs+0x6c/0x80
+[ 44.111295] ? __warn+0x8d/0x150
+[ 44.111298] ? framebuffer_release+0x2c/0x40
+[ 44.111300] ? report_bug+0x182/0x1b0
+[ 44.111303] ? handle_bug+0x6e/0xb0
+[ 44.111306] ? exc_invalid_op+0x18/0x80
+[ 44.111308] ? asm_exc_invalid_op+0x1b/0x20
+[ 44.111311] ? framebuffer_release+0x2c/0x40
+[ 44.111313] ? hvfb_remove+0x86/0xa0 [hyperv_fb]
+[ 44.111315] vmbus_remove+0x24/0x40 [hv_vmbus]
+[ 44.111323] device_remove+0x40/0x80
+[ 44.111325] device_release_driver_internal+0x20b/0x270
+[ 44.111327] ? bus_find_device+0xb3/0xf0
+
+Fix this by moving the release of framebuffer and assosiated memory
+to fb_ops.fb_destroy function, so that framebuffer framework handles
+it gracefully.
+
+While we fix this, also replace manual registrations/unregistration of
+framebuffer with devm_register_framebuffer.
+
+Fixes: 68a2d20b79b1 ("drivers/video: add Hyper-V Synthetic Video Frame Buffer Driver")
+
+Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
+Reviewed-by: Michael Kelley <mhklinux@outlook.com>
+Tested-by: Michael Kelley <mhklinux@outlook.com>
+Link: https://lore.kernel.org/r/1740845791-19977-3-git-send-email-ssengar@linux.microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Message-ID: <1740845791-19977-3-git-send-email-ssengar@linux.microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/hyperv_fb.c | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
+index 5e0dc5033b988..eb5b4eb948352 100644
+--- a/drivers/video/fbdev/hyperv_fb.c
++++ b/drivers/video/fbdev/hyperv_fb.c
+@@ -283,6 +283,8 @@ static uint screen_depth;
+ static uint screen_fb_size;
+ static uint dio_fb_size; /* FB size for deferred IO */
+
++static void hvfb_putmem(struct fb_info *info);
++
+ /* Send message to Hyper-V host */
+ static inline int synthvid_send(struct hv_device *hdev,
+ struct synthvid_msg *msg)
+@@ -863,6 +865,17 @@ static void hvfb_ops_damage_area(struct fb_info *info, u32 x, u32 y, u32 width,
+ hvfb_ondemand_refresh_throttle(par, x, y, width, height);
+ }
+
++/*
++ * fb_ops.fb_destroy is called by the last put_fb_info() call at the end
++ * of unregister_framebuffer() or fb_release(). Do any cleanup related to
++ * framebuffer here.
++ */
++static void hvfb_destroy(struct fb_info *info)
++{
++ hvfb_putmem(info);
++ framebuffer_release(info);
++}
++
+ /*
+ * TODO: GEN1 codepaths allocate from system or DMA-able memory. Fix the
+ * driver to use the _SYSMEM_ or _DMAMEM_ helpers in these cases.
+@@ -878,6 +891,7 @@ static const struct fb_ops hvfb_ops = {
+ .fb_set_par = hvfb_set_par,
+ .fb_setcolreg = hvfb_setcolreg,
+ .fb_blank = hvfb_blank,
++ .fb_destroy = hvfb_destroy,
+ };
+
+ /* Get options from kernel paramenter "video=" */
+@@ -1178,7 +1192,7 @@ static int hvfb_probe(struct hv_device *hdev,
+ if (ret)
+ goto error;
+
+- ret = register_framebuffer(info);
++ ret = devm_register_framebuffer(&hdev->device, info);
+ if (ret) {
+ pr_err("Unable to register framebuffer\n");
+ goto error;
+@@ -1226,14 +1240,10 @@ static void hvfb_remove(struct hv_device *hdev)
+
+ fb_deferred_io_cleanup(info);
+
+- unregister_framebuffer(info);
+ cancel_delayed_work_sync(&par->dwork);
+
+ vmbus_close(hdev->channel);
+ hv_set_drvdata(hdev, NULL);
+-
+- hvfb_putmem(info);
+- framebuffer_release(info);
+ }
+
+ static int hvfb_suspend(struct hv_device *hdev)
+--
+2.39.5
+
--- /dev/null
+From f9479a1db3b7f521ae0df770bce1cdb605cb1682 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Feb 2025 15:52:52 -0800
+Subject: fbdev: hyperv_fb: iounmap() the correct memory when removing a device
+
+From: Michael Kelley <mhklinux@outlook.com>
+
+[ Upstream commit 7241c886a71797cc51efc6fadec7076fcf6435c2 ]
+
+When a Hyper-V framebuffer device is removed, or the driver is unbound
+from a device, any allocated and/or mapped memory must be released. In
+particular, MMIO address space that was mapped to the framebuffer must
+be unmapped. Current code unmaps the wrong address, resulting in an
+error like:
+
+[ 4093.980597] iounmap: bad address 00000000c936c05c
+
+followed by a stack dump.
+
+Commit d21987d709e8 ("video: hyperv: hyperv_fb: Support deferred IO for
+Hyper-V frame buffer driver") changed the kind of address stored in
+info->screen_base, and the iounmap() call in hvfb_putmem() was not
+updated accordingly.
+
+Fix this by updating hvfb_putmem() to unmap the correct address.
+
+Fixes: d21987d709e8 ("video: hyperv: hyperv_fb: Support deferred IO for Hyper-V frame buffer driver")
+Signed-off-by: Michael Kelley <mhklinux@outlook.com>
+Reviewed-by: Saurabh Sengar <ssengar@linux.microsoft.com>
+Link: https://lore.kernel.org/r/20250209235252.2987-1-mhklinux@outlook.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Message-ID: <20250209235252.2987-1-mhklinux@outlook.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/hyperv_fb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
+index b9965cbdd7642..80e8ec36b7db2 100644
+--- a/drivers/video/fbdev/hyperv_fb.c
++++ b/drivers/video/fbdev/hyperv_fb.c
+@@ -1106,7 +1106,7 @@ static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info)
+
+ if (par->need_docopy) {
+ vfree(par->dio_vp);
+- iounmap(info->screen_base);
++ iounmap(par->mmio_vp);
+ vmbus_free_mmio(par->mem->start, screen_fb_size);
+ } else {
+ hvfb_release_phymem(hdev, info->fix.smem_start,
+--
+2.39.5
+
--- /dev/null
+From 1dde7485e6894a25fef58ee96a6d9ab029a362c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Mar 2025 08:16:30 -0800
+Subject: fbdev: hyperv_fb: Simplify hvfb_putmem
+
+From: Saurabh Sengar <ssengar@linux.microsoft.com>
+
+[ Upstream commit f5e728a50bb17336a20803dde488515b833ecd1d ]
+
+The device object required in 'hvfb_release_phymem' function
+for 'dma_free_coherent' can also be obtained from the 'info'
+pointer, making 'hdev' parameter in 'hvfb_putmem' redundant.
+Remove the unnecessary 'hdev' argument from 'hvfb_putmem'.
+
+Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
+Reviewed-by: Michael Kelley <mhklinux@outlook.com>
+Tested-by: Michael Kelley <mhklinux@outlook.com>
+Link: https://lore.kernel.org/r/1740845791-19977-2-git-send-email-ssengar@linux.microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Message-ID: <1740845791-19977-2-git-send-email-ssengar@linux.microsoft.com>
+Stable-dep-of: ea2f45ab0e53 ("fbdev: hyperv_fb: Allow graceful removal of framebuffer")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/hyperv_fb.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
+index 99e12abdeea1e..5e0dc5033b988 100644
+--- a/drivers/video/fbdev/hyperv_fb.c
++++ b/drivers/video/fbdev/hyperv_fb.c
+@@ -953,7 +953,7 @@ static phys_addr_t hvfb_get_phymem(struct hv_device *hdev,
+ }
+
+ /* Release contiguous physical memory */
+-static void hvfb_release_phymem(struct hv_device *hdev,
++static void hvfb_release_phymem(struct device *device,
+ phys_addr_t paddr, unsigned int size)
+ {
+ unsigned int order = get_order(size);
+@@ -961,7 +961,7 @@ static void hvfb_release_phymem(struct hv_device *hdev,
+ if (order <= MAX_ORDER)
+ __free_pages(pfn_to_page(paddr >> PAGE_SHIFT), order);
+ else
+- dma_free_coherent(&hdev->device,
++ dma_free_coherent(device,
+ round_up(size, PAGE_SIZE),
+ phys_to_virt(paddr),
+ paddr);
+@@ -1080,7 +1080,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
+ }
+
+ /* Release the framebuffer */
+-static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info)
++static void hvfb_putmem(struct fb_info *info)
+ {
+ struct hvfb_par *par = info->par;
+
+@@ -1089,7 +1089,7 @@ static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info)
+ iounmap(par->mmio_vp);
+ vmbus_free_mmio(par->mem->start, screen_fb_size);
+ } else {
+- hvfb_release_phymem(hdev, info->fix.smem_start,
++ hvfb_release_phymem(info->device, info->fix.smem_start,
+ screen_fb_size);
+ }
+
+@@ -1203,7 +1203,7 @@ static int hvfb_probe(struct hv_device *hdev,
+
+ error:
+ fb_deferred_io_cleanup(info);
+- hvfb_putmem(hdev, info);
++ hvfb_putmem(info);
+ error2:
+ vmbus_close(hdev->channel);
+ error1:
+@@ -1232,7 +1232,7 @@ static void hvfb_remove(struct hv_device *hdev)
+ vmbus_close(hdev->channel);
+ hv_set_drvdata(hdev, NULL);
+
+- hvfb_putmem(hdev, info);
++ hvfb_putmem(info);
+ framebuffer_release(info);
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 4606105325b2d3a522ce69624691959beb3024b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Aug 2023 15:14:20 +0200
+Subject: fbdev/hyperv_fb: Use fb_ops helpers for deferred I/O
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit 66a749a752351c7cdd0a4fefb2544ab05e7987c3 ]
+
+Generate callback functions for struct fb_ops with the fbdev macro
+FB_GEN_DEFAULT_DEFERRED_IOMEM_OPS(). Initialize struct fb_ops to
+the generated functions with fbdev initializer macros.
+
+The hyperv_fb driver is incomplete in its handling of deferred I/O
+and damage framebuffers. Write operations do no trigger damage handling.
+Fixing this is beyond the scope of this patch.
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Cc: "K. Y. Srinivasan" <kys@microsoft.com>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: Wei Liu <wei.liu@kernel.org>
+Cc: Dexuan Cui <decui@microsoft.com>
+Acked-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230828132131.29295-5-tzimmermann@suse.de
+Stable-dep-of: ea2f45ab0e53 ("fbdev: hyperv_fb: Allow graceful removal of framebuffer")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/Kconfig | 5 +---
+ drivers/video/fbdev/hyperv_fb.c | 48 ++++++++++-----------------------
+ 2 files changed, 15 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
+index 325298573e120..e33ea53996bd6 100644
+--- a/drivers/video/fbdev/Kconfig
++++ b/drivers/video/fbdev/Kconfig
+@@ -1900,11 +1900,8 @@ config FB_BROADSHEET
+ config FB_HYPERV
+ tristate "Microsoft Hyper-V Synthetic Video support"
+ depends on FB && HYPERV
+- select FB_CFB_FILLRECT
+- select FB_CFB_COPYAREA
+- select FB_CFB_IMAGEBLIT
+- select FB_DEFERRED_IO
+ select DMA_CMA if HAVE_DMA_CONTIGUOUS && CMA
++ select FB_IOMEM_HELPERS_DEFERRED
+ select VIDEO_NOMODESET
+ help
+ This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
+diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
+index 80e8ec36b7db2..99e12abdeea1e 100644
+--- a/drivers/video/fbdev/hyperv_fb.c
++++ b/drivers/video/fbdev/hyperv_fb.c
+@@ -848,58 +848,38 @@ static int hvfb_blank(int blank, struct fb_info *info)
+ return 1; /* get fb_blank to set the colormap to all black */
+ }
+
+-static void hvfb_cfb_fillrect(struct fb_info *p,
+- const struct fb_fillrect *rect)
++static void hvfb_ops_damage_range(struct fb_info *info, off_t off, size_t len)
+ {
+- struct hvfb_par *par = p->par;
+-
+- cfb_fillrect(p, rect);
+- if (par->synchronous_fb)
+- synthvid_update(p, 0, 0, INT_MAX, INT_MAX);
+- else
+- hvfb_ondemand_refresh_throttle(par, rect->dx, rect->dy,
+- rect->width, rect->height);
++ /* TODO: implement damage handling */
+ }
+
+-static void hvfb_cfb_copyarea(struct fb_info *p,
+- const struct fb_copyarea *area)
++static void hvfb_ops_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, u32 height)
+ {
+- struct hvfb_par *par = p->par;
++ struct hvfb_par *par = info->par;
+
+- cfb_copyarea(p, area);
+ if (par->synchronous_fb)
+- synthvid_update(p, 0, 0, INT_MAX, INT_MAX);
++ synthvid_update(info, 0, 0, INT_MAX, INT_MAX);
+ else
+- hvfb_ondemand_refresh_throttle(par, area->dx, area->dy,
+- area->width, area->height);
++ hvfb_ondemand_refresh_throttle(par, x, y, width, height);
+ }
+
+-static void hvfb_cfb_imageblit(struct fb_info *p,
+- const struct fb_image *image)
+-{
+- struct hvfb_par *par = p->par;
+-
+- cfb_imageblit(p, image);
+- if (par->synchronous_fb)
+- synthvid_update(p, 0, 0, INT_MAX, INT_MAX);
+- else
+- hvfb_ondemand_refresh_throttle(par, image->dx, image->dy,
+- image->width, image->height);
+-}
++/*
++ * TODO: GEN1 codepaths allocate from system or DMA-able memory. Fix the
++ * driver to use the _SYSMEM_ or _DMAMEM_ helpers in these cases.
++ */
++FB_GEN_DEFAULT_DEFERRED_IOMEM_OPS(hvfb_ops,
++ hvfb_ops_damage_range,
++ hvfb_ops_damage_area)
+
+ static const struct fb_ops hvfb_ops = {
+ .owner = THIS_MODULE,
++ FB_DEFAULT_DEFERRED_OPS(hvfb_ops),
+ .fb_check_var = hvfb_check_var,
+ .fb_set_par = hvfb_set_par,
+ .fb_setcolreg = hvfb_setcolreg,
+- .fb_fillrect = hvfb_cfb_fillrect,
+- .fb_copyarea = hvfb_cfb_copyarea,
+- .fb_imageblit = hvfb_cfb_imageblit,
+ .fb_blank = hvfb_blank,
+- .fb_mmap = fb_deferred_io_mmap,
+ };
+
+-
+ /* Get options from kernel paramenter "video=" */
+ static void hvfb_get_option(struct fb_info *info)
+ {
+--
+2.39.5
+
--- /dev/null
+From de57aae50432530fd10455baf296832bcf791f56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Aug 2024 11:45:57 +0200
+Subject: fbdev: Introduce devm_register_framebuffer()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Weißschuh <linux@weissschuh.net>
+
+[ Upstream commit 929c81ade6355b87097a2a4886c10750e68626cf ]
+
+Introduce a device-managed variant of register_framebuffer() which
+automatically unregisters the framebuffer on device destruction.
+This can simplify the error handling and resource management in drivers.
+
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Stable-dep-of: ea2f45ab0e53 ("fbdev: hyperv_fb: Allow graceful removal of framebuffer")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/core/fbmem.c | 30 ++++++++++++++++++++++++++++++
+ include/linux/fb.h | 1 +
+ 2 files changed, 31 insertions(+)
+
+diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
+index 0d0003bcdd933..8f096e46525ea 100644
+--- a/drivers/video/fbdev/core/fbmem.c
++++ b/drivers/video/fbdev/core/fbmem.c
+@@ -1079,6 +1079,36 @@ unregister_framebuffer(struct fb_info *fb_info)
+ }
+ EXPORT_SYMBOL(unregister_framebuffer);
+
++static void devm_unregister_framebuffer(void *data)
++{
++ struct fb_info *info = data;
++
++ unregister_framebuffer(info);
++}
++
++/**
++ * devm_register_framebuffer - resource-managed frame buffer device registration
++ * @dev: device the framebuffer belongs to
++ * @fb_info: frame buffer info structure
++ *
++ * Registers a frame buffer device @fb_info to device @dev.
++ *
++ * Returns negative errno on error, or zero for success.
++ *
++ */
++int
++devm_register_framebuffer(struct device *dev, struct fb_info *fb_info)
++{
++ int ret;
++
++ ret = register_framebuffer(fb_info);
++ if (ret)
++ return ret;
++
++ return devm_add_action_or_reset(dev, devm_unregister_framebuffer, fb_info);
++}
++EXPORT_SYMBOL(devm_register_framebuffer);
++
+ /**
+ * fb_set_suspend - low level driver signals suspend
+ * @info: framebuffer affected
+diff --git a/include/linux/fb.h b/include/linux/fb.h
+index 16a9a0a0894d9..a665e087d5db1 100644
+--- a/include/linux/fb.h
++++ b/include/linux/fb.h
+@@ -591,6 +591,7 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
+ /* fbmem.c */
+ extern int register_framebuffer(struct fb_info *fb_info);
+ extern void unregister_framebuffer(struct fb_info *fb_info);
++extern int devm_register_framebuffer(struct device *dev, struct fb_info *fb_info);
+ extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
+ extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx,
+ u32 height, u32 shift_high, u32 shift_low, u32 mod);
+--
+2.39.5
+
--- /dev/null
+From 6f449f98876ab5b526e7c95c32aaeacdf5a00705 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Sep 2023 10:52:01 +0200
+Subject: fbdev/mmp/mmpfb: Do not display boot-up logo
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit 828d96633ab7e0fe8032e9123d57b318cfd9f145 ]
+
+The fbcon module takes care of displaying the logo, if any. Remove
+the code form mmpfb. It is probably no tworking as expected, as it
+interferes with the framebuffer console. If we want to display the
+logo without fbcon, we should implement this in the fbdev core code.
+
+v2:
+ * add a note on fbcon interference (Javier)
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Acked-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230907085408.9354-3-tzimmermann@suse.de
+Stable-dep-of: ea2f45ab0e53 ("fbdev: hyperv_fb: Allow graceful removal of framebuffer")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/mmp/fb/mmpfb.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/video/fbdev/mmp/fb/mmpfb.c b/drivers/video/fbdev/mmp/fb/mmpfb.c
+index 42a87474bcead..2d9797c6fb3e6 100644
+--- a/drivers/video/fbdev/mmp/fb/mmpfb.c
++++ b/drivers/video/fbdev/mmp/fb/mmpfb.c
+@@ -628,13 +628,6 @@ static int mmpfb_probe(struct platform_device *pdev)
+ dev_info(fbi->dev, "loaded to /dev/fb%d <%s>.\n",
+ info->node, info->fix.id);
+
+-#ifdef CONFIG_LOGO
+- if (fbi->fb_start) {
+- fb_prepare_logo(info, 0);
+- fb_show_logo(info, 0);
+- }
+-#endif
+-
+ return 0;
+
+ failed_clear_info:
+--
+2.39.5
+
--- /dev/null
+From 6800587dc656877125a32ef46449569ed158e9b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Mar 2025 20:28:53 +0100
+Subject: gre: Fix IPv6 link-local address generation.
+
+From: Guillaume Nault <gnault@redhat.com>
+
+[ Upstream commit 183185a18ff96751db52a46ccf93fff3a1f42815 ]
+
+Use addrconf_addr_gen() to generate IPv6 link-local addresses on GRE
+devices in most cases and fall back to using add_v4_addrs() only in
+case the GRE configuration is incompatible with addrconf_addr_gen().
+
+GRE used to use addrconf_addr_gen() until commit e5dd729460ca
+("ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL
+address") restricted this use to gretap and ip6gretap devices, and
+created add_v4_addrs() (borrowed from SIT) for non-Ethernet GRE ones.
+
+The original problem came when commit 9af28511be10 ("addrconf: refuse
+isatap eui64 for INADDR_ANY") made __ipv6_isatap_ifid() fail when its
+addr parameter was 0. The commit says that this would create an invalid
+address, however, I couldn't find any RFC saying that the generated
+interface identifier would be wrong. Anyway, since gre over IPv4
+devices pass their local tunnel address to __ipv6_isatap_ifid(), that
+commit broke their IPv6 link-local address generation when the local
+address was unspecified.
+
+Then commit e5dd729460ca ("ip/ip6_gre: use the same logic as SIT
+interfaces when computing v6LL address") tried to fix that case by
+defining add_v4_addrs() and calling it to generate the IPv6 link-local
+address instead of using addrconf_addr_gen() (apart for gretap and
+ip6gretap devices, which would still use the regular
+addrconf_addr_gen(), since they have a MAC address).
+
+That broke several use cases because add_v4_addrs() isn't properly
+integrated into the rest of IPv6 Neighbor Discovery code. Several of
+these shortcomings have been fixed over time, but add_v4_addrs()
+remains broken on several aspects. In particular, it doesn't send any
+Router Sollicitations, so the SLAAC process doesn't start until the
+interface receives a Router Advertisement. Also, add_v4_addrs() mostly
+ignores the address generation mode of the interface
+(/proc/sys/net/ipv6/conf/*/addr_gen_mode), thus breaking the
+IN6_ADDR_GEN_MODE_RANDOM and IN6_ADDR_GEN_MODE_STABLE_PRIVACY cases.
+
+Fix the situation by using add_v4_addrs() only in the specific scenario
+where the normal method would fail. That is, for interfaces that have
+all of the following characteristics:
+
+ * run over IPv4,
+ * transport IP packets directly, not Ethernet (that is, not gretap
+ interfaces),
+ * tunnel endpoint is INADDR_ANY (that is, 0),
+ * device address generation mode is EUI64.
+
+In all other cases, revert back to the regular addrconf_addr_gen().
+
+Also, remove the special case for ip6gre interfaces in add_v4_addrs(),
+since ip6gre devices now always use addrconf_addr_gen() instead.
+
+Fixes: e5dd729460ca ("ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL address")
+Signed-off-by: Guillaume Nault <gnault@redhat.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/559c32ce5c9976b269e6337ac9abb6a96abe5096.1741375285.git.gnault@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/addrconf.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 8360939acf85a..db07d3bbaf379 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -3189,16 +3189,13 @@ static void add_v4_addrs(struct inet6_dev *idev)
+ struct in6_addr addr;
+ struct net_device *dev;
+ struct net *net = dev_net(idev->dev);
+- int scope, plen, offset = 0;
++ int scope, plen;
+ u32 pflags = 0;
+
+ ASSERT_RTNL();
+
+ memset(&addr, 0, sizeof(struct in6_addr));
+- /* in case of IP6GRE the dev_addr is an IPv6 and therefore we use only the last 4 bytes */
+- if (idev->dev->addr_len == sizeof(struct in6_addr))
+- offset = sizeof(struct in6_addr) - 4;
+- memcpy(&addr.s6_addr32[3], idev->dev->dev_addr + offset, 4);
++ memcpy(&addr.s6_addr32[3], idev->dev->dev_addr, 4);
+
+ if (!(idev->dev->flags & IFF_POINTOPOINT) && idev->dev->type == ARPHRD_SIT) {
+ scope = IPV6_ADDR_COMPATv4;
+@@ -3508,7 +3505,13 @@ static void addrconf_gre_config(struct net_device *dev)
+ return;
+ }
+
+- if (dev->type == ARPHRD_ETHER) {
++ /* Generate the IPv6 link-local address using addrconf_addr_gen(),
++ * unless we have an IPv4 GRE device not bound to an IP address and
++ * which is in EUI64 mode (as __ipv6_isatap_ifid() would fail in this
++ * case). Such devices fall back to add_v4_addrs() instead.
++ */
++ if (!(dev->type == ARPHRD_IPGRE && *(__be32 *)dev->dev_addr == 0 &&
++ idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64)) {
+ addrconf_addr_gen(idev, true);
+ return;
+ }
+--
+2.39.5
+
--- /dev/null
+From f597ef81f3ede8420f10099878296907d469473f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2025 09:15:39 +0100
+Subject: ice: fix memory leak in aRFS after reset
+
+From: Grzegorz Nitka <grzegorz.nitka@intel.com>
+
+[ Upstream commit 23d97f18901ef5e4e264e3b1777fe65c760186b5 ]
+
+Fix aRFS (accelerated Receive Flow Steering) structures memory leak by
+adding a checker to verify if aRFS memory is already allocated while
+configuring VSI. aRFS objects are allocated in two cases:
+- as part of VSI initialization (at probe), and
+- as part of reset handling
+
+However, VSI reconfiguration executed during reset involves memory
+allocation one more time, without prior releasing already allocated
+resources. This led to the memory leak with the following signature:
+
+[root@os-delivery ~]# cat /sys/kernel/debug/kmemleak
+unreferenced object 0xff3c1ca7252e6000 (size 8192):
+ comm "kworker/0:0", pid 8, jiffies 4296833052
+ hex dump (first 32 bytes):
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ backtrace (crc 0):
+ [<ffffffff991ec485>] __kmalloc_cache_noprof+0x275/0x340
+ [<ffffffffc0a6e06a>] ice_init_arfs+0x3a/0xe0 [ice]
+ [<ffffffffc09f1027>] ice_vsi_cfg_def+0x607/0x850 [ice]
+ [<ffffffffc09f244b>] ice_vsi_setup+0x5b/0x130 [ice]
+ [<ffffffffc09c2131>] ice_init+0x1c1/0x460 [ice]
+ [<ffffffffc09c64af>] ice_probe+0x2af/0x520 [ice]
+ [<ffffffff994fbcd3>] local_pci_probe+0x43/0xa0
+ [<ffffffff98f07103>] work_for_cpu_fn+0x13/0x20
+ [<ffffffff98f0b6d9>] process_one_work+0x179/0x390
+ [<ffffffff98f0c1e9>] worker_thread+0x239/0x340
+ [<ffffffff98f14abc>] kthread+0xcc/0x100
+ [<ffffffff98e45a6d>] ret_from_fork+0x2d/0x50
+ [<ffffffff98e083ba>] ret_from_fork_asm+0x1a/0x30
+ ...
+
+Fixes: 28bf26724fdb ("ice: Implement aRFS")
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_arfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_arfs.c b/drivers/net/ethernet/intel/ice/ice_arfs.c
+index cca0e753f38ff..d7e0116f67737 100644
+--- a/drivers/net/ethernet/intel/ice/ice_arfs.c
++++ b/drivers/net/ethernet/intel/ice/ice_arfs.c
+@@ -510,7 +510,7 @@ void ice_init_arfs(struct ice_vsi *vsi)
+ struct hlist_head *arfs_fltr_list;
+ unsigned int i;
+
+- if (!vsi || vsi->type != ICE_VSI_PF)
++ if (!vsi || vsi->type != ICE_VSI_PF || ice_is_arfs_active(vsi))
+ return;
+
+ arfs_fltr_list = kcalloc(ICE_MAX_ARFS_LIST, sizeof(*arfs_fltr_list),
+--
+2.39.5
+
--- /dev/null
+From 73bf39e9ca9eab9b850d6eae00e114349fad5d1f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 10:45:53 +0300
+Subject: ipvs: prevent integer overflow in do_ip_vs_get_ctl()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 80b78c39eb86e6b55f56363b709eb817527da5aa ]
+
+The get->num_services variable is an unsigned int which is controlled by
+the user. The struct_size() function ensures that the size calculation
+does not overflow an unsigned long, however, we are saving the result to
+an int so the calculation can overflow.
+
+Both "len" and "get->num_services" come from the user. This check is
+just a sanity check to help the user and ensure they are using the API
+correctly. An integer overflow here is not a big deal. This has no
+security impact.
+
+Save the result from struct_size() type size_t to fix this integer
+overflow bug.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_ctl.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
+index dec5309d9f1f5..ae76542de3e98 100644
+--- a/net/netfilter/ipvs/ip_vs_ctl.c
++++ b/net/netfilter/ipvs/ip_vs_ctl.c
+@@ -3091,12 +3091,12 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
+ case IP_VS_SO_GET_SERVICES:
+ {
+ struct ip_vs_get_services *get;
+- int size;
++ size_t size;
+
+ get = (struct ip_vs_get_services *)arg;
+ size = struct_size(get, entrytable, get->num_services);
+ if (*len != size) {
+- pr_err("length: %u != %u\n", *len, size);
++ pr_err("length: %u != %zu\n", *len, size);
+ ret = -EINVAL;
+ goto out;
+ }
+@@ -3132,12 +3132,12 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
+ case IP_VS_SO_GET_DESTS:
+ {
+ struct ip_vs_get_dests *get;
+- int size;
++ size_t size;
+
+ get = (struct ip_vs_get_dests *)arg;
+ size = struct_size(get, entrytable, get->num_dests);
+ if (*len != size) {
+- pr_err("length: %u != %u\n", *len, size);
++ pr_err("length: %u != %zu\n", *len, size);
+ ret = -EINVAL;
+ goto out;
+ }
+--
+2.39.5
+
--- /dev/null
+From 50761fcf75ab3937d428d70ee0ebd9e9f95afeb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 12:23:05 -0500
+Subject: net: dsa: mv88e6xxx: Verify after ATU Load ops
+
+From: Joseph Huang <Joseph.Huang@garmin.com>
+
+[ Upstream commit dc5340c3133a3ebe54853fd299116149e528cfaa ]
+
+ATU Load operations could fail silently if there's not enough space
+on the device to hold the new entry. When this happens, the symptom
+depends on the unknown flood settings. If unknown multicast flood is
+disabled, the multicast packets are dropped when the ATU table is
+full. If unknown multicast flood is enabled, the multicast packets
+will be flooded to all ports. Either way, IGMP snooping is broken
+when the ATU Load operation fails silently.
+
+Do a Read-After-Write verification after each fdb/mdb add operation
+to make sure that the operation was really successful, and return
+-ENOSPC otherwise.
+
+Fixes: defb05b9b9b4 ("net: dsa: mv88e6xxx: Add support for fdb_add, fdb_del, and fdb_getnext")
+Signed-off-by: Joseph Huang <Joseph.Huang@garmin.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250306172306.3859214-1-Joseph.Huang@garmin.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/chip.c | 59 ++++++++++++++++++++++++++------
+ 1 file changed, 48 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index 062bcbe6255cf..a39b33353ca6c 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -2125,13 +2125,11 @@ mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
+ return err;
+ }
+
+-static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
+- const unsigned char *addr, u16 vid,
+- u8 state)
++static int mv88e6xxx_port_db_get(struct mv88e6xxx_chip *chip,
++ const unsigned char *addr, u16 vid,
++ u16 *fid, struct mv88e6xxx_atu_entry *entry)
+ {
+- struct mv88e6xxx_atu_entry entry;
+ struct mv88e6xxx_vtu_entry vlan;
+- u16 fid;
+ int err;
+
+ /* Ports have two private address databases: one for when the port is
+@@ -2142,7 +2140,7 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
+ * VLAN ID into the port's database used for VLAN-unaware bridging.
+ */
+ if (vid == 0) {
+- fid = MV88E6XXX_FID_BRIDGED;
++ *fid = MV88E6XXX_FID_BRIDGED;
+ } else {
+ err = mv88e6xxx_vtu_get(chip, vid, &vlan);
+ if (err)
+@@ -2152,14 +2150,39 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
+ if (!vlan.valid)
+ return -EOPNOTSUPP;
+
+- fid = vlan.fid;
++ *fid = vlan.fid;
+ }
+
+- entry.state = 0;
+- ether_addr_copy(entry.mac, addr);
+- eth_addr_dec(entry.mac);
++ entry->state = 0;
++ ether_addr_copy(entry->mac, addr);
++ eth_addr_dec(entry->mac);
++
++ return mv88e6xxx_g1_atu_getnext(chip, *fid, entry);
++}
++
++static bool mv88e6xxx_port_db_find(struct mv88e6xxx_chip *chip,
++ const unsigned char *addr, u16 vid)
++{
++ struct mv88e6xxx_atu_entry entry;
++ u16 fid;
++ int err;
+
+- err = mv88e6xxx_g1_atu_getnext(chip, fid, &entry);
++ err = mv88e6xxx_port_db_get(chip, addr, vid, &fid, &entry);
++ if (err)
++ return false;
++
++ return entry.state && ether_addr_equal(entry.mac, addr);
++}
++
++static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
++ const unsigned char *addr, u16 vid,
++ u8 state)
++{
++ struct mv88e6xxx_atu_entry entry;
++ u16 fid;
++ int err;
++
++ err = mv88e6xxx_port_db_get(chip, addr, vid, &fid, &entry);
+ if (err)
+ return err;
+
+@@ -2757,6 +2780,13 @@ static int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
+ mv88e6xxx_reg_lock(chip);
+ err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
+ MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
++ if (err)
++ goto out;
++
++ if (!mv88e6xxx_port_db_find(chip, addr, vid))
++ err = -ENOSPC;
++
++out:
+ mv88e6xxx_reg_unlock(chip);
+
+ return err;
+@@ -6454,6 +6484,13 @@ static int mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port,
+ mv88e6xxx_reg_lock(chip);
+ err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
+ MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC);
++ if (err)
++ goto out;
++
++ if (!mv88e6xxx_port_db_find(chip, mdb->addr, mdb->vid))
++ err = -ENOSPC;
++
++out:
+ mv88e6xxx_reg_unlock(chip);
+
+ return err;
+--
+2.39.5
+
--- /dev/null
+From 4e6e9279b7212a42e5c141809e1440800b0eedb2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 10:33:20 +0800
+Subject: net: mctp i2c: Copy headers if cloned
+
+From: Matt Johnston <matt@codeconstruct.com.au>
+
+[ Upstream commit df8ce77ba8b7c012a3edd1ca7368b46831341466 ]
+
+Use skb_cow_head() prior to modifying the TX SKB. This is necessary
+when the SKB has been cloned, to avoid modifying other shared clones.
+
+Signed-off-by: Matt Johnston <matt@codeconstruct.com.au>
+Fixes: f5b8abf9fc3d ("mctp i2c: MCTP I2C binding driver")
+Link: https://patch.msgid.link/20250306-matt-mctp-i2c-cow-v1-1-293827212681@codeconstruct.com.au
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/mctp/mctp-i2c.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/mctp/mctp-i2c.c b/drivers/net/mctp/mctp-i2c.c
+index 20b8d7d528baf..fbe8483a07b58 100644
+--- a/drivers/net/mctp/mctp-i2c.c
++++ b/drivers/net/mctp/mctp-i2c.c
+@@ -543,6 +543,7 @@ static int mctp_i2c_header_create(struct sk_buff *skb, struct net_device *dev,
+ struct mctp_i2c_hdr *hdr;
+ struct mctp_hdr *mhdr;
+ u8 lldst, llsrc;
++ int rc;
+
+ if (len > MCTP_I2C_MAXMTU)
+ return -EMSGSIZE;
+@@ -553,6 +554,10 @@ static int mctp_i2c_header_create(struct sk_buff *skb, struct net_device *dev,
+ lldst = *((u8 *)daddr);
+ llsrc = *((u8 *)saddr);
+
++ rc = skb_cow_head(skb, sizeof(struct mctp_i2c_hdr));
++ if (rc)
++ return rc;
++
+ skb_push(skb, sizeof(struct mctp_i2c_hdr));
+ skb_reset_mac_header(skb);
+ hdr = (void *)skb_mac_header(skb);
+--
+2.39.5
+
--- /dev/null
+From da668fa96217c0ceee6404aaf36b0dcd274c87e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Mar 2025 00:01:43 +0200
+Subject: net/mlx5: Bridge, fix the crash caused by LAG state check
+
+From: Jianbo Liu <jianbol@nvidia.com>
+
+[ Upstream commit 4b8eeed4fb105770ce6dc84a2c6ef953c7b71cbb ]
+
+When removing LAG device from bridge, NETDEV_CHANGEUPPER event is
+triggered. Driver finds the lower devices (PFs) to flush all the
+offloaded entries. And mlx5_lag_is_shared_fdb is checked, it returns
+false if one of PF is unloaded. In such case,
+mlx5_esw_bridge_lag_rep_get() and its caller return NULL, instead of
+the alive PF, and the flush is skipped.
+
+Besides, the bridge fdb entry's lastuse is updated in mlx5 bridge
+event handler. But this SWITCHDEV_FDB_ADD_TO_BRIDGE event can be
+ignored in this case because the upper interface for bond is deleted,
+and the entry will never be aged because lastuse is never updated.
+
+To make things worse, as the entry is alive, mlx5 bridge workqueue
+keeps sending that event, which is then handled by kernel bridge
+notifier. It causes the following crash when accessing the passed bond
+netdev which is already destroyed.
+
+To fix this issue, remove such checks. LAG state is already checked in
+commit 15f8f168952f ("net/mlx5: Bridge, verify LAG state when adding
+bond to bridge"), driver still need to skip offload if LAG becomes
+invalid state after initialization.
+
+ Oops: stack segment: 0000 [#1] SMP
+ CPU: 3 UID: 0 PID: 23695 Comm: kworker/u40:3 Tainted: G OE 6.11.0_mlnx #1
+ Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
+ Workqueue: mlx5_bridge_wq mlx5_esw_bridge_update_work [mlx5_core]
+ RIP: 0010:br_switchdev_event+0x2c/0x110 [bridge]
+ Code: 44 00 00 48 8b 02 48 f7 00 00 02 00 00 74 69 41 54 55 53 48 83 ec 08 48 8b a8 08 01 00 00 48 85 ed 74 4a 48 83 fe 02 48 89 d3 <4c> 8b 65 00 74 23 76 49 48 83 fe 05 74 7e 48 83 fe 06 75 2f 0f b7
+ RSP: 0018:ffffc900092cfda0 EFLAGS: 00010297
+ RAX: ffff888123bfe000 RBX: ffffc900092cfe08 RCX: 00000000ffffffff
+ RDX: ffffc900092cfe08 RSI: 0000000000000001 RDI: ffffffffa0c585f0
+ RBP: 6669746f6e690a30 R08: 0000000000000000 R09: ffff888123ae92c8
+ R10: 0000000000000000 R11: fefefefefefefeff R12: ffff888123ae9c60
+ R13: 0000000000000001 R14: ffffc900092cfe08 R15: 0000000000000000
+ FS: 0000000000000000(0000) GS:ffff88852c980000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007f15914c8734 CR3: 0000000002830005 CR4: 0000000000770ef0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+ PKRU: 55555554
+ Call Trace:
+ <TASK>
+ ? __die_body+0x1a/0x60
+ ? die+0x38/0x60
+ ? do_trap+0x10b/0x120
+ ? do_error_trap+0x64/0xa0
+ ? exc_stack_segment+0x33/0x50
+ ? asm_exc_stack_segment+0x22/0x30
+ ? br_switchdev_event+0x2c/0x110 [bridge]
+ ? sched_balance_newidle.isra.149+0x248/0x390
+ notifier_call_chain+0x4b/0xa0
+ atomic_notifier_call_chain+0x16/0x20
+ mlx5_esw_bridge_update+0xec/0x170 [mlx5_core]
+ mlx5_esw_bridge_update_work+0x19/0x40 [mlx5_core]
+ process_scheduled_works+0x81/0x390
+ worker_thread+0x106/0x250
+ ? bh_worker+0x110/0x110
+ kthread+0xb7/0xe0
+ ? kthread_park+0x80/0x80
+ ret_from_fork+0x2d/0x50
+ ? kthread_park+0x80/0x80
+ ret_from_fork_asm+0x11/0x20
+ </TASK>
+
+Fixes: ff9b7521468b ("net/mlx5: Bridge, support LAG")
+Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
+Reviewed-by: Vlad Buslov <vladbu@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Link: https://patch.msgid.link/1741644104-97767-6-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/en/rep/bridge.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
+index 5d128c5b4529a..0f5d7ea8956f7 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
+@@ -48,15 +48,10 @@ mlx5_esw_bridge_lag_rep_get(struct net_device *dev, struct mlx5_eswitch *esw)
+ struct list_head *iter;
+
+ netdev_for_each_lower_dev(dev, lower, iter) {
+- struct mlx5_core_dev *mdev;
+- struct mlx5e_priv *priv;
+-
+ if (!mlx5e_eswitch_rep(lower))
+ continue;
+
+- priv = netdev_priv(lower);
+- mdev = priv->mdev;
+- if (mlx5_lag_is_shared_fdb(mdev) && mlx5_esw_bridge_dev_same_esw(lower, esw))
++ if (mlx5_esw_bridge_dev_same_esw(lower, esw))
+ return lower;
+ }
+
+@@ -125,7 +120,7 @@ static bool mlx5_esw_bridge_is_local(struct net_device *dev, struct net_device *
+ priv = netdev_priv(rep);
+ mdev = priv->mdev;
+ if (netif_is_lag_master(dev))
+- return mlx5_lag_is_shared_fdb(mdev) && mlx5_lag_is_master(mdev);
++ return mlx5_lag_is_master(mdev);
+ return true;
+ }
+
+@@ -455,6 +450,9 @@ static int mlx5_esw_bridge_switchdev_event(struct notifier_block *nb,
+ if (!rep)
+ return NOTIFY_DONE;
+
++ if (netif_is_lag_master(dev) && !mlx5_lag_is_shared_fdb(esw->dev))
++ return NOTIFY_DONE;
++
+ switch (event) {
+ case SWITCHDEV_FDB_ADD_TO_BRIDGE:
+ fdb_info = container_of(info,
+--
+2.39.5
+
--- /dev/null
+From aa559f58489f2f432843eb39fabc2e39d8ea8aa0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 23:25:29 +0200
+Subject: net/mlx5: Fill out devlink dev info only for PFs
+
+From: Jiri Pirko <jiri@nvidia.com>
+
+[ Upstream commit d749d901b2168389f060b654fdaa08acf6b367d2 ]
+
+Firmware version query is supported on the PFs. Due to this
+following kernel warning log is observed:
+
+[ 188.590344] mlx5_core 0000:08:00.2: mlx5_fw_version_query:816:(pid 1453): fw query isn't supported by the FW
+
+Fix it by restricting the query and devlink info to the PF.
+
+Fixes: 8338d9378895 ("net/mlx5: Added devlink info callback")
+Signed-off-by: Jiri Pirko <jiri@nvidia.com>
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Parav Pandit <parav@nvidia.com>
+Link: https://patch.msgid.link/20250306212529.429329-1-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/devlink.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 1bccb5633ab4b..f66788a2ed77e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -46,6 +46,9 @@ mlx5_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
+ u32 running_fw, stored_fw;
+ int err;
+
++ if (!mlx5_core_is_pf(dev))
++ return 0;
++
+ err = devlink_info_version_fixed_put(req, "fw.psid", dev->board_id);
+ if (err)
+ return err;
+--
+2.39.5
+
--- /dev/null
+From 4987c00185c6a6f9c5e11a8c910927b9a131a60d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Mar 2025 10:18:20 +0800
+Subject: net/mlx5: handle errors in mlx5_chains_create_table()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+[ Upstream commit eab0396353be1c778eba1c0b5180176f04dd21ce ]
+
+In mlx5_chains_create_table(), the return value of mlx5_get_fdb_sub_ns()
+and mlx5_get_flow_namespace() must be checked to prevent NULL pointer
+dereferences. If either function fails, the function should log error
+message with mlx5_core_warn() and return error pointer.
+
+Fixes: 39ac237ce009 ("net/mlx5: E-Switch, Refactor chains and priorities")
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20250307021820.2646-1-vulab@iscas.ac.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c
+index a80ecb672f33d..711d14dea2485 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c
+@@ -196,6 +196,11 @@ mlx5_chains_create_table(struct mlx5_fs_chains *chains,
+ ns = mlx5_get_flow_namespace(chains->dev, chains->ns);
+ }
+
++ if (!ns) {
++ mlx5_core_warn(chains->dev, "Failed to get flow namespace\n");
++ return ERR_PTR(-EOPNOTSUPP);
++ }
++
+ ft_attr.autogroup.num_reserved_entries = 2;
+ ft_attr.autogroup.max_num_groups = chains->group_num;
+ ft = mlx5_create_auto_grouped_flow_table(ns, &ft_attr);
+--
+2.39.5
+
--- /dev/null
+From e6a3d94e96c00cda3c01e93167dba07d91cfaa5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Mar 2025 00:01:42 +0200
+Subject: net/mlx5: Lag, Check shared fdb before creating MultiPort E-Switch
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit 32966984bee1defd9f5a8f9be274d7c32f911ba1 ]
+
+Currently, MultiPort E-Switch is requesting to create a LAG with shared
+FDB without checking the LAG is supporting shared FDB.
+Add the check.
+
+Fixes: a32327a3a02c ("net/mlx5: Lag, Control MultiPort E-Switch single FDB mode")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Mark Bloch <mbloch@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Link: https://patch.msgid.link/1741644104-97767-5-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c | 4 ++--
+ drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h | 1 +
+ drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c | 3 ++-
+ 3 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+index 18cf756bad8cc..f6b1ac80c0af9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+@@ -823,7 +823,7 @@ void mlx5_disable_lag(struct mlx5_lag *ldev)
+ mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
+ }
+
+-static bool mlx5_shared_fdb_supported(struct mlx5_lag *ldev)
++bool mlx5_lag_shared_fdb_supported(struct mlx5_lag *ldev)
+ {
+ struct mlx5_core_dev *dev;
+ int i;
+@@ -900,7 +900,7 @@ static void mlx5_do_bond(struct mlx5_lag *ldev)
+ }
+
+ if (do_bond && !__mlx5_lag_is_active(ldev)) {
+- bool shared_fdb = mlx5_shared_fdb_supported(ldev);
++ bool shared_fdb = mlx5_lag_shared_fdb_supported(ldev);
+
+ roce_lag = mlx5_lag_is_roce_lag(ldev);
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
+index 481e92f39fe61..b7ccf0e955f56 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
+@@ -92,6 +92,7 @@ mlx5_lag_is_ready(struct mlx5_lag *ldev)
+ return test_bit(MLX5_LAG_FLAG_NDEVS_READY, &ldev->state_flags);
+ }
+
++bool mlx5_lag_shared_fdb_supported(struct mlx5_lag *ldev);
+ bool mlx5_lag_check_prereq(struct mlx5_lag *ldev);
+ void mlx5_modify_lag(struct mlx5_lag *ldev,
+ struct lag_tracker *tracker);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
+index 6b0413a3987ce..8a07fdf295056 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
+@@ -81,7 +81,8 @@ static int enable_mpesw(struct mlx5_lag *ldev)
+ if (mlx5_eswitch_mode(dev0) != MLX5_ESWITCH_OFFLOADS ||
+ !MLX5_CAP_PORT_SELECTION(dev0, port_select_flow_table) ||
+ !MLX5_CAP_GEN(dev0, create_lag_when_not_master_up) ||
+- !mlx5_lag_check_prereq(ldev))
++ !mlx5_lag_check_prereq(ldev) ||
++ !mlx5_lag_shared_fdb_supported(ldev))
+ return -EOPNOTSUPP;
+
+ err = mlx5_mpesw_metadata_set(ldev);
+--
+2.39.5
+
--- /dev/null
+From d677c060a83b733dd3178ebe943c2f2039f53fc6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Mar 2025 00:01:44 +0200
+Subject: net/mlx5e: Prevent bridge link show failure for non-eswitch-allowed
+ devices
+
+From: Carolina Jubran <cjubran@nvidia.com>
+
+[ Upstream commit e92df790d07a8eea873efcb84776e7b71f81c7d5 ]
+
+mlx5_eswitch_get_vepa returns -EPERM if the device lacks
+eswitch_manager capability, blocking mlx5e_bridge_getlink from
+retrieving VEPA mode. Since mlx5e_bridge_getlink implements
+ndo_bridge_getlink, returning -EPERM causes bridge link show to fail
+instead of skipping devices without this capability.
+
+To avoid this, return -EOPNOTSUPP from mlx5e_bridge_getlink when
+mlx5_eswitch_get_vepa fails, ensuring the command continues processing
+other devices while ignoring those without the necessary capability.
+
+Fixes: 4b89251de024 ("net/mlx5: Support ndo bridge_setlink and getlink")
+Signed-off-by: Carolina Jubran <cjubran@nvidia.com>
+Reviewed-by: Jianbo Liu <jianbol@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Link: https://patch.msgid.link/1741644104-97767-7-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index b34f57ab9755c..8a892614015cd 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -4891,11 +4891,9 @@ static int mlx5e_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+ struct mlx5e_priv *priv = netdev_priv(dev);
+ struct mlx5_core_dev *mdev = priv->mdev;
+ u8 mode, setting;
+- int err;
+
+- err = mlx5_eswitch_get_vepa(mdev->priv.eswitch, &setting);
+- if (err)
+- return err;
++ if (mlx5_eswitch_get_vepa(mdev->priv.eswitch, &setting))
++ return -EOPNOTSUPP;
+ mode = setting ? BRIDGE_MODE_VEPA : BRIDGE_MODE_VEB;
+ return ndo_dflt_bridge_getlink(skb, pid, seq, dev,
+ mode,
+--
+2.39.5
+
--- /dev/null
+From 19bc928712a0d6c6fdc455e5964e579f332156a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Mar 2025 01:45:59 +0100
+Subject: net: openvswitch: remove misbehaving actions length check
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit a1e64addf3ff9257b45b78bc7d743781c3f41340 ]
+
+The actions length check is unreliable and produces different results
+depending on the initial length of the provided netlink attribute and
+the composition of the actual actions inside of it. For example, a
+user can add 4088 empty clone() actions without triggering -EMSGSIZE,
+on attempt to add 4089 such actions the operation will fail with the
+-EMSGSIZE verdict. However, if another 16 KB of other actions will
+be *appended* to the previous 4089 clone() actions, the check passes
+and the flow is successfully installed into the openvswitch datapath.
+
+The reason for a such a weird behavior is the way memory is allocated.
+When ovs_flow_cmd_new() is invoked, it calls ovs_nla_copy_actions(),
+that in turn calls nla_alloc_flow_actions() with either the actual
+length of the user-provided actions or the MAX_ACTIONS_BUFSIZE. The
+function adds the size of the sw_flow_actions structure and then the
+actually allocated memory is rounded up to the closest power of two.
+
+So, if the user-provided actions are larger than MAX_ACTIONS_BUFSIZE,
+then MAX_ACTIONS_BUFSIZE + sizeof(*sfa) rounded up is 32K + 24 -> 64K.
+Later, while copying individual actions, we look at ksize(), which is
+64K, so this way the MAX_ACTIONS_BUFSIZE check is not actually
+triggered and the user can easily allocate almost 64 KB of actions.
+
+However, when the initial size is less than MAX_ACTIONS_BUFSIZE, but
+the actions contain ones that require size increase while copying
+(such as clone() or sample()), then the limit check will be performed
+during the reserve_sfa_size() and the user will not be allowed to
+create actions that yield more than 32 KB internally.
+
+This is one part of the problem. The other part is that it's not
+actually possible for the userspace application to know beforehand
+if the particular set of actions will be rejected or not.
+
+Certain actions require more space in the internal representation,
+e.g. an empty clone() takes 4 bytes in the action list passed in by
+the user, but it takes 12 bytes in the internal representation due
+to an extra nested attribute, and some actions require less space in
+the internal representations, e.g. set(tunnel(..)) normally takes
+64+ bytes in the action list provided by the user, but only needs to
+store a single pointer in the internal implementation, since all the
+data is stored in the tunnel_info structure instead.
+
+And the action size limit is applied to the internal representation,
+not to the action list passed by the user. So, it's not possible for
+the userpsace application to predict if the certain combination of
+actions will be rejected or not, because it is not possible for it to
+calculate how much space these actions will take in the internal
+representation without knowing kernel internals.
+
+All that is causing random failures in ovs-vswitchd in userspace and
+inability to handle certain traffic patterns as a result. For example,
+it is reported that adding a bit more than a 1100 VMs in an OpenStack
+setup breaks the network due to OVS not being able to handle ARP
+traffic anymore in some cases (it tries to install a proper datapath
+flow, but the kernel rejects it with -EMSGSIZE, even though the action
+list isn't actually that large.)
+
+Kernel behavior must be consistent and predictable in order for the
+userspace application to use it in a reasonable way. ovs-vswitchd has
+a mechanism to re-direct parts of the traffic and partially handle it
+in userspace if the required action list is oversized, but that doesn't
+work properly if we can't actually tell if the action list is oversized
+or not.
+
+Solution for this is to check the size of the user-provided actions
+instead of the internal representation. This commit just removes the
+check from the internal part because there is already an implicit size
+check imposed by the netlink protocol. The attribute can't be larger
+than 64 KB. Realistically, we could reduce the limit to 32 KB, but
+we'll be risking to break some existing setups that rely on the fact
+that it's possible to create nearly 64 KB action lists today.
+
+Vast majority of flows in real setups are below 100-ish bytes. So
+removal of the limit will not change real memory consumption on the
+system. The absolutely worst case scenario is if someone adds a flow
+with 64 KB of empty clone() actions. That will yield a 192 KB in the
+internal representation consuming 256 KB block of memory. However,
+that list of actions is not meaningful and also a no-op. Real world
+very large action lists (that can occur for a rare cases of BUM
+traffic handling) are unlikely to contain a large number of clones and
+will likely have a lot of tunnel attributes making the internal
+representation comparable in size to the original action list.
+So, it should be fine to just remove the limit.
+
+Commit in the 'Fixes' tag is the first one that introduced the
+difference between internal representation and the user-provided action
+lists, but there were many more afterwards that lead to the situation
+we have today.
+
+Fixes: 7d5437c709de ("openvswitch: Add tunneling interface.")
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Link: https://patch.msgid.link/20250308004609.2881861-1-i.maximets@ovn.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/flow_netlink.c | 15 +--------------
+ 1 file changed, 1 insertion(+), 14 deletions(-)
+
+diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
+index ebc5728aab4ea..9c13e14034d3b 100644
+--- a/net/openvswitch/flow_netlink.c
++++ b/net/openvswitch/flow_netlink.c
+@@ -2304,14 +2304,10 @@ int ovs_nla_put_mask(const struct sw_flow *flow, struct sk_buff *skb)
+ OVS_FLOW_ATTR_MASK, true, skb);
+ }
+
+-#define MAX_ACTIONS_BUFSIZE (32 * 1024)
+-
+ static struct sw_flow_actions *nla_alloc_flow_actions(int size)
+ {
+ struct sw_flow_actions *sfa;
+
+- WARN_ON_ONCE(size > MAX_ACTIONS_BUFSIZE);
+-
+ sfa = kmalloc(kmalloc_size_roundup(sizeof(*sfa) + size), GFP_KERNEL);
+ if (!sfa)
+ return ERR_PTR(-ENOMEM);
+@@ -2467,15 +2463,6 @@ static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa,
+
+ new_acts_size = max(next_offset + req_size, ksize(*sfa) * 2);
+
+- if (new_acts_size > MAX_ACTIONS_BUFSIZE) {
+- if ((next_offset + req_size) > MAX_ACTIONS_BUFSIZE) {
+- OVS_NLERR(log, "Flow action size exceeds max %u",
+- MAX_ACTIONS_BUFSIZE);
+- return ERR_PTR(-EMSGSIZE);
+- }
+- new_acts_size = MAX_ACTIONS_BUFSIZE;
+- }
+-
+ acts = nla_alloc_flow_actions(new_acts_size);
+ if (IS_ERR(acts))
+ return (void *)acts;
+@@ -3502,7 +3489,7 @@ int ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
+ int err;
+ u32 mpls_label_count = 0;
+
+- *sfa = nla_alloc_flow_actions(min(nla_len(attr), MAX_ACTIONS_BUFSIZE));
++ *sfa = nla_alloc_flow_actions(nla_len(attr));
+ if (IS_ERR(*sfa))
+ return PTR_ERR(*sfa);
+
+--
+2.39.5
+
--- /dev/null
+From 462da714f89c77bf5bae583571147a3fa08f9d65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Mar 2025 14:15:09 +0200
+Subject: net: switchdev: Convert blocking notification chain to a raw one
+
+From: Amit Cohen <amcohen@nvidia.com>
+
+[ Upstream commit 62531a1effa87bdab12d5104015af72e60d926ff ]
+
+A blocking notification chain uses a read-write semaphore to protect the
+integrity of the chain. The semaphore is acquired for writing when
+adding / removing notifiers to / from the chain and acquired for reading
+when traversing the chain and informing notifiers about an event.
+
+In case of the blocking switchdev notification chain, recursive
+notifications are possible which leads to the semaphore being acquired
+twice for reading and to lockdep warnings being generated [1].
+
+Specifically, this can happen when the bridge driver processes a
+SWITCHDEV_BRPORT_UNOFFLOADED event which causes it to emit notifications
+about deferred events when calling switchdev_deferred_process().
+
+Fix this by converting the notification chain to a raw notification
+chain in a similar fashion to the netdev notification chain. Protect
+the chain using the RTNL mutex by acquiring it when modifying the chain.
+Events are always informed under the RTNL mutex, but add an assertion in
+call_switchdev_blocking_notifiers() to make sure this is not violated in
+the future.
+
+Maintain the "blocking" prefix as events are always emitted from process
+context and listeners are allowed to block.
+
+[1]:
+WARNING: possible recursive locking detected
+6.14.0-rc4-custom-g079270089484 #1 Not tainted
+--------------------------------------------
+ip/52731 is trying to acquire lock:
+ffffffff850918d8 ((switchdev_blocking_notif_chain).rwsem){++++}-{4:4}, at: blocking_notifier_call_chain+0x58/0xa0
+
+but task is already holding lock:
+ffffffff850918d8 ((switchdev_blocking_notif_chain).rwsem){++++}-{4:4}, at: blocking_notifier_call_chain+0x58/0xa0
+
+other info that might help us debug this:
+Possible unsafe locking scenario:
+CPU0
+----
+lock((switchdev_blocking_notif_chain).rwsem);
+lock((switchdev_blocking_notif_chain).rwsem);
+
+*** DEADLOCK ***
+May be due to missing lock nesting notation
+3 locks held by ip/52731:
+ #0: ffffffff84f795b0 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_newlink+0x727/0x1dc0
+ #1: ffffffff8731f628 (&net->rtnl_mutex){+.+.}-{4:4}, at: rtnl_newlink+0x790/0x1dc0
+ #2: ffffffff850918d8 ((switchdev_blocking_notif_chain).rwsem){++++}-{4:4}, at: blocking_notifier_call_chain+0x58/0xa0
+
+stack backtrace:
+...
+? __pfx_down_read+0x10/0x10
+? __pfx_mark_lock+0x10/0x10
+? __pfx_switchdev_port_attr_set_deferred+0x10/0x10
+blocking_notifier_call_chain+0x58/0xa0
+switchdev_port_attr_notify.constprop.0+0xb3/0x1b0
+? __pfx_switchdev_port_attr_notify.constprop.0+0x10/0x10
+? mark_held_locks+0x94/0xe0
+? switchdev_deferred_process+0x11a/0x340
+switchdev_port_attr_set_deferred+0x27/0xd0
+switchdev_deferred_process+0x164/0x340
+br_switchdev_port_unoffload+0xc8/0x100 [bridge]
+br_switchdev_blocking_event+0x29f/0x580 [bridge]
+notifier_call_chain+0xa2/0x440
+blocking_notifier_call_chain+0x6e/0xa0
+switchdev_bridge_port_unoffload+0xde/0x1a0
+...
+
+Fixes: f7a70d650b0b6 ("net: bridge: switchdev: Ensure deferred event delivery on unoffload")
+Signed-off-by: Amit Cohen <amcohen@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Tested-by: Vladimir Oltean <olteanv@gmail.com>
+Link: https://patch.msgid.link/20250305121509.631207-1-amcohen@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/switchdev/switchdev.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
+index c9189a970eec3..fb0e65c89525d 100644
+--- a/net/switchdev/switchdev.c
++++ b/net/switchdev/switchdev.c
+@@ -381,7 +381,7 @@ bool switchdev_port_obj_act_is_deferred(struct net_device *dev,
+ EXPORT_SYMBOL_GPL(switchdev_port_obj_act_is_deferred);
+
+ static ATOMIC_NOTIFIER_HEAD(switchdev_notif_chain);
+-static BLOCKING_NOTIFIER_HEAD(switchdev_blocking_notif_chain);
++static RAW_NOTIFIER_HEAD(switchdev_blocking_notif_chain);
+
+ /**
+ * register_switchdev_notifier - Register notifier
+@@ -427,17 +427,27 @@ EXPORT_SYMBOL_GPL(call_switchdev_notifiers);
+
+ int register_switchdev_blocking_notifier(struct notifier_block *nb)
+ {
+- struct blocking_notifier_head *chain = &switchdev_blocking_notif_chain;
++ struct raw_notifier_head *chain = &switchdev_blocking_notif_chain;
++ int err;
++
++ rtnl_lock();
++ err = raw_notifier_chain_register(chain, nb);
++ rtnl_unlock();
+
+- return blocking_notifier_chain_register(chain, nb);
++ return err;
+ }
+ EXPORT_SYMBOL_GPL(register_switchdev_blocking_notifier);
+
+ int unregister_switchdev_blocking_notifier(struct notifier_block *nb)
+ {
+- struct blocking_notifier_head *chain = &switchdev_blocking_notif_chain;
++ struct raw_notifier_head *chain = &switchdev_blocking_notif_chain;
++ int err;
+
+- return blocking_notifier_chain_unregister(chain, nb);
++ rtnl_lock();
++ err = raw_notifier_chain_unregister(chain, nb);
++ rtnl_unlock();
++
++ return err;
+ }
+ EXPORT_SYMBOL_GPL(unregister_switchdev_blocking_notifier);
+
+@@ -445,10 +455,11 @@ int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev,
+ struct switchdev_notifier_info *info,
+ struct netlink_ext_ack *extack)
+ {
++ ASSERT_RTNL();
+ info->dev = dev;
+ info->extack = extack;
+- return blocking_notifier_call_chain(&switchdev_blocking_notif_chain,
+- val, info);
++ return raw_notifier_call_chain(&switchdev_blocking_notif_chain,
++ val, info);
+ }
+ EXPORT_SYMBOL_GPL(call_switchdev_blocking_notifiers);
+
+--
+2.39.5
+
--- /dev/null
+From 230608fd795f8660a01583e24333dc5aa11497c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 15:23:54 -0800
+Subject: net_sched: Prevent creation of classes with TC_H_ROOT
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+[ Upstream commit 0c3057a5a04d07120b3d0ec9c79568fceb9c921e ]
+
+The function qdisc_tree_reduce_backlog() uses TC_H_ROOT as a termination
+condition when traversing up the qdisc tree to update parent backlog
+counters. However, if a class is created with classid TC_H_ROOT, the
+traversal terminates prematurely at this class instead of reaching the
+actual root qdisc, causing parent statistics to be incorrectly maintained.
+In case of DRR, this could lead to a crash as reported by Mingi Cho.
+
+Prevent the creation of any Qdisc class with classid TC_H_ROOT
+(0xFFFFFFFF) across all qdisc types, as suggested by Jamal.
+
+Reported-by: Mingi Cho <mincho@theori.io>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Fixes: 066a3b5b2346 ("[NET_SCHED] sch_api: fix qdisc_tree_decrease_qlen() loop")
+Link: https://patch.msgid.link/20250306232355.93864-2-xiyou.wangcong@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_api.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
+index 7cddaa6321c7c..df89790c459ad 100644
+--- a/net/sched/sch_api.c
++++ b/net/sched/sch_api.c
+@@ -2197,6 +2197,12 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n,
+ return -EOPNOTSUPP;
+ }
+
++ /* Prevent creation of traffic classes with classid TC_H_ROOT */
++ if (clid == TC_H_ROOT) {
++ NL_SET_ERR_MSG(extack, "Cannot create traffic class with classid TC_H_ROOT");
++ return -EINVAL;
++ }
++
+ new_cl = cl;
+ err = -EOPNOTSUPP;
+ if (cops->change)
+--
+2.39.5
+
--- /dev/null
+From 4a34dd3a5d391555422d29f1298e8bddd4088716 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Mar 2025 17:07:38 +0900
+Subject: netfilter: nf_conncount: Fully initialize struct nf_conncount_tuple
+ in insert_tree()
+
+From: Kohei Enju <enjuk@amazon.com>
+
+[ Upstream commit d653bfeb07ebb3499c403404c21ac58a16531607 ]
+
+Since commit b36e4523d4d5 ("netfilter: nf_conncount: fix garbage
+collection confirm race"), `cpu` and `jiffies32` were introduced to
+the struct nf_conncount_tuple.
+
+The commit made nf_conncount_add() initialize `conn->cpu` and
+`conn->jiffies32` when allocating the struct.
+In contrast, count_tree() was not changed to initialize them.
+
+By commit 34848d5c896e ("netfilter: nf_conncount: Split insert and
+traversal"), count_tree() was split and the relevant allocation
+code now resides in insert_tree().
+Initialize `conn->cpu` and `conn->jiffies32` in insert_tree().
+
+BUG: KMSAN: uninit-value in find_or_evict net/netfilter/nf_conncount.c:117 [inline]
+BUG: KMSAN: uninit-value in __nf_conncount_add+0xd9c/0x2850 net/netfilter/nf_conncount.c:143
+ find_or_evict net/netfilter/nf_conncount.c:117 [inline]
+ __nf_conncount_add+0xd9c/0x2850 net/netfilter/nf_conncount.c:143
+ count_tree net/netfilter/nf_conncount.c:438 [inline]
+ nf_conncount_count+0x82f/0x1e80 net/netfilter/nf_conncount.c:521
+ connlimit_mt+0x7f6/0xbd0 net/netfilter/xt_connlimit.c:72
+ __nft_match_eval net/netfilter/nft_compat.c:403 [inline]
+ nft_match_eval+0x1a5/0x300 net/netfilter/nft_compat.c:433
+ expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline]
+ nft_do_chain+0x426/0x2290 net/netfilter/nf_tables_core.c:288
+ nft_do_chain_ipv4+0x1a5/0x230 net/netfilter/nft_chain_filter.c:23
+ nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline]
+ nf_hook_slow+0xf4/0x400 net/netfilter/core.c:626
+ nf_hook_slow_list+0x24d/0x860 net/netfilter/core.c:663
+ NF_HOOK_LIST include/linux/netfilter.h:350 [inline]
+ ip_sublist_rcv+0x17b7/0x17f0 net/ipv4/ip_input.c:633
+ ip_list_rcv+0x9ef/0xa40 net/ipv4/ip_input.c:669
+ __netif_receive_skb_list_ptype net/core/dev.c:5936 [inline]
+ __netif_receive_skb_list_core+0x15c5/0x1670 net/core/dev.c:5983
+ __netif_receive_skb_list net/core/dev.c:6035 [inline]
+ netif_receive_skb_list_internal+0x1085/0x1700 net/core/dev.c:6126
+ netif_receive_skb_list+0x5a/0x460 net/core/dev.c:6178
+ xdp_recv_frames net/bpf/test_run.c:280 [inline]
+ xdp_test_run_batch net/bpf/test_run.c:361 [inline]
+ bpf_test_run_xdp_live+0x2e86/0x3480 net/bpf/test_run.c:390
+ bpf_prog_test_run_xdp+0xf1d/0x1ae0 net/bpf/test_run.c:1316
+ bpf_prog_test_run+0x5e5/0xa30 kernel/bpf/syscall.c:4407
+ __sys_bpf+0x6aa/0xd90 kernel/bpf/syscall.c:5813
+ __do_sys_bpf kernel/bpf/syscall.c:5902 [inline]
+ __se_sys_bpf kernel/bpf/syscall.c:5900 [inline]
+ __ia32_sys_bpf+0xa0/0xe0 kernel/bpf/syscall.c:5900
+ ia32_sys_call+0x394d/0x4180 arch/x86/include/generated/asm/syscalls_32.h:358
+ do_syscall_32_irqs_on arch/x86/entry/common.c:165 [inline]
+ __do_fast_syscall_32+0xb0/0x110 arch/x86/entry/common.c:387
+ do_fast_syscall_32+0x38/0x80 arch/x86/entry/common.c:412
+ do_SYSENTER_32+0x1f/0x30 arch/x86/entry/common.c:450
+ entry_SYSENTER_compat_after_hwframe+0x84/0x8e
+
+Uninit was created at:
+ slab_post_alloc_hook mm/slub.c:4121 [inline]
+ slab_alloc_node mm/slub.c:4164 [inline]
+ kmem_cache_alloc_noprof+0x915/0xe10 mm/slub.c:4171
+ insert_tree net/netfilter/nf_conncount.c:372 [inline]
+ count_tree net/netfilter/nf_conncount.c:450 [inline]
+ nf_conncount_count+0x1415/0x1e80 net/netfilter/nf_conncount.c:521
+ connlimit_mt+0x7f6/0xbd0 net/netfilter/xt_connlimit.c:72
+ __nft_match_eval net/netfilter/nft_compat.c:403 [inline]
+ nft_match_eval+0x1a5/0x300 net/netfilter/nft_compat.c:433
+ expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline]
+ nft_do_chain+0x426/0x2290 net/netfilter/nf_tables_core.c:288
+ nft_do_chain_ipv4+0x1a5/0x230 net/netfilter/nft_chain_filter.c:23
+ nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline]
+ nf_hook_slow+0xf4/0x400 net/netfilter/core.c:626
+ nf_hook_slow_list+0x24d/0x860 net/netfilter/core.c:663
+ NF_HOOK_LIST include/linux/netfilter.h:350 [inline]
+ ip_sublist_rcv+0x17b7/0x17f0 net/ipv4/ip_input.c:633
+ ip_list_rcv+0x9ef/0xa40 net/ipv4/ip_input.c:669
+ __netif_receive_skb_list_ptype net/core/dev.c:5936 [inline]
+ __netif_receive_skb_list_core+0x15c5/0x1670 net/core/dev.c:5983
+ __netif_receive_skb_list net/core/dev.c:6035 [inline]
+ netif_receive_skb_list_internal+0x1085/0x1700 net/core/dev.c:6126
+ netif_receive_skb_list+0x5a/0x460 net/core/dev.c:6178
+ xdp_recv_frames net/bpf/test_run.c:280 [inline]
+ xdp_test_run_batch net/bpf/test_run.c:361 [inline]
+ bpf_test_run_xdp_live+0x2e86/0x3480 net/bpf/test_run.c:390
+ bpf_prog_test_run_xdp+0xf1d/0x1ae0 net/bpf/test_run.c:1316
+ bpf_prog_test_run+0x5e5/0xa30 kernel/bpf/syscall.c:4407
+ __sys_bpf+0x6aa/0xd90 kernel/bpf/syscall.c:5813
+ __do_sys_bpf kernel/bpf/syscall.c:5902 [inline]
+ __se_sys_bpf kernel/bpf/syscall.c:5900 [inline]
+ __ia32_sys_bpf+0xa0/0xe0 kernel/bpf/syscall.c:5900
+ ia32_sys_call+0x394d/0x4180 arch/x86/include/generated/asm/syscalls_32.h:358
+ do_syscall_32_irqs_on arch/x86/entry/common.c:165 [inline]
+ __do_fast_syscall_32+0xb0/0x110 arch/x86/entry/common.c:387
+ do_fast_syscall_32+0x38/0x80 arch/x86/entry/common.c:412
+ do_SYSENTER_32+0x1f/0x30 arch/x86/entry/common.c:450
+ entry_SYSENTER_compat_after_hwframe+0x84/0x8e
+
+Reported-by: syzbot+83fed965338b573115f7@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=83fed965338b573115f7
+Fixes: b36e4523d4d5 ("netfilter: nf_conncount: fix garbage collection confirm race")
+Signed-off-by: Kohei Enju <enjuk@amazon.com>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conncount.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
+index 71869ad466467..6156c0751056c 100644
+--- a/net/netfilter/nf_conncount.c
++++ b/net/netfilter/nf_conncount.c
+@@ -377,6 +377,8 @@ insert_tree(struct net *net,
+
+ conn->tuple = *tuple;
+ conn->zone = *zone;
++ conn->cpu = raw_smp_processor_id();
++ conn->jiffies32 = (u32)jiffies;
+ memcpy(rbconn->key, key, sizeof(u32) * data->keylen);
+
+ nf_conncount_list_init(&rbconn->list);
+--
+2.39.5
+
--- /dev/null
+From 5c2086488729f6ae58409659e56d507e065844d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 13:32:34 +0000
+Subject: netfilter: nf_conncount: garbage collection is not skipped when
+ jiffies wrap around
+
+From: Nicklas Bo Jensen <njensen@akamai.com>
+
+[ Upstream commit df08c94baafb001de6cf44bb7098bb557f36c335 ]
+
+nf_conncount is supposed to skip garbage collection if it has already
+run garbage collection in the same jiffy. Unfortunately, this is broken
+when jiffies wrap around which this patch fixes.
+
+The problem is that last_gc in the nf_conncount_list struct is an u32,
+but jiffies is an unsigned long which is 8 bytes on my systems. When
+those two are compared it only works until last_gc wraps around.
+
+See bug report: https://bugzilla.netfilter.org/show_bug.cgi?id=1778
+for more details.
+
+Fixes: d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC")
+Signed-off-by: Nicklas Bo Jensen <njensen@akamai.com>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conncount.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
+index 5885810da412f..71869ad466467 100644
+--- a/net/netfilter/nf_conncount.c
++++ b/net/netfilter/nf_conncount.c
+@@ -132,7 +132,7 @@ static int __nf_conncount_add(struct net *net,
+ struct nf_conn *found_ct;
+ unsigned int collect = 0;
+
+- if (time_is_after_eq_jiffies((unsigned long)list->last_gc))
++ if ((u32)jiffies == list->last_gc)
+ goto add_new_node;
+
+ /* check the saved connections */
+@@ -234,7 +234,7 @@ bool nf_conncount_gc_list(struct net *net,
+ bool ret = false;
+
+ /* don't bother if we just did GC */
+- if (time_is_after_eq_jiffies((unsigned long)READ_ONCE(list->last_gc)))
++ if ((u32)jiffies == READ_ONCE(list->last_gc))
+ return false;
+
+ /* don't bother if other cpu is already doing GC */
+--
+2.39.5
+
--- /dev/null
+From 552205e685ca05ffb8296f1f8567fb43bdaedd0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 17:02:42 +0100
+Subject: netfilter: nft_ct: Use __refcount_inc() for per-CPU
+ nft_ct_pcpu_template.
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit 5cfe5612ca9590db69b9be29dc83041dbf001108 ]
+
+nft_ct_pcpu_template is a per-CPU variable and relies on disabled BH for its
+locking. The refcounter is read and if its value is set to one then the
+refcounter is incremented and variable is used - otherwise it is already
+in use and left untouched.
+
+Without per-CPU locking in local_bh_disable() on PREEMPT_RT the
+read-then-increment operation is not atomic and therefore racy.
+
+This can be avoided by using unconditionally __refcount_inc() which will
+increment counter and return the old value as an atomic operation.
+In case the returned counter is not one, the variable is in use and we
+need to decrement counter. Otherwise we can use it.
+
+Use __refcount_inc() instead of read and a conditional increment.
+
+Fixes: edee4f1e9245 ("netfilter: nft_ct: add zone id set support")
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_ct.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
+index 255640013ab84..ab1214da99ff3 100644
+--- a/net/netfilter/nft_ct.c
++++ b/net/netfilter/nft_ct.c
+@@ -230,6 +230,7 @@ static void nft_ct_set_zone_eval(const struct nft_expr *expr,
+ enum ip_conntrack_info ctinfo;
+ u16 value = nft_reg_load16(®s->data[priv->sreg]);
+ struct nf_conn *ct;
++ int oldcnt;
+
+ ct = nf_ct_get(skb, &ctinfo);
+ if (ct) /* already tracked */
+@@ -250,10 +251,11 @@ static void nft_ct_set_zone_eval(const struct nft_expr *expr,
+
+ ct = this_cpu_read(nft_ct_pcpu_template);
+
+- if (likely(refcount_read(&ct->ct_general.use) == 1)) {
+- refcount_inc(&ct->ct_general.use);
++ __refcount_inc(&ct->ct_general.use, &oldcnt);
++ if (likely(oldcnt == 1)) {
+ nf_ct_zone_add(ct, &zone);
+ } else {
++ refcount_dec(&ct->ct_general.use);
+ /* previous skb got queued to userspace, allocate temporary
+ * one until percpu template can be reused.
+ */
+--
+2.39.5
+
--- /dev/null
+From e04944a7b0655f71f2ef278c0812b41a77c4a285 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Mar 2025 00:14:36 +0300
+Subject: netfilter: nft_exthdr: fix offset with ipv4_find_option()
+
+From: Alexey Kashavkin <akashavkin@gmail.com>
+
+[ Upstream commit 6edd78af9506bb182518da7f6feebd75655d9a0e ]
+
+There is an incorrect calculation in the offset variable which causes
+the nft_skb_copy_to_reg() function to always return -EFAULT. Adding the
+start variable is redundant. In the __ip_options_compile() function the
+correct offset is specified when finding the function. There is no need
+to add the size of the iphdr structure to the offset.
+
+Fixes: dbb5281a1f84 ("netfilter: nf_tables: add support for matching IPv4 options")
+Signed-off-by: Alexey Kashavkin <akashavkin@gmail.com>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_exthdr.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
+index 6eb571d0c3fdf..cfa90ab660cfe 100644
+--- a/net/netfilter/nft_exthdr.c
++++ b/net/netfilter/nft_exthdr.c
+@@ -85,7 +85,6 @@ static int ipv4_find_option(struct net *net, struct sk_buff *skb,
+ unsigned char optbuf[sizeof(struct ip_options) + 40];
+ struct ip_options *opt = (struct ip_options *)optbuf;
+ struct iphdr *iph, _iph;
+- unsigned int start;
+ bool found = false;
+ __be32 info;
+ int optlen;
+@@ -93,7 +92,6 @@ static int ipv4_find_option(struct net *net, struct sk_buff *skb,
+ iph = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
+ if (!iph)
+ return -EBADMSG;
+- start = sizeof(struct iphdr);
+
+ optlen = iph->ihl * 4 - (int)sizeof(struct iphdr);
+ if (optlen <= 0)
+@@ -103,7 +101,7 @@ static int ipv4_find_option(struct net *net, struct sk_buff *skb,
+ /* Copy the options since __ip_options_compile() modifies
+ * the options.
+ */
+- if (skb_copy_bits(skb, start, opt->__data, optlen))
++ if (skb_copy_bits(skb, sizeof(struct iphdr), opt->__data, optlen))
+ return -EBADMSG;
+ opt->optlen = optlen;
+
+@@ -118,18 +116,18 @@ static int ipv4_find_option(struct net *net, struct sk_buff *skb,
+ found = target == IPOPT_SSRR ? opt->is_strictroute :
+ !opt->is_strictroute;
+ if (found)
+- *offset = opt->srr + start;
++ *offset = opt->srr;
+ break;
+ case IPOPT_RR:
+ if (!opt->rr)
+ break;
+- *offset = opt->rr + start;
++ *offset = opt->rr;
+ found = true;
+ break;
+ case IPOPT_RA:
+ if (!opt->router_alert)
+ break;
+- *offset = opt->router_alert + start;
++ *offset = opt->router_alert;
+ found = true;
+ break;
+ default:
+--
+2.39.5
+
--- /dev/null
+From eb954e034f8b4fba046c20d1dfacf2847241f19a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 05:16:18 -0800
+Subject: netpoll: hold rcu read lock in __netpoll_send_skb()
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 505ead7ab77f289f12d8a68ac83da068e4d4408b ]
+
+The function __netpoll_send_skb() is being invoked without holding the
+RCU read lock. This oversight triggers a warning message when
+CONFIG_PROVE_RCU_LIST is enabled:
+
+ net/core/netpoll.c:330 suspicious rcu_dereference_check() usage!
+
+ netpoll_send_skb
+ netpoll_send_udp
+ write_ext_msg
+ console_flush_all
+ console_unlock
+ vprintk_emit
+
+To prevent npinfo from disappearing unexpectedly, ensure that
+__netpoll_send_skb() is protected with the RCU read lock.
+
+Fixes: 2899656b494dcd1 ("netpoll: take rcu_read_lock_bh() in netpoll_send_skb_on_dev()")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250306-netpoll_rcu_v2-v2-1-bc4f5c51742a@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/netpoll.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/net/core/netpoll.c b/net/core/netpoll.c
+index 1791462f1600a..1a4d2a61b060b 100644
+--- a/net/core/netpoll.c
++++ b/net/core/netpoll.c
+@@ -326,6 +326,7 @@ static int netpoll_owner_active(struct net_device *dev)
+ static netdev_tx_t __netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
+ {
+ netdev_tx_t status = NETDEV_TX_BUSY;
++ netdev_tx_t ret = NET_XMIT_DROP;
+ struct net_device *dev;
+ unsigned long tries;
+ /* It is up to the caller to keep npinfo alive. */
+@@ -334,11 +335,12 @@ static netdev_tx_t __netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
+ lockdep_assert_irqs_disabled();
+
+ dev = np->dev;
++ rcu_read_lock();
+ npinfo = rcu_dereference_bh(dev->npinfo);
+
+ if (!npinfo || !netif_running(dev) || !netif_device_present(dev)) {
+ dev_kfree_skb_irq(skb);
+- return NET_XMIT_DROP;
++ goto out;
+ }
+
+ /* don't get messages out of order, and no recursion */
+@@ -377,7 +379,10 @@ static netdev_tx_t __netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
+ skb_queue_tail(&npinfo->txq, skb);
+ schedule_delayed_work(&npinfo->tx_work,0);
+ }
+- return NETDEV_TX_OK;
++ ret = NETDEV_TX_OK;
++out:
++ rcu_read_unlock();
++ return ret;
+ }
+
+ netdev_tx_t netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
+--
+2.39.5
+
--- /dev/null
+From 2a6e66cbdf9233f7fe57645eacbd74d72ec16df0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Feb 2025 21:02:41 +0100
+Subject: pinctrl: bcm281xx: Fix incorrect regmap max_registers value
+
+From: Artur Weber <aweber.kernel@gmail.com>
+
+[ Upstream commit 68283c1cb573143c0b7515e93206f3503616bc10 ]
+
+The max_registers value does not take into consideration the stride;
+currently, it's set to the number of the last pin, but this does not
+accurately represent the final register.
+
+Fix this by multiplying the current value by 4.
+
+Fixes: 54b1aa5a5b16 ("ARM: pinctrl: Add Broadcom Capri pinctrl driver")
+Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
+Link: https://lore.kernel.org/20250207-bcm21664-pinctrl-v1-2-e7cfac9b2d3b@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/bcm/pinctrl-bcm281xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c
+index 73dbf29c002f3..cf6efa9c0364a 100644
+--- a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c
++++ b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c
+@@ -974,7 +974,7 @@ static const struct regmap_config bcm281xx_pinctrl_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+- .max_register = BCM281XX_PIN_VC_CAM3_SDA,
++ .max_register = BCM281XX_PIN_VC_CAM3_SDA * 4,
+ };
+
+ static int bcm281xx_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+--
+2.39.5
+
--- /dev/null
+From 49c818867feb8a7b88c8e57e8aeb817110c7a302 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 10:06:10 -0500
+Subject: Revert "Bluetooth: hci_core: Fix sleeping function called from
+ invalid context"
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit ab6ab707a4d060a51c45fc13e3b2228d5f7c0b87 ]
+
+This reverts commit 4d94f05558271654670d18c26c912da0c1c15549 which has
+problems (see [1]) and is no longer needed since 581dd2dc168f
+("Bluetooth: hci_event: Fix using rcu_read_(un)lock while iterating")
+has reworked the code where the original bug has been found.
+
+[1] Link: https://lore.kernel.org/linux-bluetooth/877c55ci1r.wl-tiwai@suse.de/T/#t
+Fixes: 4d94f0555827 ("Bluetooth: hci_core: Fix sleeping function called from invalid context")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 108 +++++++++++--------------------
+ net/bluetooth/hci_core.c | 10 ++-
+ net/bluetooth/iso.c | 6 --
+ net/bluetooth/l2cap_core.c | 12 ++--
+ net/bluetooth/rfcomm/core.c | 6 --
+ net/bluetooth/sco.c | 12 ++--
+ 6 files changed, 57 insertions(+), 97 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 4fcee6b734b74..e9214ccfde2d7 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -800,6 +800,7 @@ struct hci_conn_params {
+ extern struct list_head hci_dev_list;
+ extern struct list_head hci_cb_list;
+ extern rwlock_t hci_dev_list_lock;
++extern struct mutex hci_cb_list_lock;
+
+ #define hci_dev_set_flag(hdev, nr) set_bit((nr), (hdev)->dev_flags)
+ #define hci_dev_clear_flag(hdev, nr) clear_bit((nr), (hdev)->dev_flags)
+@@ -1948,47 +1949,24 @@ struct hci_cb {
+
+ char *name;
+
+- bool (*match) (struct hci_conn *conn);
+ void (*connect_cfm) (struct hci_conn *conn, __u8 status);
+ void (*disconn_cfm) (struct hci_conn *conn, __u8 status);
+ void (*security_cfm) (struct hci_conn *conn, __u8 status,
+- __u8 encrypt);
++ __u8 encrypt);
+ void (*key_change_cfm) (struct hci_conn *conn, __u8 status);
+ void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role);
+ };
+
+-static inline void hci_cb_lookup(struct hci_conn *conn, struct list_head *list)
+-{
+- struct hci_cb *cb, *cpy;
+-
+- rcu_read_lock();
+- list_for_each_entry_rcu(cb, &hci_cb_list, list) {
+- if (cb->match && cb->match(conn)) {
+- cpy = kmalloc(sizeof(*cpy), GFP_ATOMIC);
+- if (!cpy)
+- break;
+-
+- *cpy = *cb;
+- INIT_LIST_HEAD(&cpy->list);
+- list_add_rcu(&cpy->list, list);
+- }
+- }
+- rcu_read_unlock();
+-}
+-
+ static inline void hci_connect_cfm(struct hci_conn *conn, __u8 status)
+ {
+- struct list_head list;
+- struct hci_cb *cb, *tmp;
+-
+- INIT_LIST_HEAD(&list);
+- hci_cb_lookup(conn, &list);
++ struct hci_cb *cb;
+
+- list_for_each_entry_safe(cb, tmp, &list, list) {
++ mutex_lock(&hci_cb_list_lock);
++ list_for_each_entry(cb, &hci_cb_list, list) {
+ if (cb->connect_cfm)
+ cb->connect_cfm(conn, status);
+- kfree(cb);
+ }
++ mutex_unlock(&hci_cb_list_lock);
+
+ if (conn->connect_cfm_cb)
+ conn->connect_cfm_cb(conn, status);
+@@ -1996,43 +1974,22 @@ static inline void hci_connect_cfm(struct hci_conn *conn, __u8 status)
+
+ static inline void hci_disconn_cfm(struct hci_conn *conn, __u8 reason)
+ {
+- struct list_head list;
+- struct hci_cb *cb, *tmp;
+-
+- INIT_LIST_HEAD(&list);
+- hci_cb_lookup(conn, &list);
++ struct hci_cb *cb;
+
+- list_for_each_entry_safe(cb, tmp, &list, list) {
++ mutex_lock(&hci_cb_list_lock);
++ list_for_each_entry(cb, &hci_cb_list, list) {
+ if (cb->disconn_cfm)
+ cb->disconn_cfm(conn, reason);
+- kfree(cb);
+ }
++ mutex_unlock(&hci_cb_list_lock);
+
+ if (conn->disconn_cfm_cb)
+ conn->disconn_cfm_cb(conn, reason);
+ }
+
+-static inline void hci_security_cfm(struct hci_conn *conn, __u8 status,
+- __u8 encrypt)
+-{
+- struct list_head list;
+- struct hci_cb *cb, *tmp;
+-
+- INIT_LIST_HEAD(&list);
+- hci_cb_lookup(conn, &list);
+-
+- list_for_each_entry_safe(cb, tmp, &list, list) {
+- if (cb->security_cfm)
+- cb->security_cfm(conn, status, encrypt);
+- kfree(cb);
+- }
+-
+- if (conn->security_cfm_cb)
+- conn->security_cfm_cb(conn, status);
+-}
+-
+ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
+ {
++ struct hci_cb *cb;
+ __u8 encrypt;
+
+ if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
+@@ -2040,11 +1997,20 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
+
+ encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00;
+
+- hci_security_cfm(conn, status, encrypt);
++ mutex_lock(&hci_cb_list_lock);
++ list_for_each_entry(cb, &hci_cb_list, list) {
++ if (cb->security_cfm)
++ cb->security_cfm(conn, status, encrypt);
++ }
++ mutex_unlock(&hci_cb_list_lock);
++
++ if (conn->security_cfm_cb)
++ conn->security_cfm_cb(conn, status);
+ }
+
+ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
+ {
++ struct hci_cb *cb;
+ __u8 encrypt;
+
+ if (conn->state == BT_CONFIG) {
+@@ -2071,38 +2037,40 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
+ conn->sec_level = conn->pending_sec_level;
+ }
+
+- hci_security_cfm(conn, status, encrypt);
++ mutex_lock(&hci_cb_list_lock);
++ list_for_each_entry(cb, &hci_cb_list, list) {
++ if (cb->security_cfm)
++ cb->security_cfm(conn, status, encrypt);
++ }
++ mutex_unlock(&hci_cb_list_lock);
++
++ if (conn->security_cfm_cb)
++ conn->security_cfm_cb(conn, status);
+ }
+
+ static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status)
+ {
+- struct list_head list;
+- struct hci_cb *cb, *tmp;
+-
+- INIT_LIST_HEAD(&list);
+- hci_cb_lookup(conn, &list);
++ struct hci_cb *cb;
+
+- list_for_each_entry_safe(cb, tmp, &list, list) {
++ mutex_lock(&hci_cb_list_lock);
++ list_for_each_entry(cb, &hci_cb_list, list) {
+ if (cb->key_change_cfm)
+ cb->key_change_cfm(conn, status);
+- kfree(cb);
+ }
++ mutex_unlock(&hci_cb_list_lock);
+ }
+
+ static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status,
+ __u8 role)
+ {
+- struct list_head list;
+- struct hci_cb *cb, *tmp;
+-
+- INIT_LIST_HEAD(&list);
+- hci_cb_lookup(conn, &list);
++ struct hci_cb *cb;
+
+- list_for_each_entry_safe(cb, tmp, &list, list) {
++ mutex_lock(&hci_cb_list_lock);
++ list_for_each_entry(cb, &hci_cb_list, list) {
+ if (cb->role_switch_cfm)
+ cb->role_switch_cfm(conn, status, role);
+- kfree(cb);
+ }
++ mutex_unlock(&hci_cb_list_lock);
+ }
+
+ static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index f29fd32644011..30519d47e8a69 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -58,6 +58,7 @@ DEFINE_RWLOCK(hci_dev_list_lock);
+
+ /* HCI callback list */
+ LIST_HEAD(hci_cb_list);
++DEFINE_MUTEX(hci_cb_list_lock);
+
+ /* HCI ID Numbering */
+ static DEFINE_IDA(hci_index_ida);
+@@ -2956,7 +2957,9 @@ int hci_register_cb(struct hci_cb *cb)
+ {
+ BT_DBG("%p name %s", cb, cb->name);
+
+- list_add_tail_rcu(&cb->list, &hci_cb_list);
++ mutex_lock(&hci_cb_list_lock);
++ list_add_tail(&cb->list, &hci_cb_list);
++ mutex_unlock(&hci_cb_list_lock);
+
+ return 0;
+ }
+@@ -2966,8 +2969,9 @@ int hci_unregister_cb(struct hci_cb *cb)
+ {
+ BT_DBG("%p name %s", cb, cb->name);
+
+- list_del_rcu(&cb->list);
+- synchronize_rcu();
++ mutex_lock(&hci_cb_list_lock);
++ list_del(&cb->list);
++ mutex_unlock(&hci_cb_list_lock);
+
+ return 0;
+ }
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index f165cafa3aa98..b94d202bf3745 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -1929,11 +1929,6 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
+ return lm;
+ }
+
+-static bool iso_match(struct hci_conn *hcon)
+-{
+- return hcon->type == ISO_LINK || hcon->type == LE_LINK;
+-}
+-
+ static void iso_connect_cfm(struct hci_conn *hcon, __u8 status)
+ {
+ if (hcon->type != ISO_LINK) {
+@@ -2115,7 +2110,6 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
+
+ static struct hci_cb iso_cb = {
+ .name = "ISO",
+- .match = iso_match,
+ .connect_cfm = iso_connect_cfm,
+ .disconn_cfm = iso_disconn_cfm,
+ };
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 304ebb31cebba..76a85d8b17574 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -7228,11 +7228,6 @@ static struct l2cap_chan *l2cap_global_fixed_chan(struct l2cap_chan *c,
+ return NULL;
+ }
+
+-static bool l2cap_match(struct hci_conn *hcon)
+-{
+- return hcon->type == ACL_LINK || hcon->type == LE_LINK;
+-}
+-
+ static void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
+ {
+ struct hci_dev *hdev = hcon->hdev;
+@@ -7240,6 +7235,9 @@ static void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
+ struct l2cap_chan *pchan;
+ u8 dst_type;
+
++ if (hcon->type != ACL_LINK && hcon->type != LE_LINK)
++ return;
++
+ BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
+
+ if (status) {
+@@ -7304,6 +7302,9 @@ int l2cap_disconn_ind(struct hci_conn *hcon)
+
+ static void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
+ {
++ if (hcon->type != ACL_LINK && hcon->type != LE_LINK)
++ return;
++
+ BT_DBG("hcon %p reason %d", hcon, reason);
+
+ l2cap_conn_del(hcon, bt_to_errno(reason));
+@@ -7582,7 +7583,6 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
+
+ static struct hci_cb l2cap_cb = {
+ .name = "L2CAP",
+- .match = l2cap_match,
+ .connect_cfm = l2cap_connect_cfm,
+ .disconn_cfm = l2cap_disconn_cfm,
+ .security_cfm = l2cap_security_cfm,
+diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
+index 9d46afb24caf0..1d34d84970332 100644
+--- a/net/bluetooth/rfcomm/core.c
++++ b/net/bluetooth/rfcomm/core.c
+@@ -2134,11 +2134,6 @@ static int rfcomm_run(void *unused)
+ return 0;
+ }
+
+-static bool rfcomm_match(struct hci_conn *hcon)
+-{
+- return hcon->type == ACL_LINK;
+-}
+-
+ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
+ {
+ struct rfcomm_session *s;
+@@ -2185,7 +2180,6 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
+
+ static struct hci_cb rfcomm_cb = {
+ .name = "RFCOMM",
+- .match = rfcomm_match,
+ .security_cfm = rfcomm_security_cfm
+ };
+
+diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
+index c4c36ff25fb20..64d4d57c7033a 100644
+--- a/net/bluetooth/sco.c
++++ b/net/bluetooth/sco.c
+@@ -1353,13 +1353,11 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
+ return lm;
+ }
+
+-static bool sco_match(struct hci_conn *hcon)
+-{
+- return hcon->type == SCO_LINK || hcon->type == ESCO_LINK;
+-}
+-
+ static void sco_connect_cfm(struct hci_conn *hcon, __u8 status)
+ {
++ if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
++ return;
++
+ BT_DBG("hcon %p bdaddr %pMR status %u", hcon, &hcon->dst, status);
+
+ if (!status) {
+@@ -1374,6 +1372,9 @@ static void sco_connect_cfm(struct hci_conn *hcon, __u8 status)
+
+ static void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
+ {
++ if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
++ return;
++
+ BT_DBG("hcon %p reason %d", hcon, reason);
+
+ sco_conn_del(hcon, bt_to_errno(reason));
+@@ -1399,7 +1400,6 @@ void sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
+
+ static struct hci_cb sco_cb = {
+ .name = "SCO",
+- .match = sco_match,
+ .connect_cfm = sco_connect_cfm,
+ .disconn_cfm = sco_disconn_cfm,
+ };
+--
+2.39.5
+
--- /dev/null
+From 5c1d406ce2d45112b7f41fad4515bda959c9eefe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Mar 2025 23:44:10 +0800
+Subject: sched: address a potential NULL pointer dereference in the GRED
+ scheduler.
+
+From: Jun Yang <juny24602@gmail.com>
+
+[ Upstream commit 115ef44a98220fddfab37a39a19370497cd718b9 ]
+
+If kzalloc in gred_init returns a NULL pointer, the code follows the
+error handling path, invoking gred_destroy. This, in turn, calls
+gred_offload, where memset could receive a NULL pointer as input,
+potentially leading to a kernel crash.
+
+When table->opt is NULL in gred_init(), gred_change_table_def()
+is not called yet, so it is not necessary to call ->ndo_setup_tc()
+in gred_offload().
+
+Signed-off-by: Jun Yang <juny24602@gmail.com>
+Reviewed-by: Cong Wang <xiyou.wangcong@gmail.com>
+Fixes: f25c0515c521 ("net: sched: gred: dynamically allocate tc_gred_qopt_offload")
+Link: https://patch.msgid.link/20250305154410.3505642-1-juny24602@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_gred.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
+index 872d127c9db42..fa7a1b69c0f35 100644
+--- a/net/sched/sch_gred.c
++++ b/net/sched/sch_gred.c
+@@ -913,7 +913,8 @@ static void gred_destroy(struct Qdisc *sch)
+ for (i = 0; i < table->DPs; i++)
+ gred_destroy_vq(table->tab[i]);
+
+- gred_offload(sch, TC_GRED_DESTROY);
++ if (table->opt)
++ gred_offload(sch, TC_GRED_DESTROY);
+ kfree(table->opt);
+ }
+
+--
+2.39.5
+
bpf-use-raw_spinlock_t-in-ringbuf.patch
tcp-fix-races-in-tcp_abort.patch
tcp-fix-forever-orphan-socket-caused-by-tcp_abort.patch
+fbdev-hyperv_fb-iounmap-the-correct-memory-when-remo.patch
+pinctrl-bcm281xx-fix-incorrect-regmap-max_registers-.patch
+netfilter-nft_ct-use-__refcount_inc-for-per-cpu-nft_.patch
+ice-fix-memory-leak-in-arfs-after-reset.patch
+netfilter-nf_conncount-garbage-collection-is-not-ski.patch
+sched-address-a-potential-null-pointer-dereference-i.patch
+wifi-cfg80211-cancel-wiphy_work-before-freeing-wiphy.patch
+bluetooth-hci_event-fix-enabling-passive-scanning.patch
+revert-bluetooth-hci_core-fix-sleeping-function-call.patch
+net-mlx5-fill-out-devlink-dev-info-only-for-pfs.patch
+net-dsa-mv88e6xxx-verify-after-atu-load-ops.patch
+net-mctp-i2c-copy-headers-if-cloned.patch
+netpoll-hold-rcu-read-lock-in-__netpoll_send_skb.patch
+drm-hyperv-fix-address-space-leak-when-hyper-v-drm-d.patch
+dt-bindings-display-rockchip-vop-document-rv1126-vop.patch
+fbdev-hyperv_fb-use-fb_ops-helpers-for-deferred-i-o.patch
+fbdev-mmp-mmpfb-do-not-display-boot-up-logo.patch
+fbdev-core-unexport-logo-helpers.patch
+fbdev-introduce-devm_register_framebuffer.patch
+fbdev-hyperv_fb-simplify-hvfb_putmem.patch
+fbdev-hyperv_fb-allow-graceful-removal-of-framebuffe.patch
+drivers-hv-vmbus-don-t-release-fb_mmio-resource-in-v.patch
+net-mlx5-handle-errors-in-mlx5_chains_create_table.patch
+eth-bnxt-do-not-update-checksum-in-bnxt_xdp_build_sk.patch
+net-switchdev-convert-blocking-notification-chain-to.patch
+bonding-fix-incorrect-mac-address-setting-to-receive.patch
+netfilter-nf_conncount-fully-initialize-struct-nf_co.patch
+ipvs-prevent-integer-overflow-in-do_ip_vs_get_ctl.patch
+net_sched-prevent-creation-of-classes-with-tc_h_root.patch
+netfilter-nft_exthdr-fix-offset-with-ipv4_find_optio.patch
+gre-fix-ipv6-link-local-address-generation.patch
+net-openvswitch-remove-misbehaving-actions-length-ch.patch
+net-mlx5-lag-check-shared-fdb-before-creating-multip.patch
+net-mlx5-bridge-fix-the-crash-caused-by-lag-state-ch.patch
+net-mlx5e-prevent-bridge-link-show-failure-for-non-e.patch
--- /dev/null
+From fa5049799999f00a45809579a0bb5787f42de76c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 12:37:59 +0200
+Subject: wifi: cfg80211: cancel wiphy_work before freeing wiphy
+
+From: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+
+[ Upstream commit 72d520476a2fab6f3489e8388ab524985d6c4b90 ]
+
+A wiphy_work can be queued from the moment the wiphy is allocated and
+initialized (i.e. wiphy_new_nm). When a wiphy_work is queued, the
+rdev::wiphy_work is getting queued.
+
+If wiphy_free is called before the rdev::wiphy_work had a chance to run,
+the wiphy memory will be freed, and then when it eventally gets to run
+it'll use invalid memory.
+
+Fix this by canceling the work before freeing the wiphy.
+
+Fixes: a3ee4dc84c4e ("wifi: cfg80211: add a work abstraction with special semantics")
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Reviewed-by: Johannes Berg <johannes.berg@intel.com>
+Link: https://patch.msgid.link/20250306123626.efd1d19f6e07.I48229f96f4067ef73f5b87302335e2fd750136c9@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/core.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 3c1247933ae92..a2b15349324b6 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1151,6 +1151,13 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
+ {
+ struct cfg80211_internal_bss *scan, *tmp;
+ struct cfg80211_beacon_registration *reg, *treg;
++ unsigned long flags;
++
++ spin_lock_irqsave(&rdev->wiphy_work_lock, flags);
++ WARN_ON(!list_empty(&rdev->wiphy_work_list));
++ spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags);
++ cancel_work_sync(&rdev->wiphy_work);
++
+ rfkill_destroy(rdev->wiphy.rfkill);
+ list_for_each_entry_safe(reg, treg, &rdev->beacon_registrations, list) {
+ list_del(®->list);
+--
+2.39.5
+