--- /dev/null
+From af790cdd2e61f13f3dbb692af153aba1a126a96e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Jun 2025 16:37:01 +0100
+Subject: btrfs: use btrfs_record_snapshot_destroy() during rmdir
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 157501b0469969fc1ba53add5049575aadd79d80 ]
+
+We are setting the parent directory's last_unlink_trans directly which
+may result in a concurrent task starting to log the directory not see the
+update and therefore can log the directory after we removed a child
+directory which had a snapshot within instead of falling back to a
+transaction commit. Replaying such a log tree would result in a mount
+failure since we can't currently delete snapshots (and subvolumes) during
+log replay. This is the type of failure described in commit 1ec9a1ae1e30
+("Btrfs: fix unreplayable log after snapshot delete + parent dir fsync").
+
+Fix this by using btrfs_record_snapshot_destroy() which updates the
+last_unlink_trans field while holding the inode's log_mutex lock.
+
+Fixes: 44f714dae50a ("Btrfs: improve performance on fsync against new inode after rename/unlink")
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/inode.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index f7f97cd3cdf06..5ecc2f3dc3a99 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -4856,7 +4856,6 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
+ struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
+ int err = 0;
+ struct btrfs_trans_handle *trans;
+- u64 last_unlink_trans;
+ struct fscrypt_name fname;
+
+ if (inode->i_size > BTRFS_EMPTY_DIR_SIZE)
+@@ -4891,8 +4890,6 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
+ if (err)
+ goto out;
+
+- last_unlink_trans = BTRFS_I(inode)->last_unlink_trans;
+-
+ /* now the directory is empty */
+ err = btrfs_unlink_inode(trans, BTRFS_I(dir), BTRFS_I(d_inode(dentry)),
+ &fname.disk_name);
+@@ -4909,8 +4906,8 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
+ * 5) mkdir foo
+ * 6) fsync foo or some file inside foo
+ */
+- if (last_unlink_trans >= trans->transid)
+- BTRFS_I(dir)->last_unlink_trans = last_unlink_trans;
++ if (BTRFS_I(inode)->last_unlink_trans >= trans->transid)
++ btrfs_record_snapshot_destroy(trans, BTRFS_I(dir));
+ }
+ out:
+ btrfs_end_transaction(trans);
+--
+2.39.5
+
--- /dev/null
+From 349212293e1f0b0773593a4d6b329ea191002aaf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jul 2025 12:34:31 -0400
+Subject: dpaa2-eth: fix xdp_rxq_info leak
+
+From: Fushuai Wang <wangfushuai@baidu.com>
+
+[ Upstream commit 2def09ead4ad5907988b655d1e1454003aaf8297 ]
+
+The driver registered xdp_rxq_info structures via xdp_rxq_info_reg()
+but failed to properly unregister them in error paths and during
+removal.
+
+Fixes: d678be1dc1ec ("dpaa2-eth: add XDP_REDIRECT support")
+Signed-off-by: Fushuai Wang <wangfushuai@baidu.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
+Link: https://patch.msgid.link/20250626133003.80136-1-wangfushuai@baidu.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 26 +++++++++++++++++--
+ 1 file changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+index bbbe7c5b5d35a..5ef117c9d0eca 100644
+--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+@@ -3729,6 +3729,7 @@ static int dpaa2_eth_setup_rx_flow(struct dpaa2_eth_priv *priv,
+ MEM_TYPE_PAGE_ORDER0, NULL);
+ if (err) {
+ dev_err(dev, "xdp_rxq_info_reg_mem_model failed\n");
++ xdp_rxq_info_unreg(&fq->channel->xdp_rxq);
+ return err;
+ }
+
+@@ -4221,17 +4222,25 @@ static int dpaa2_eth_bind_dpni(struct dpaa2_eth_priv *priv)
+ return -EINVAL;
+ }
+ if (err)
+- return err;
++ goto out;
+ }
+
+ err = dpni_get_qdid(priv->mc_io, 0, priv->mc_token,
+ DPNI_QUEUE_TX, &priv->tx_qdid);
+ if (err) {
+ dev_err(dev, "dpni_get_qdid() failed\n");
+- return err;
++ goto out;
+ }
+
+ return 0;
++
++out:
++ while (i--) {
++ if (priv->fq[i].type == DPAA2_RX_FQ &&
++ xdp_rxq_info_is_reg(&priv->fq[i].channel->xdp_rxq))
++ xdp_rxq_info_unreg(&priv->fq[i].channel->xdp_rxq);
++ }
++ return err;
+ }
+
+ /* Allocate rings for storing incoming frame descriptors */
+@@ -4588,6 +4597,17 @@ static void dpaa2_eth_del_ch_napi(struct dpaa2_eth_priv *priv)
+ }
+ }
+
++static void dpaa2_eth_free_rx_xdp_rxq(struct dpaa2_eth_priv *priv)
++{
++ int i;
++
++ for (i = 0; i < priv->num_fqs; i++) {
++ if (priv->fq[i].type == DPAA2_RX_FQ &&
++ xdp_rxq_info_is_reg(&priv->fq[i].channel->xdp_rxq))
++ xdp_rxq_info_unreg(&priv->fq[i].channel->xdp_rxq);
++ }
++}
++
+ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
+ {
+ struct device *dev;
+@@ -4786,6 +4806,7 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
+ free_percpu(priv->percpu_stats);
+ err_alloc_percpu_stats:
+ dpaa2_eth_del_ch_napi(priv);
++ dpaa2_eth_free_rx_xdp_rxq(priv);
+ err_bind:
+ dpaa2_eth_free_dpbp(priv);
+ err_dpbp_setup:
+@@ -4840,6 +4861,7 @@ static int dpaa2_eth_remove(struct fsl_mc_device *ls_dev)
+ free_percpu(priv->percpu_extras);
+
+ dpaa2_eth_del_ch_napi(priv);
++ dpaa2_eth_free_rx_xdp_rxq(priv);
+ dpaa2_eth_free_dpbp(priv);
+ dpaa2_eth_free_dpio(priv);
+ dpaa2_eth_free_dpni(priv);
+--
+2.39.5
+
--- /dev/null
+From d501c92864a6bfc47ad73c441701144c42ed5c0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 28 Jun 2025 19:42:42 -0300
+Subject: drm/v3d: Disable interrupts before resetting the GPU
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maíra Canal <mcanal@igalia.com>
+
+[ Upstream commit 226862f50a7a88e4e4de9abbf36c64d19acd6fd0 ]
+
+Currently, an interrupt can be triggered during a GPU reset, which can
+lead to GPU hangs and NULL pointer dereference in an interrupt context
+as shown in the following trace:
+
+ [ 314.035040] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000c0
+ [ 314.043822] Mem abort info:
+ [ 314.046606] ESR = 0x0000000096000005
+ [ 314.050347] EC = 0x25: DABT (current EL), IL = 32 bits
+ [ 314.055651] SET = 0, FnV = 0
+ [ 314.058695] EA = 0, S1PTW = 0
+ [ 314.061826] FSC = 0x05: level 1 translation fault
+ [ 314.066694] Data abort info:
+ [ 314.069564] ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
+ [ 314.075039] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+ [ 314.080080] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+ [ 314.085382] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000102728000
+ [ 314.091814] [00000000000000c0] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
+ [ 314.100511] Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
+ [ 314.106770] Modules linked in: v3d i2c_brcmstb vc4 snd_soc_hdmi_codec gpu_sched drm_shmem_helper drm_display_helper cec drm_dma_helper drm_kms_helper drm drm_panel_orientation_quirks snd_soc_core snd_compress snd_pcm_dmaengine snd_pcm snd_timer snd backlight
+ [ 314.129654] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.25+rpt-rpi-v8 #1 Debian 1:6.12.25-1+rpt1
+ [ 314.139388] Hardware name: Raspberry Pi 4 Model B Rev 1.4 (DT)
+ [ 314.145211] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+ [ 314.152165] pc : v3d_irq+0xec/0x2e0 [v3d]
+ [ 314.156187] lr : v3d_irq+0xe0/0x2e0 [v3d]
+ [ 314.160198] sp : ffffffc080003ea0
+ [ 314.163502] x29: ffffffc080003ea0 x28: ffffffec1f184980 x27: 021202b000000000
+ [ 314.170633] x26: ffffffec1f17f630 x25: ffffff8101372000 x24: ffffffec1f17d9f0
+ [ 314.177764] x23: 000000000000002a x22: 000000000000002a x21: ffffff8103252000
+ [ 314.184895] x20: 0000000000000001 x19: 00000000deadbeef x18: 0000000000000000
+ [ 314.192026] x17: ffffff94e51d2000 x16: ffffffec1dac3cb0 x15: c306000000000000
+ [ 314.199156] x14: 0000000000000000 x13: b2fc982e03cc5168 x12: 0000000000000001
+ [ 314.206286] x11: ffffff8103f8bcc0 x10: ffffffec1f196868 x9 : ffffffec1dac3874
+ [ 314.213416] x8 : 0000000000000000 x7 : 0000000000042a3a x6 : ffffff810017a180
+ [ 314.220547] x5 : ffffffec1ebad400 x4 : ffffffec1ebad320 x3 : 00000000000bebeb
+ [ 314.227677] x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000
+ [ 314.234807] Call trace:
+ [ 314.237243] v3d_irq+0xec/0x2e0 [v3d]
+ [ 314.240906] __handle_irq_event_percpu+0x58/0x218
+ [ 314.245609] handle_irq_event+0x54/0xb8
+ [ 314.249439] handle_fasteoi_irq+0xac/0x240
+ [ 314.253527] handle_irq_desc+0x48/0x68
+ [ 314.257269] generic_handle_domain_irq+0x24/0x38
+ [ 314.261879] gic_handle_irq+0x48/0xd8
+ [ 314.265533] call_on_irq_stack+0x24/0x58
+ [ 314.269448] do_interrupt_handler+0x88/0x98
+ [ 314.273624] el1_interrupt+0x34/0x68
+ [ 314.277193] el1h_64_irq_handler+0x18/0x28
+ [ 314.281281] el1h_64_irq+0x64/0x68
+ [ 314.284673] default_idle_call+0x3c/0x168
+ [ 314.288675] do_idle+0x1fc/0x230
+ [ 314.291895] cpu_startup_entry+0x3c/0x50
+ [ 314.295810] rest_init+0xe4/0xf0
+ [ 314.299030] start_kernel+0x5e8/0x790
+ [ 314.302684] __primary_switched+0x80/0x90
+ [ 314.306691] Code: 940029eb 360ffc13 f9442ea0 52800001 (f9406017)
+ [ 314.312775] ---[ end trace 0000000000000000 ]---
+ [ 314.317384] Kernel panic - not syncing: Oops: Fatal exception in interrupt
+ [ 314.324249] SMP: stopping secondary CPUs
+ [ 314.328167] Kernel Offset: 0x2b9da00000 from 0xffffffc080000000
+ [ 314.334076] PHYS_OFFSET: 0x0
+ [ 314.336946] CPU features: 0x08,00002013,c0200000,0200421b
+ [ 314.342337] Memory Limit: none
+ [ 314.345382] ---[ end Kernel panic - not syncing: Oops: Fatal exception in interrupt ]---
+
+Before resetting the GPU, it's necessary to disable all interrupts and
+deal with any interrupt handler still in-flight. Otherwise, the GPU might
+reset with jobs still running, or yet, an interrupt could be handled
+during the reset.
+
+Cc: stable@vger.kernel.org
+Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+")
+Reviewed-by: Juan A. Suarez <jasuarez@igalia.com>
+Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
+Link: https://lore.kernel.org/r/20250628224243.47599-1-mcanal@igalia.com
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/v3d/v3d_drv.h | 8 ++++++++
+ drivers/gpu/drm/v3d/v3d_gem.c | 2 ++
+ drivers/gpu/drm/v3d/v3d_irq.c | 37 +++++++++++++++++++++++++----------
+ 3 files changed, 37 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h
+index b74b1351bfc83..a366ea208787d 100644
+--- a/drivers/gpu/drm/v3d/v3d_drv.h
++++ b/drivers/gpu/drm/v3d/v3d_drv.h
+@@ -62,6 +62,12 @@ struct v3d_perfmon {
+ u64 values[];
+ };
+
++enum v3d_irq {
++ V3D_CORE_IRQ,
++ V3D_HUB_IRQ,
++ V3D_MAX_IRQS,
++};
++
+ struct v3d_dev {
+ struct drm_device drm;
+
+@@ -71,6 +77,8 @@ struct v3d_dev {
+ int ver;
+ bool single_irq_line;
+
++ int irq[V3D_MAX_IRQS];
++
+ void __iomem *hub_regs;
+ void __iomem *core_regs[3];
+ void __iomem *bridge_regs;
+diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c
+index b8980440d137f..8b6450a96ebc3 100644
+--- a/drivers/gpu/drm/v3d/v3d_gem.c
++++ b/drivers/gpu/drm/v3d/v3d_gem.c
+@@ -119,6 +119,8 @@ v3d_reset(struct v3d_dev *v3d)
+ if (false)
+ v3d_idle_axi(v3d, 0);
+
++ v3d_irq_disable(v3d);
++
+ v3d_idle_gca(v3d);
+ v3d_reset_v3d(v3d);
+
+diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c
+index b2d59a1686972..641315dbee8b2 100644
+--- a/drivers/gpu/drm/v3d/v3d_irq.c
++++ b/drivers/gpu/drm/v3d/v3d_irq.c
+@@ -215,7 +215,7 @@ v3d_hub_irq(int irq, void *arg)
+ int
+ v3d_irq_init(struct v3d_dev *v3d)
+ {
+- int irq1, ret, core;
++ int irq, ret, core;
+
+ INIT_WORK(&v3d->overflow_mem_work, v3d_overflow_mem_work);
+
+@@ -226,17 +226,24 @@ v3d_irq_init(struct v3d_dev *v3d)
+ V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS);
+ V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS);
+
+- irq1 = platform_get_irq_optional(v3d_to_pdev(v3d), 1);
+- if (irq1 == -EPROBE_DEFER)
+- return irq1;
+- if (irq1 > 0) {
+- ret = devm_request_irq(v3d->drm.dev, irq1,
++ irq = platform_get_irq_optional(v3d_to_pdev(v3d), 1);
++ if (irq == -EPROBE_DEFER)
++ return irq;
++ if (irq > 0) {
++ v3d->irq[V3D_CORE_IRQ] = irq;
++
++ ret = devm_request_irq(v3d->drm.dev, v3d->irq[V3D_CORE_IRQ],
+ v3d_irq, IRQF_SHARED,
+ "v3d_core0", v3d);
+ if (ret)
+ goto fail;
+- ret = devm_request_irq(v3d->drm.dev,
+- platform_get_irq(v3d_to_pdev(v3d), 0),
++
++ irq = platform_get_irq(v3d_to_pdev(v3d), 0);
++ if (irq < 0)
++ return irq;
++ v3d->irq[V3D_HUB_IRQ] = irq;
++
++ ret = devm_request_irq(v3d->drm.dev, v3d->irq[V3D_HUB_IRQ],
+ v3d_hub_irq, IRQF_SHARED,
+ "v3d_hub", v3d);
+ if (ret)
+@@ -244,8 +251,12 @@ v3d_irq_init(struct v3d_dev *v3d)
+ } else {
+ v3d->single_irq_line = true;
+
+- ret = devm_request_irq(v3d->drm.dev,
+- platform_get_irq(v3d_to_pdev(v3d), 0),
++ irq = platform_get_irq(v3d_to_pdev(v3d), 0);
++ if (irq < 0)
++ return irq;
++ v3d->irq[V3D_CORE_IRQ] = irq;
++
++ ret = devm_request_irq(v3d->drm.dev, v3d->irq[V3D_CORE_IRQ],
+ v3d_irq, IRQF_SHARED,
+ "v3d", v3d);
+ if (ret)
+@@ -286,6 +297,12 @@ v3d_irq_disable(struct v3d_dev *v3d)
+ V3D_CORE_WRITE(core, V3D_CTL_INT_MSK_SET, ~0);
+ V3D_WRITE(V3D_HUB_INT_MSK_SET, ~0);
+
++ /* Finish any interrupt handler still in flight. */
++ for (int i = 0; i < V3D_MAX_IRQS; i++) {
++ if (v3d->irq[i])
++ synchronize_irq(v3d->irq[i]);
++ }
++
+ /* Clear any pending interrupts we might have left. */
+ for (core = 0; core < v3d->cores; core++)
+ V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS);
+--
+2.39.5
+
--- /dev/null
+From 5904a8ad2b3e05b659d59973afcc26f1cc8013ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Jun 2025 07:13:46 +0200
+Subject: net: usb: lan78xx: fix WARN in __netif_napi_del_locked on disconnect
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+[ Upstream commit 6c7ffc9af7186ed79403a3ffee9a1e5199fc7450 ]
+
+Remove redundant netif_napi_del() call from disconnect path.
+
+A WARN may be triggered in __netif_napi_del_locked() during USB device
+disconnect:
+
+ WARNING: CPU: 0 PID: 11 at net/core/dev.c:7417 __netif_napi_del_locked+0x2b4/0x350
+
+This happens because netif_napi_del() is called in the disconnect path while
+NAPI is still enabled. However, it is not necessary to call netif_napi_del()
+explicitly, since unregister_netdev() will handle NAPI teardown automatically
+and safely. Removing the redundant call avoids triggering the warning.
+
+Full trace:
+ lan78xx 1-1:1.0 enu1: Failed to read register index 0x000000c4. ret = -ENODEV
+ lan78xx 1-1:1.0 enu1: Failed to set MAC down with error -ENODEV
+ lan78xx 1-1:1.0 enu1: Link is Down
+ lan78xx 1-1:1.0 enu1: Failed to read register index 0x00000120. ret = -ENODEV
+ ------------[ cut here ]------------
+ WARNING: CPU: 0 PID: 11 at net/core/dev.c:7417 __netif_napi_del_locked+0x2b4/0x350
+ Modules linked in: flexcan can_dev fuse
+ CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 6.16.0-rc2-00624-ge926949dab03 #9 PREEMPT
+ Hardware name: SKOV IMX8MP CPU revC - bd500 (DT)
+ Workqueue: usb_hub_wq hub_event
+ pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+ pc : __netif_napi_del_locked+0x2b4/0x350
+ lr : __netif_napi_del_locked+0x7c/0x350
+ sp : ffffffc085b673c0
+ x29: ffffffc085b673c0 x28: ffffff800b7f2000 x27: ffffff800b7f20d8
+ x26: ffffff80110bcf58 x25: ffffff80110bd978 x24: 1ffffff0022179eb
+ x23: ffffff80110bc000 x22: ffffff800b7f5000 x21: ffffff80110bc000
+ x20: ffffff80110bcf38 x19: ffffff80110bcf28 x18: dfffffc000000000
+ x17: ffffffc081578940 x16: ffffffc08284cee0 x15: 0000000000000028
+ x14: 0000000000000006 x13: 0000000000040000 x12: ffffffb0022179e8
+ x11: 1ffffff0022179e7 x10: ffffffb0022179e7 x9 : dfffffc000000000
+ x8 : 0000004ffdde8619 x7 : ffffff80110bcf3f x6 : 0000000000000001
+ x5 : ffffff80110bcf38 x4 : ffffff80110bcf38 x3 : 0000000000000000
+ x2 : 0000000000000000 x1 : 1ffffff0022179e7 x0 : 0000000000000000
+ Call trace:
+ __netif_napi_del_locked+0x2b4/0x350 (P)
+ lan78xx_disconnect+0xf4/0x360
+ usb_unbind_interface+0x158/0x718
+ device_remove+0x100/0x150
+ device_release_driver_internal+0x308/0x478
+ device_release_driver+0x1c/0x30
+ bus_remove_device+0x1a8/0x368
+ device_del+0x2e0/0x7b0
+ usb_disable_device+0x244/0x540
+ usb_disconnect+0x220/0x758
+ hub_event+0x105c/0x35e0
+ process_one_work+0x760/0x17b0
+ worker_thread+0x768/0xce8
+ kthread+0x3bc/0x690
+ ret_from_fork+0x10/0x20
+ irq event stamp: 211604
+ hardirqs last enabled at (211603): [<ffffffc0828cc9ec>] _raw_spin_unlock_irqrestore+0x84/0x98
+ hardirqs last disabled at (211604): [<ffffffc0828a9a84>] el1_dbg+0x24/0x80
+ softirqs last enabled at (211296): [<ffffffc080095f10>] handle_softirqs+0x820/0xbc8
+ softirqs last disabled at (210993): [<ffffffc080010288>] __do_softirq+0x18/0x20
+ ---[ end trace 0000000000000000 ]---
+ lan78xx 1-1:1.0 enu1: failed to kill vid 0081/0
+
+Fixes: ec4c7e12396b ("lan78xx: Introduce NAPI polling support")
+Suggested-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20250627051346.276029-1-o.rempel@pengutronix.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/lan78xx.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
+index feff1265cad6f..0f1c9009d793e 100644
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -4231,8 +4231,6 @@ static void lan78xx_disconnect(struct usb_interface *intf)
+
+ set_bit(EVENT_DEV_DISCONNECT, &dev->flags);
+
+- netif_napi_del(&dev->napi);
+-
+ udev = interface_to_usbdev(intf);
+ net = dev->net;
+
+--
+2.39.5
+
--- /dev/null
+From df3da4f9d578ed1acfe55d1a2bcc178060f031ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Jun 2025 15:16:11 -0400
+Subject: NFSv4/flexfiles: Fix handling of NFS level errors in I/O
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 38074de35b015df5623f524d6f2b49a0cd395c40 ]
+
+Allow the flexfiles error handling to recognise NFS level errors (as
+opposed to RPC level errors) and handle them separately. The main
+motivator is the NFSERR_PERM errors that get returned if the NFS client
+connects to the data server through a port number that is lower than
+1024. In that case, the client should disconnect and retry a READ on a
+different data server, or it should retry a WRITE after reconnecting.
+
+Reviewed-by: Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
+Fixes: d67ae825a59d ("pnfs/flexfiles: Add the FlexFile Layout Driver")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/flexfilelayout/flexfilelayout.c | 121 ++++++++++++++++++-------
+ 1 file changed, 87 insertions(+), 34 deletions(-)
+
+diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
+index 07e5ea64dcd68..aa55b5df065bc 100644
+--- a/fs/nfs/flexfilelayout/flexfilelayout.c
++++ b/fs/nfs/flexfilelayout/flexfilelayout.c
+@@ -1096,6 +1096,7 @@ static void ff_layout_reset_read(struct nfs_pgio_header *hdr)
+ }
+
+ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
++ u32 op_status,
+ struct nfs4_state *state,
+ struct nfs_client *clp,
+ struct pnfs_layout_segment *lseg,
+@@ -1106,32 +1107,42 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
+ struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx);
+ struct nfs4_slot_table *tbl = &clp->cl_session->fc_slot_table;
+
+- switch (task->tk_status) {
+- case -NFS4ERR_BADSESSION:
+- case -NFS4ERR_BADSLOT:
+- case -NFS4ERR_BAD_HIGH_SLOT:
+- case -NFS4ERR_DEADSESSION:
+- case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
+- case -NFS4ERR_SEQ_FALSE_RETRY:
+- case -NFS4ERR_SEQ_MISORDERED:
++ switch (op_status) {
++ case NFS4_OK:
++ case NFS4ERR_NXIO:
++ break;
++ case NFSERR_PERM:
++ if (!task->tk_xprt)
++ break;
++ xprt_force_disconnect(task->tk_xprt);
++ goto out_retry;
++ case NFS4ERR_BADSESSION:
++ case NFS4ERR_BADSLOT:
++ case NFS4ERR_BAD_HIGH_SLOT:
++ case NFS4ERR_DEADSESSION:
++ case NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
++ case NFS4ERR_SEQ_FALSE_RETRY:
++ case NFS4ERR_SEQ_MISORDERED:
+ dprintk("%s ERROR %d, Reset session. Exchangeid "
+ "flags 0x%x\n", __func__, task->tk_status,
+ clp->cl_exchange_flags);
+ nfs4_schedule_session_recovery(clp->cl_session, task->tk_status);
+- break;
+- case -NFS4ERR_DELAY:
+- case -NFS4ERR_GRACE:
++ goto out_retry;
++ case NFS4ERR_DELAY:
++ nfs_inc_stats(lseg->pls_layout->plh_inode, NFSIOS_DELAY);
++ fallthrough;
++ case NFS4ERR_GRACE:
+ rpc_delay(task, FF_LAYOUT_POLL_RETRY_MAX);
+- break;
+- case -NFS4ERR_RETRY_UNCACHED_REP:
+- break;
++ goto out_retry;
++ case NFS4ERR_RETRY_UNCACHED_REP:
++ goto out_retry;
+ /* Invalidate Layout errors */
+- case -NFS4ERR_PNFS_NO_LAYOUT:
+- case -ESTALE: /* mapped NFS4ERR_STALE */
+- case -EBADHANDLE: /* mapped NFS4ERR_BADHANDLE */
+- case -EISDIR: /* mapped NFS4ERR_ISDIR */
+- case -NFS4ERR_FHEXPIRED:
+- case -NFS4ERR_WRONG_TYPE:
++ case NFS4ERR_PNFS_NO_LAYOUT:
++ case NFS4ERR_STALE:
++ case NFS4ERR_BADHANDLE:
++ case NFS4ERR_ISDIR:
++ case NFS4ERR_FHEXPIRED:
++ case NFS4ERR_WRONG_TYPE:
+ dprintk("%s Invalid layout error %d\n", __func__,
+ task->tk_status);
+ /*
+@@ -1144,6 +1155,11 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
+ pnfs_destroy_layout(NFS_I(inode));
+ rpc_wake_up(&tbl->slot_tbl_waitq);
+ goto reset;
++ default:
++ break;
++ }
++
++ switch (task->tk_status) {
+ /* RPC connection errors */
+ case -ECONNREFUSED:
+ case -EHOSTDOWN:
+@@ -1159,26 +1175,56 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
+ nfs4_delete_deviceid(devid->ld, devid->nfs_client,
+ &devid->deviceid);
+ rpc_wake_up(&tbl->slot_tbl_waitq);
+- fallthrough;
++ break;
+ default:
+- if (ff_layout_avoid_mds_available_ds(lseg))
+- return -NFS4ERR_RESET_TO_PNFS;
+-reset:
+- dprintk("%s Retry through MDS. Error %d\n", __func__,
+- task->tk_status);
+- return -NFS4ERR_RESET_TO_MDS;
++ break;
+ }
++
++ if (ff_layout_avoid_mds_available_ds(lseg))
++ return -NFS4ERR_RESET_TO_PNFS;
++reset:
++ dprintk("%s Retry through MDS. Error %d\n", __func__,
++ task->tk_status);
++ return -NFS4ERR_RESET_TO_MDS;
++
++out_retry:
+ task->tk_status = 0;
+ return -EAGAIN;
+ }
+
+ /* Retry all errors through either pNFS or MDS except for -EJUKEBOX */
+ static int ff_layout_async_handle_error_v3(struct rpc_task *task,
++ u32 op_status,
++ struct nfs_client *clp,
+ struct pnfs_layout_segment *lseg,
+ u32 idx)
+ {
+ struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx);
+
++ switch (op_status) {
++ case NFS_OK:
++ case NFSERR_NXIO:
++ break;
++ case NFSERR_PERM:
++ if (!task->tk_xprt)
++ break;
++ xprt_force_disconnect(task->tk_xprt);
++ goto out_retry;
++ case NFSERR_ACCES:
++ case NFSERR_BADHANDLE:
++ case NFSERR_FBIG:
++ case NFSERR_IO:
++ case NFSERR_NOSPC:
++ case NFSERR_ROFS:
++ case NFSERR_STALE:
++ goto out_reset_to_pnfs;
++ case NFSERR_JUKEBOX:
++ nfs_inc_stats(lseg->pls_layout->plh_inode, NFSIOS_DELAY);
++ goto out_retry;
++ default:
++ break;
++ }
++
+ switch (task->tk_status) {
+ /* File access problems. Don't mark the device as unavailable */
+ case -EACCES:
+@@ -1197,6 +1243,7 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task,
+ nfs4_delete_deviceid(devid->ld, devid->nfs_client,
+ &devid->deviceid);
+ }
++out_reset_to_pnfs:
+ /* FIXME: Need to prevent infinite looping here. */
+ return -NFS4ERR_RESET_TO_PNFS;
+ out_retry:
+@@ -1207,6 +1254,7 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task,
+ }
+
+ static int ff_layout_async_handle_error(struct rpc_task *task,
++ u32 op_status,
+ struct nfs4_state *state,
+ struct nfs_client *clp,
+ struct pnfs_layout_segment *lseg,
+@@ -1225,10 +1273,11 @@ static int ff_layout_async_handle_error(struct rpc_task *task,
+
+ switch (vers) {
+ case 3:
+- return ff_layout_async_handle_error_v3(task, lseg, idx);
+- case 4:
+- return ff_layout_async_handle_error_v4(task, state, clp,
++ return ff_layout_async_handle_error_v3(task, op_status, clp,
+ lseg, idx);
++ case 4:
++ return ff_layout_async_handle_error_v4(task, op_status, state,
++ clp, lseg, idx);
+ default:
+ /* should never happen */
+ WARN_ON_ONCE(1);
+@@ -1281,6 +1330,7 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg,
+ switch (status) {
+ case NFS4ERR_DELAY:
+ case NFS4ERR_GRACE:
++ case NFS4ERR_PERM:
+ break;
+ case NFS4ERR_NXIO:
+ ff_layout_mark_ds_unreachable(lseg, idx);
+@@ -1313,7 +1363,8 @@ static int ff_layout_read_done_cb(struct rpc_task *task,
+ trace_ff_layout_read_error(hdr);
+ }
+
+- err = ff_layout_async_handle_error(task, hdr->args.context->state,
++ err = ff_layout_async_handle_error(task, hdr->res.op_status,
++ hdr->args.context->state,
+ hdr->ds_clp, hdr->lseg,
+ hdr->pgio_mirror_idx);
+
+@@ -1483,7 +1534,8 @@ static int ff_layout_write_done_cb(struct rpc_task *task,
+ trace_ff_layout_write_error(hdr);
+ }
+
+- err = ff_layout_async_handle_error(task, hdr->args.context->state,
++ err = ff_layout_async_handle_error(task, hdr->res.op_status,
++ hdr->args.context->state,
+ hdr->ds_clp, hdr->lseg,
+ hdr->pgio_mirror_idx);
+
+@@ -1529,8 +1581,9 @@ static int ff_layout_commit_done_cb(struct rpc_task *task,
+ trace_ff_layout_commit_error(data);
+ }
+
+- err = ff_layout_async_handle_error(task, NULL, data->ds_clp,
+- data->lseg, data->ds_commit_index);
++ err = ff_layout_async_handle_error(task, data->res.op_status,
++ NULL, data->ds_clp, data->lseg,
++ data->ds_commit_index);
+
+ trace_nfs4_pnfs_commit_ds(data, err);
+ switch (err) {
+--
+2.39.5
+
--- /dev/null
+From f7b15cf12c5c7bb3cfa495b60447a353de7eb891 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Jun 2025 22:17:37 -0300
+Subject: platform/x86: dell-wmi-sysman: Fix class device unregistration
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kurt Borja <kuurtb@gmail.com>
+
+[ Upstream commit 314e5ad4782d08858b3abc325c0487bd2abc23a1 ]
+
+Devices under the firmware_attributes_class do not have unique a dev_t.
+Therefore, device_unregister() should be used instead of
+device_destroy(), since the latter may match any device with a given
+dev_t.
+
+Fixes: e8a60aa7404b ("platform/x86: Introduce support for Systems Management Driver over WMI for Dell Systems")
+Signed-off-by: Kurt Borja <kuurtb@gmail.com>
+Link: https://lore.kernel.org/r/20250625-dest-fix-v1-3-3a0f342312bb@gmail.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/dell/dell-wmi-sysman/sysman.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c
+index 660f00173f2ea..fb5eb4342c6ed 100644
+--- a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c
++++ b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c
+@@ -605,7 +605,7 @@ static int __init sysman_init(void)
+ release_attributes_data();
+
+ err_destroy_classdev:
+- device_destroy(fw_attr_class, MKDEV(0, 0));
++ device_unregister(wmi_priv.class_dev);
+
+ err_unregister_class:
+ fw_attributes_class_put();
+@@ -622,7 +622,7 @@ static int __init sysman_init(void)
+ static void __exit sysman_exit(void)
+ {
+ release_attributes_data();
+- device_destroy(fw_attr_class, MKDEV(0, 0));
++ device_unregister(wmi_priv.class_dev);
+ fw_attributes_class_put();
+ exit_bios_attr_set_interface();
+ exit_bios_attr_pass_interface();
+--
+2.39.5
+
--- /dev/null
+From 36092e72cf1c7c1814ee6d853a88e90611f2bad3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Jun 2025 22:17:36 -0300
+Subject: platform/x86: think-lmi: Fix class device unregistration
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kurt Borja <kuurtb@gmail.com>
+
+[ Upstream commit 5ff1fbb3059730700b4823f43999fc1315984632 ]
+
+Devices under the firmware_attributes_class do not have unique a dev_t.
+Therefore, device_unregister() should be used instead of
+device_destroy(), since the latter may match any device with a given
+dev_t.
+
+Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms")
+Signed-off-by: Kurt Borja <kuurtb@gmail.com>
+Link: https://lore.kernel.org/r/20250625-dest-fix-v1-2-3a0f342312bb@gmail.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/think-lmi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c
+index 6641f934f15bf..804e2493d7d21 100644
+--- a/drivers/platform/x86/think-lmi.c
++++ b/drivers/platform/x86/think-lmi.c
+@@ -1380,7 +1380,7 @@ static int tlmi_sysfs_init(void)
+ fail_create_attr:
+ tlmi_release_attr();
+ fail_device_created:
+- device_destroy(fw_attr_class, MKDEV(0, 0));
++ device_unregister(tlmi_priv.class_dev);
+ fail_class_created:
+ fw_attributes_class_put();
+ return ret;
+@@ -1602,7 +1602,7 @@ static int tlmi_analyze(void)
+ static void tlmi_remove(struct wmi_device *wdev)
+ {
+ tlmi_release_attr();
+- device_destroy(fw_attr_class, MKDEV(0, 0));
++ device_unregister(tlmi_priv.class_dev);
+ fw_attributes_class_put();
+ }
+
+--
+2.39.5
+
--- /dev/null
+From a7fafb96b43bba18087a6ae3998e0da6d1fee109 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jul 2025 04:35:20 -0400
+Subject: s390/pci: Fix stale function handles in error handling
+
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+
+[ Upstream commit 45537926dd2aaa9190ac0fac5a0fbeefcadfea95 ]
+
+The error event information for PCI error events contains a function
+handle for the respective function. This handle is generally captured at
+the time the error event was recorded. Due to delays in processing or
+cascading issues, it may happen that during firmware recovery multiple
+events are generated. When processing these events in order Linux may
+already have recovered an affected function making the event information
+stale. Fix this by doing an unconditional CLP List PCI function
+retrieving the current function handle with the zdev->state_lock held
+and ignoring the event if its function handle is stale.
+
+Cc: stable@vger.kernel.org
+Fixes: 4cdf2f4e24ff ("s390/pci: implement minimal PCI error recovery")
+Reviewed-by: Julian Ruess <julianr@linux.ibm.com>
+Reviewed-by: Gerd Bayer <gbayer@linux.ibm.com>
+Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
+Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/pci/pci_event.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c
+index d969f36bf186f..dc512c8f82324 100644
+--- a/arch/s390/pci/pci_event.c
++++ b/arch/s390/pci/pci_event.c
+@@ -257,6 +257,8 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
+ struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
+ struct pci_dev *pdev = NULL;
+ pci_ers_result_t ers_res;
++ u32 fh = 0;
++ int rc;
+
+ zpci_dbg(3, "err fid:%x, fh:%x, pec:%x\n",
+ ccdf->fid, ccdf->fh, ccdf->pec);
+@@ -264,9 +266,23 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
+ zpci_err_hex(ccdf, sizeof(*ccdf));
+
+ if (zdev) {
++ mutex_lock(&zdev->state_lock);
++ rc = clp_refresh_fh(zdev->fid, &fh);
++ if (rc) {
++ mutex_unlock(&zdev->state_lock);
++ goto no_pdev;
++ }
++ if (!fh || ccdf->fh != fh) {
++ /* Ignore events with stale handles */
++ zpci_dbg(3, "err fid:%x, fh:%x (stale %x)\n",
++ ccdf->fid, fh, ccdf->fh);
++ mutex_unlock(&zdev->state_lock);
++ goto no_pdev;
++ }
+ zpci_update_fh(zdev, ccdf->fh);
+ if (zdev->zbus->bus)
+ pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn);
++ mutex_unlock(&zdev->state_lock);
+ }
+
+ pr_err("%s: Event 0x%x reports an error for PCI function 0x%x\n",
+--
+2.39.5
+
acpica-refuse-to-evaluate-a-method-if-arguments-are-.patch
mtd-spinand-fix-memory-leak-of-ecc-engine-conf.patch
rcu-return-early-if-callback-is-not-specified.patch
+virtio-net-ensure-the-received-length-does-not-excee.patch
+s390-pci-fix-stale-function-handles-in-error-handlin.patch
+drm-v3d-disable-interrupts-before-resetting-the-gpu.patch
+nfsv4-flexfiles-fix-handling-of-nfs-level-errors-in-.patch
+btrfs-use-btrfs_record_snapshot_destroy-during-rmdir.patch
+dpaa2-eth-fix-xdp_rxq_info-leak.patch
+platform-x86-think-lmi-fix-class-device-unregistrati.patch
+platform-x86-dell-wmi-sysman-fix-class-device-unregi.patch
+net-usb-lan78xx-fix-warn-in-__netif_napi_del_locked-.patch
--- /dev/null
+From b4d2801cd0ce9ca42a51c90f5346a1f3cb72c18f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jul 2025 04:14:54 -0400
+Subject: virtio-net: ensure the received length does not exceed allocated size
+
+From: Bui Quang Minh <minhquangbui99@gmail.com>
+
+[ Upstream commit 315dbdd7cdf6aa533829774caaf4d25f1fd20e73 ]
+
+In xdp_linearize_page, when reading the following buffers from the ring,
+we forget to check the received length with the true allocate size. This
+can lead to an out-of-bound read. This commit adds that missing check.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 4941d472bf95 ("virtio-net: do not reset during XDP set")
+Signed-off-by: Bui Quang Minh <minhquangbui99@gmail.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Link: https://patch.msgid.link/20250630144212.48471-2-minhquangbui99@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/virtio_net.c | 38 ++++++++++++++++++++++++++++++++++----
+ 1 file changed, 34 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index 11aa0a7d54cd7..1b4cf8eb7e136 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -440,6 +440,26 @@ static unsigned int mergeable_ctx_to_truesize(void *mrg_ctx)
+ return (unsigned long)mrg_ctx & ((1 << MRG_CTX_HEADER_SHIFT) - 1);
+ }
+
++static int check_mergeable_len(struct net_device *dev, void *mrg_ctx,
++ unsigned int len)
++{
++ unsigned int headroom, tailroom, room, truesize;
++
++ truesize = mergeable_ctx_to_truesize(mrg_ctx);
++ headroom = mergeable_ctx_to_headroom(mrg_ctx);
++ tailroom = headroom ? sizeof(struct skb_shared_info) : 0;
++ room = SKB_DATA_ALIGN(headroom + tailroom);
++
++ if (len > truesize - room) {
++ pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
++ dev->name, len, (unsigned long)(truesize - room));
++ DEV_STATS_INC(dev, rx_length_errors);
++ return -1;
++ }
++
++ return 0;
++}
++
+ /* Called from bottom half context */
+ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
+ struct receive_queue *rq,
+@@ -719,7 +739,8 @@ static unsigned int virtnet_get_headroom(struct virtnet_info *vi)
+ * across multiple buffers (num_buf > 1), and we make sure buffers
+ * have enough headroom.
+ */
+-static struct page *xdp_linearize_page(struct receive_queue *rq,
++static struct page *xdp_linearize_page(struct net_device *dev,
++ struct receive_queue *rq,
+ u16 *num_buf,
+ struct page *p,
+ int offset,
+@@ -739,18 +760,27 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
+ memcpy(page_address(page) + page_off, page_address(p) + offset, *len);
+ page_off += *len;
+
++ /* Only mergeable mode can go inside this while loop. In small mode,
++ * *num_buf == 1, so it cannot go inside.
++ */
+ while (--*num_buf) {
+ unsigned int buflen;
+ void *buf;
++ void *ctx;
+ int off;
+
+- buf = virtqueue_get_buf(rq->vq, &buflen);
++ buf = virtqueue_get_buf_ctx(rq->vq, &buflen, &ctx);
+ if (unlikely(!buf))
+ goto err_buf;
+
+ p = virt_to_head_page(buf);
+ off = buf - page_address(p);
+
++ if (check_mergeable_len(dev, ctx, buflen)) {
++ put_page(p);
++ goto err_buf;
++ }
++
+ /* guard against a misconfigured or uncooperative backend that
+ * is sending packet larger than the MTU.
+ */
+@@ -831,7 +861,7 @@ static struct sk_buff *receive_small(struct net_device *dev,
+ headroom = vi->hdr_len + header_offset;
+ buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+- xdp_page = xdp_linearize_page(rq, &num_buf, page,
++ xdp_page = xdp_linearize_page(dev, rq, &num_buf, page,
+ offset, header_offset,
+ &tlen);
+ if (!xdp_page)
+@@ -1006,7 +1036,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
+ if (unlikely(num_buf > 1 ||
+ headroom < virtnet_get_headroom(vi))) {
+ /* linearize data for XDP */
+- xdp_page = xdp_linearize_page(rq, &num_buf,
++ xdp_page = xdp_linearize_page(dev, rq, &num_buf,
+ page, offset,
+ VIRTIO_XDP_HEADROOM,
+ &len);
+--
+2.39.5
+