From 1d0e25c1ddf2063c499264fb2ba0fa6a3e4f8a00 Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Sat, 27 Jun 2026 12:57:25 +0200 Subject: [PATCH 01/15] udmabuf: Ensure to perform cache synchronisation in begin_cpu_udmabuf() The message of commit 504e2b4ab97a ("dma-buf/udmabuf: skip redundant cpu sync to fix cacheline EEXIST warning") says: > The CPU sync at map/unmap time is also redundant for udmabuf: > begin_cpu_udmabuf() and end_cpu_udmabuf() already perform explicit > cache synchronization via dma_sync_sgtable_for_cpu/device() when CPU > access is requested through the dma-buf interface. This, however, does not apply to the first time begin_cpu_udmabuf() is called on an udmabuf, in which case the implementation previously relied on get_sg_table() to perform the cache synchronisation. Ensure to call dma_sync_sgtable_for_cpu() in that case as well. Fixes: 504e2b4ab97a ("dma-buf/udmabuf: skip redundant cpu sync to fix cacheline EEXIST warning") Signed-off-by: Robert Mader Reviewed-by: Mikhail Gavrilov Signed-off-by: Vivek Kasireddy Link: https://patch.msgid.link/20260627105725.9083-1-robert.mader@collabora.com --- drivers/dma-buf/udmabuf.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index bced421c0d65..08f57bc1294d 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -224,21 +224,22 @@ static int begin_cpu_udmabuf(struct dma_buf *buf, { struct udmabuf *ubuf = buf->priv; struct device *dev = ubuf->device->this_device; - int ret = 0; if (!ubuf->sg) { ubuf->sg = get_sg_table(dev, buf, direction); if (IS_ERR(ubuf->sg)) { + int ret; + ret = PTR_ERR(ubuf->sg); ubuf->sg = NULL; + return ret; } else { ubuf->sg_dir = direction; } - } else { - dma_sync_sgtable_for_cpu(dev, ubuf->sg, direction); } - return ret; + dma_sync_sgtable_for_cpu(dev, ubuf->sg, direction); + return 0; } static int end_cpu_udmabuf(struct dma_buf *buf, From e4159045c2704dfe146f0ccb0445d9d074cd6882 Mon Sep 17 00:00:00 2001 From: Karol Wachowski Date: Fri, 10 Jul 2026 12:13:31 +0200 Subject: [PATCH 02/15] accel/ivpu: Fix wrong register read in LNL failure diagnostics diagnose_failure_lnl() read VPU_HW_BTRS_MTL_INTERRUPT_STAT instead of VPU_HW_BTRS_LNL_INTERRUPT_STAT, which on LNL and newer parts is a different register with a different bit layout, so failure diagnostics decoded the wrong register and reported a bogus error cause. Read the LNL interrupt status register instead. Fixes: 8a27ad81f7d3 ("accel/ivpu: Split IP and buttress code") Reviewed-by: Andrzej Kacprowski Signed-off-by: Karol Wachowski Link: https://patch.msgid.link/20260710101331.1899505-1-karol.wachowski@linux.intel.com --- drivers/accel/ivpu/ivpu_hw_btrs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index dac935164e11..a17c829adb89 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -927,7 +927,7 @@ static void diagnose_failure_mtl(struct ivpu_device *vdev) static void diagnose_failure_lnl(struct ivpu_device *vdev) { - u32 reg = REGB_RD32(VPU_HW_BTRS_MTL_INTERRUPT_STAT) & BTRS_LNL_IRQ_MASK; + u32 reg = REGB_RD32(VPU_HW_BTRS_LNL_INTERRUPT_STAT) & BTRS_LNL_IRQ_MASK; if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, ATS_ERR, reg)) { ivpu_err(vdev, "ATS_ERR_LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n", From d489a5305b9d5480d6fb97d5636f5f4b1e0b3827 Mon Sep 17 00:00:00 2001 From: Jason Macnak Date: Thu, 25 Jun 2026 10:08:28 -0700 Subject: [PATCH 03/15] drm/virtio: Don't detach GEM from a non-created context Applies the same treatment as commit 7cf6dd467e87 ("drm/virtio: Don't attach GEM to a non-created context in gem_object_open()") to virtio_gpu_gem_object_close() to avoid trying to detach a resource that was never attached due to a context never being created when context_init is supported. Fixes: 086b9f27f0ab ("drm/virtio: Don't create a context with default param if context_init is supported") Cc: # v6.14+ Signed-off-by: Jason Macnak Signed-off-by: Dmitry Osipenko Link: https://patch.msgid.link/20260625170828.3335431-1-natsu@google.com --- drivers/gpu/drm/virtio/virtgpu_gem.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c index 435d37d36034..66c3f6f74e9c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_gem.c +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c @@ -139,13 +139,15 @@ void virtio_gpu_gem_object_close(struct drm_gem_object *obj, if (!vgdev->has_virgl_3d) return; - objs = virtio_gpu_array_alloc(1); - if (!objs) - return; - virtio_gpu_array_add_obj(objs, obj); + if (vfpriv->context_created) { + objs = virtio_gpu_array_alloc(1); + if (!objs) + return; + virtio_gpu_array_add_obj(objs, obj); - virtio_gpu_cmd_context_detach_resource(vgdev, vfpriv->ctx_id, - objs); + virtio_gpu_cmd_context_detach_resource(vgdev, vfpriv->ctx_id, + objs); + } virtio_gpu_notify(vgdev); } From d1b894c5bbb3fee0012bd14356286dc2384e8213 Mon Sep 17 00:00:00 2001 From: Ryosuke Yasuoka Date: Mon, 13 Jul 2026 22:01:00 +0900 Subject: [PATCH 04/15] drm/virtio: fix deadlock in display_info_cb by removing hotplug from dequeue worker A probe-time deadlock can occur between the dequeue worker and drm_client_register(). During probe, drm_client_register() holds clientlist_mutex and calls the fbdev hotplug callback, which triggers an atomic commit that ends up sleeping in virtio_gpu_queue_ctrl_sgs() waiting for virtqueue space. The dequeue worker that would free that space calls virtio_gpu_cmd_get_display_info_cb(), which invokes drm_kms_helper_hotplug_event() -> drm_client_dev_hotplug(), attempting to acquire the same clientlist_mutex. Since wake_up() is only called after the resp_cb loop, the probe thread is never woken and both threads deadlock. Fix this by removing the hotplug notification from virtio_gpu_cmd_get_display_info_cb(). The display data (outputs[i].info) is still updated synchronously in the callback. For the init path, drm_client_register() already fires an initial hotplug when the client is registered, which picks up the connector state updated by display_info_cb. For the runtime config_changed path, add a wait_event_timeout() in config_changed_work_func() so that display_info_cb updates the connector data before the hotplug notification is sent. Also replace drm_helper_hpd_irq_event() with drm_kms_helper_hotplug_event() since virtio-gpu never calls drm_kms_helper_poll_init() and thus drm_helper_hpd_irq_event() always returns false without doing anything. Fixes: 27655b9bb9f0 ("drm/client: Send hotplug event after registering a client") Closes: https://syzkaller.appspot.com/bug?id=d6dd6f86d3aaf7eebe7406e45c1c6e549453f224 Closes: https://syzkaller.appspot.com/bug?id=908bd910da5dd79b88de4cf7baf376cc873a922e Suggested-by: Dmitry Osipenko Signed-off-by: Ryosuke Yasuoka Signed-off-by: Dmitry Osipenko Link: https://patch.msgid.link/20260713-virtiogpu_syzbot-v2-1-2958fa37d46d@redhat.com --- drivers/gpu/drm/virtio/virtgpu_kms.c | 5 ++++- drivers/gpu/drm/virtio/virtgpu_vq.c | 3 --- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index cfde9f573df6..b4329f28e976 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -49,7 +49,10 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work) virtio_gpu_cmd_get_edids(vgdev); virtio_gpu_cmd_get_display_info(vgdev); virtio_gpu_notify(vgdev); - drm_helper_hpd_irq_event(vgdev->ddev); + wait_event_timeout(vgdev->resp_wq, + !vgdev->display_info_pending, + 5 * HZ); + drm_kms_helper_hotplug_event(vgdev->ddev); } events_clear |= VIRTIO_GPU_EVENT_DISPLAY; } diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index c8b9475a7472..e5e1af8b8e8a 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -840,9 +840,6 @@ static void virtio_gpu_cmd_get_display_info_cb(struct virtio_gpu_device *vgdev, vgdev->display_info_pending = false; spin_unlock(&vgdev->display_info_lock); wake_up(&vgdev->resp_wq); - - if (!drm_helper_hpd_irq_event(vgdev->ddev)) - drm_kms_helper_hotplug_event(vgdev->ddev); } static void virtio_gpu_cmd_get_capset_info_cb(struct virtio_gpu_device *vgdev, From 0bc7c196f3ab855da0879283ba633c4c51ddfd81 Mon Sep 17 00:00:00 2001 From: Honglei Huang Date: Wed, 1 Jul 2026 14:27:58 +0800 Subject: [PATCH 05/15] drm/gpusvm: free the whole IOVA reservation on unmap dma_iova_try_alloc() reserves IOVA for the entire range, but in a mixed range only the system pages are linked (their total size is state_offset) while device pages never touch the IOVA state. dma_iova_destroy() with state_offset only frees the linked part, permanently leaking the IOVA reserved for the device pages and eventually exhausting the IOVA space. Unlink the linked system-page portion and free the whole reserved IOVA instead. On the get_pages() error path state_offset is 0 (no page linked, dma_addr[0] unpopulated), so skip the unlink and just free the reservation; this also avoids reading the uninitialized dma_addr[0].dir there. Allocate the dma_addr array with the zeroing kvzalloc_objs() so every entry has a well-defined value. This issue was found by Sashiko AI review. Fixes: 37ad039fb367 ("drm/gpusvm: Use dma-map IOVA alloc, link, and sync API in GPU SVM") Cc: stable@vger.kernel.org Reviewed-by: Matthew Brost Signed-off-by: Honglei Huang Signed-off-by: Matthew Brost Link: https://patch.msgid.link/20260701062800.409248-2-honghuan@amd.com --- drivers/gpu/drm/drm_gpusvm.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c index 958cb605aedd..3145d55cd860 100644 --- a/drivers/gpu/drm/drm_gpusvm.c +++ b/drivers/gpu/drm/drm_gpusvm.c @@ -1146,10 +1146,19 @@ static void __drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm, }; bool use_iova = dma_use_iova(&svm_pages->state); - if (use_iova) - dma_iova_destroy(dev, &svm_pages->state, - svm_pages->state_offset, - svm_pages->dma_addr[0].dir, 0); + /* + * IOVA is reserved for the whole range but only the linked + * system pages (state_offset bytes) need unlinking; free the + * entire reservation to avoid leaking the device-page part. + * On the error path state_offset is 0, so just free it. + */ + if (use_iova) { + if (svm_pages->state_offset) + dma_iova_unlink(dev, &svm_pages->state, 0, + svm_pages->state_offset, + svm_pages->dma_addr[0].dir, 0); + dma_iova_free(dev, &svm_pages->state); + } for (i = 0, j = 0; i < npages; j++) { struct drm_pagemap_addr *addr = &svm_pages->dma_addr[j]; @@ -1486,7 +1495,7 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, /* Unlock and restart mapping to allocate memory. */ drm_gpusvm_notifier_unlock(gpusvm); svm_pages->dma_addr = - kvmalloc_objs(*svm_pages->dma_addr, npages); + kvzalloc_objs(*svm_pages->dma_addr, npages); if (!svm_pages->dma_addr) { err = -ENOMEM; goto err_free; From ea2f9985aa4adeef89e9523be295633bb3d0874a Mon Sep 17 00:00:00 2001 From: Honglei Huang Date: Wed, 1 Jul 2026 14:27:59 +0800 Subject: [PATCH 06/15] drm/gpusvm: do not route system pages to device_unmap() on IOVA unmap In a mixed range: ctx->allow_mixed dpagemap is not NULL while some entries are system pages. The unmap loop used: dma_unmap_page(...); else if (dpagemap && dpagemap->ops->device_unmap) dpagemap->ops->device_unmap(...); When use_iova is true the first condition is false for system pages, so they fall through to device_unmap() and a system DMA address is handed to the device specific unmap callback, risking invalid accesses or state corruption. Key the branch off addr->proto instead: system pages only need an explicit dma_unmap_page() in the non IOVA case, IOVA system pages are already torn down by the single dma_iova_destroy(), and only genuine device pages reach device_unmap(). This issue was found by Sashiko AI review. Fixes: 37ad039fb367 ("drm/gpusvm: Use dma-map IOVA alloc, link, and sync API in GPU SVM") Cc: stable@vger.kernel.org Reviewed-by: Matthew Brost Signed-off-by: Honglei Huang Signed-off-by: Matthew Brost Link: https://patch.msgid.link/20260701062800.409248-3-honghuan@amd.com --- drivers/gpu/drm/drm_gpusvm.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c index 3145d55cd860..44bb19658dd6 100644 --- a/drivers/gpu/drm/drm_gpusvm.c +++ b/drivers/gpu/drm/drm_gpusvm.c @@ -1163,12 +1163,18 @@ static void __drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm, for (i = 0, j = 0; i < npages; j++) { struct drm_pagemap_addr *addr = &svm_pages->dma_addr[j]; - if (!use_iova && addr->proto == DRM_INTERCONNECT_SYSTEM) - dma_unmap_page(dev, - addr->addr, - PAGE_SIZE << addr->order, - addr->dir); - else if (dpagemap && dpagemap->ops->device_unmap) + if (addr->proto == DRM_INTERCONNECT_SYSTEM) { + /* + * Linked IOVA pages were already torn down by + * the dma_iova_unlink()/dma_iova_free() above; + * only the non-IOVA mappings need unmap here. + */ + if (!use_iova) + dma_unmap_page(dev, + addr->addr, + PAGE_SIZE << addr->order, + addr->dir); + } else if (dpagemap && dpagemap->ops->device_unmap) dpagemap->ops->device_unmap(dpagemap, dev, addr); i += 1 << addr->order; From 7f708f51e3955bda0d77a0b67ab9bea6c97fea99 Mon Sep 17 00:00:00 2001 From: Honglei Huang Date: Wed, 1 Jul 2026 14:28:00 +0800 Subject: [PATCH 07/15] drm/gpusvm: publish dpagemap early to avoid device mapping leak on error drm_gpusvm_get_pages() only stored the local dpagemap into svm_pages->dpagemap on the success path. If a later page failed (e.g. -EOPNOTSUPP when ctx->allow_mixed is false) and jumped to err_unmap, svm_pages->dpagemap was still NULL, so __drm_gpusvm_unmap_pages() skipped device_unmap() and leaked the device mappings already created. Assign svm_pages->dpagemap when the first device page is mapped so the err_unmap path can device_unmap() those mappings. This issue was found by Sashiko AI review. Fixes: f70da6f99d4f ("drm/gpusvm: pull out drm_gpusvm_pages substructure") Cc: stable@vger.kernel.org Reviewed-by: Matthew Brost Signed-off-by: Honglei Huang Signed-off-by: Matthew Brost Link: https://patch.msgid.link/20260701062800.409248-4-honghuan@amd.com --- drivers/gpu/drm/drm_gpusvm.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c index 44bb19658dd6..9a06ff7d2608 100644 --- a/drivers/gpu/drm/drm_gpusvm.c +++ b/drivers/gpu/drm/drm_gpusvm.c @@ -1544,6 +1544,16 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, err = -EAGAIN; goto err_unmap; } + + /* + * Set the dpagemap as soon as the first + * device page is mapped so the err_unmap path + * can device_unmap() the device mappings that + * have already been created. + */ + drm_pagemap_get(dpagemap); + drm_pagemap_put(svm_pages->dpagemap); + svm_pages->dpagemap = dpagemap; } svm_pages->dma_addr[j] = dpagemap->ops->device_map(dpagemap, @@ -1611,12 +1621,8 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, goto err_unmap; } - if (pagemap) { + if (pagemap) flags.has_devmem_pages = true; - drm_pagemap_get(dpagemap); - drm_pagemap_put(svm_pages->dpagemap); - svm_pages->dpagemap = dpagemap; - } /* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */ WRITE_ONCE(svm_pages->flags.__flags, flags.__flags); From 261c1fe3327ad24508f54552c6366e3e4db82c15 Mon Sep 17 00:00:00 2001 From: Doruk Tan Ozturk Date: Mon, 13 Jul 2026 19:30:28 +0200 Subject: [PATCH 08/15] accel/amdxdna: reject user command submission without a command BO amdxdna_drm_submit_execbuf() passes the user-supplied command BO handle straight into amdxdna_cmd_submit() with drv_cmd == NULL. When the handle is AMDXDNA_INVALID_BO_HANDLE (0), the block that fetches job->cmd_bo is skipped, leaving it NULL, and no check rejects it on the user path (the !job->cmd_bo guard lives inside the != INVALID branch). The job is then armed and pushed to the DRM scheduler. aie2_sched_job_run() takes the drv_cmd == NULL path and calls amdxdna_cmd_set_state(job->cmd_bo) -> amdxdna_gem_vmap(NULL) -> to_gobj(NULL)->dev, a NULL pointer dereference in the drm_sched worker. A process with access to the accel node on a system with a probed AMD NPU can trigger a kernel oops with a single AMDXDNA_EXEC_CMD ioctl (cmd_handles = 0). Only internal driver commands (SYNC_DEBUG_BO / ATTACH_DEBUG_BO) legitimately pass AMDXDNA_INVALID_BO_HANDLE, and they always set drv_cmd. Reject the invalid handle for user submissions (drv_cmd == NULL) at the submit choke point so every user path is covered. Fixes: aac243092b70 ("accel/amdxdna: Add command execution") Cc: stable@vger.kernel.org Found by 0sec automated security-research tooling (https://0sec.ai). Assisted-by: 0sec:claude-opus-4-8 Signed-off-by: Doruk Tan Ozturk Reviewed-by: Lizhi Hou Signed-off-by: Lizhi Hou Link: https://patch.msgid.link/20260713173030.87541-2-doruk@0sec.ai --- drivers/accel/amdxdna/amdxdna_ctx.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/accel/amdxdna/amdxdna_ctx.c b/drivers/accel/amdxdna/amdxdna_ctx.c index 8f8df9d04ec5..a5c8c2c4de6d 100644 --- a/drivers/accel/amdxdna/amdxdna_ctx.c +++ b/drivers/accel/amdxdna/amdxdna_ctx.c @@ -603,6 +603,16 @@ int amdxdna_cmd_submit(struct amdxdna_client *client, ret = -EINVAL; goto free_job; } + } else if (!drv_cmd) { + /* + * Only internal driver commands (drv_cmd != NULL) may omit a + * command BO. A user command submission with the invalid handle + * would leave job->cmd_bo NULL and later fault when the scheduler + * dereferences it in amdxdna_cmd_set_state(). + */ + XDNA_DBG(xdna, "Command BO handle required for user submission"); + ret = -EINVAL; + goto free_job; } ret = amdxdna_arg_bos_lookup(client, job, arg_bo_hdls, arg_bo_cnt); From 38953513d7313992676d4136cd425cdb70c6278e Mon Sep 17 00:00:00 2001 From: Doruk Tan Ozturk Date: Mon, 13 Jul 2026 19:30:29 +0200 Subject: [PATCH 09/15] accel/amdxdna: reject command submission on devices without a submit op amdxdna_cmd_submit() calls xdna->dev_info->ops->cmd_submit() unconditionally, but only aie2_dev_ops defines that callback. aie4_vf_ops (the AIE4 SR-IOV virtual function) does not, so a user AMDXDNA_EXEC_CMD ioctl on an AIE4 device reaches a NULL function-pointer call and oopses the kernel. AIE4 submits work through a mapped user queue and doorbell, not this ioctl path. Reject the submission early with -EOPNOTSUPP when the device provides no cmd_submit op, so the shared EXEC ioctl is a clean no-op on such devices. Fixes: aac243092b70 ("accel/amdxdna: Add command execution") Cc: stable@vger.kernel.org Found by 0sec automated security-research tooling (https://0sec.ai). Assisted-by: 0sec:claude-opus-4-8 Signed-off-by: Doruk Tan Ozturk Reviewed-by: Lizhi Hou Signed-off-by: Lizhi Hou Link: https://patch.msgid.link/20260713173030.87541-3-doruk@0sec.ai --- drivers/accel/amdxdna/amdxdna_ctx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/accel/amdxdna/amdxdna_ctx.c b/drivers/accel/amdxdna/amdxdna_ctx.c index a5c8c2c4de6d..bdbd3db12a6c 100644 --- a/drivers/accel/amdxdna/amdxdna_ctx.c +++ b/drivers/accel/amdxdna/amdxdna_ctx.c @@ -590,6 +590,10 @@ int amdxdna_cmd_submit(struct amdxdna_client *client, int ret, idx; XDNA_DBG(xdna, "Command BO hdl %d, Arg BO count %d", cmd_bo_hdl, arg_bo_cnt); + + if (!xdna->dev_info->ops->cmd_submit) + return -EOPNOTSUPP; + job = kzalloc_flex(*job, bos, arg_bo_cnt); if (!job) return -ENOMEM; From 5b7b3b6595ee77d01c7463757baed114786094dd Mon Sep 17 00:00:00 2001 From: Matthew Brost Date: Thu, 2 Jul 2026 14:48:15 -0700 Subject: [PATCH 10/15] drm/ttm: Account for NULL and handle pages in ttm_pool_backup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pages in ttm_pool_backup can be NULL or backup handles (ttm_backup_page_ptr_is_handle()), neither of which can be passed to set_pages_array_wb() or freed. Add a dedicated WB pass before the dma/purge loop that walks allocations using the same i += num_pages stride, skipping NULL and handle entries, and calls set_pages_array_wb() once per contiguous run of real pages. Apply the same NULL/handle guard to the dma/purge loop. Fixes the following oops: Oops: general protection fault, kernel NULL pointer dereference 0x0: 0000 [#1] SMP NOPTI RIP: 0010:__cpa_process_fault+0xf8/0x770 RSP: 0018:ffffc90000a87718 EFLAGS: 00010287 RAX: 0000000000000000 RBX: ffffc90000a87868 RCX: 0000000000000000 RDX: 0000000000001000 RSI: 0005088000000000 RDI: ffffffff827c5f34 RBP: 0005088000000000 R08: ffffc90000a877cb R09: ffffc90000a877d0 R10: 0000000000000000 R11: 000000000000001b R12: 000ffffffffff000 R13: ffffc90000a87868 R14: ffffc90000a87868 R15: ffff88815b882ae0 FS: 0000000000000000(0000) GS:ffff8884ec840000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f930b844000 CR3: 000000000262e003 CR4: 0000000008f70ef0 PKRU: 55555554 Call Trace: __change_page_attr_set_clr+0x989/0xe90 ? __purge_vmap_area_lazy+0x6c/0x3a0 ? _vm_unmap_aliases+0x250/0x2a0 set_pages_array_wb+0x7f/0x120 ttm_pool_backup+0x4c9/0x5b0 [ttm] ? dma_resv_wait_timeout+0x3b/0xf0 ttm_tt_backup+0x32/0x60 [ttm] ttm_bo_shrink+0x66/0x110 [ttm] xe_bo_shrink_purge+0x12b/0x1b0 [xe] xe_bo_shrink+0xbb/0x270 [xe] __xe_shrinker_walk+0xf7/0x160 [xe] xe_shrinker_walk+0x9d/0xc0 [xe] xe_shrinker_scan+0x11f/0x210 [xe] do_shrink_slab+0x13b/0x270 shrink_slab+0xf1/0x400 shrink_node+0x352/0x8a0 balance_pgdat+0x32c/0x700 kswapd+0x205/0x2f0 ? __pfx_autoremove_wake_function+0x10/0x10 ? __pfx_kswapd+0x10/0x10 kthread+0xd1/0x110 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x1b1/0x200 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 Cc: Christian Koenig Cc: Huang Rui Cc: Matthew Auld Cc: Matthew Brost Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Simona Vetter Cc: Thomas Hellström Cc: dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org Fixes: b63d715b8090 ("drm/ttm/pool, drm/ttm/tt: Provide a helper to shrink pages") Cc: stable@vger.kernel.org Assisted-by: GitHub_Copilot:claude-opus-4.8 Signed-off-by: Matthew Brost Reviewed-by: Thomas Hellström Link: https://patch.msgid.link/20260702214815.4009271-1-matthew.brost@intel.com --- drivers/gpu/drm/ttm/ttm_pool.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index 278bbe7a11ad..46983e7de7a3 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -1051,9 +1051,31 @@ long ttm_pool_backup(struct ttm_pool *pool, struct ttm_tt *tt, return -EBUSY; #ifdef CONFIG_X86 - /* Anything returned to the system needs to be cached. */ - if (tt->caching != ttm_cached) - set_pages_array_wb(tt->pages, tt->num_pages); + /* Anything returned to the system needs to be cached. Walk allocations + * skipping NULL pages and issue set_pages_array_wb() per contiguous run. + */ + if (tt->caching != ttm_cached) { + pgoff_t run_start = 0, run_count = 0; + + for (i = 0; i < tt->num_pages; i += num_pages) { + page = tt->pages[i]; + if (unlikely(!page || ttm_backup_page_ptr_is_handle(page))) { + if (run_count) { + set_pages_array_wb(&tt->pages[run_start], + run_count); + run_count = 0; + } + num_pages = 1; + continue; + } + num_pages = 1UL << ttm_pool_page_order(pool, page); + if (!run_count) + run_start = i; + run_count += num_pages; + } + if (run_count) + set_pages_array_wb(&tt->pages[run_start], run_count); + } #endif if (tt->dma_address || flags->purge) { @@ -1061,7 +1083,7 @@ long ttm_pool_backup(struct ttm_pool *pool, struct ttm_tt *tt, unsigned int order; page = tt->pages[i]; - if (unlikely(!page)) { + if (unlikely(!page || ttm_backup_page_ptr_is_handle(page))) { num_pages = 1; continue; } @@ -1104,6 +1126,10 @@ long ttm_pool_backup(struct ttm_pool *pool, struct ttm_tt *tt, if (unlikely(!page)) continue; + /* Already-handled entry from a previous attempt. */ + if (unlikely(ttm_backup_page_ptr_is_handle(page))) + continue; + ttm_pool_split_for_swap(pool, page); shandle = ttm_backup_backup_page(backup, page, flags->writeback, i, From 4a2c8cbe9bcba170706fdf08b1c84b6cbcf5b044 Mon Sep 17 00:00:00 2001 From: Osama Abdelkader Date: Tue, 14 Jul 2026 18:30:55 +0200 Subject: [PATCH 11/15] drm/panthor: return error on truncated firmware panthor_fw_load() detects truncated firmware images, but jumps to the common cleanup path without setting ret. If no previous error was recorded, the function can return 0 and treat the invalid firmware as successfully loaded. Set ret to -EINVAL before leaving the truncated-image path. Fixes: 2718d91816ee ("drm/panthor: Add the FW logical block") Cc: stable@vger.kernel.org Signed-off-by: Osama Abdelkader Reviewed-by: Liviu Dudau Reviewed-by: Boris Brezillon Link: https://patch.msgid.link/20260714163056.22329-1-osama.abdelkader@gmail.com Signed-off-by: Liviu Dudau --- drivers/gpu/drm/panthor/panthor_fw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panthor/panthor_fw.c b/drivers/gpu/drm/panthor/panthor_fw.c index de8e6689a869..90f59d782a80 100644 --- a/drivers/gpu/drm/panthor/panthor_fw.c +++ b/drivers/gpu/drm/panthor/panthor_fw.c @@ -829,6 +829,7 @@ static int panthor_fw_load(struct panthor_device *ptdev) } if (hdr.size > iter.size) { + ret = -EINVAL; drm_err(&ptdev->base, "Firmware image is truncated\n"); goto out; } From 022e901333c3054656a640794e842bab7af5a75c Mon Sep 17 00:00:00 2001 From: Linmao Li Date: Mon, 13 Jul 2026 16:29:12 +0800 Subject: [PATCH 12/15] drm/panthor: Check debugfs GEM lock initialization drmm_mutex_init() can fail while registering the managed cleanup action. When that happens, drmm_add_action_or_reset() destroys the mutex before returning the error. Continuing initialization would therefore leave the debugfs GEM object list with an unusable lock. Propagate the error as is already done for the other managed mutexes in panthor_device_init(). Fixes: a3707f53eb3f ("drm/panthor: show device-wide list of DRM GEM objects over DebugFS") Signed-off-by: Linmao Li Reviewed-by: Liviu Dudau Link: https://patch.msgid.link/20260713082912.321021-1-lilinmao@kylinos.cn Signed-off-by: Liviu Dudau --- drivers/gpu/drm/panthor/panthor_device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c index 0b25abebb803..9687c59de350 100644 --- a/drivers/gpu/drm/panthor/panthor_device.c +++ b/drivers/gpu/drm/panthor/panthor_device.c @@ -182,7 +182,10 @@ int panthor_device_init(struct panthor_device *ptdev) return ret; #ifdef CONFIG_DEBUG_FS - drmm_mutex_init(&ptdev->base, &ptdev->gems.lock); + ret = drmm_mutex_init(&ptdev->base, &ptdev->gems.lock); + if (ret) + return ret; + INIT_LIST_HEAD(&ptdev->gems.node); #endif From ddb44baed257560f192b145ed36cf8c0a412de47 Mon Sep 17 00:00:00 2001 From: Jhonraushan Date: Wed, 15 Jul 2026 13:12:06 +0530 Subject: [PATCH 13/15] accel/ivpu: Reject firmware log with size smaller than header fw_log_from_bo() validates the tracing buffer header_size and that the log fits within the BO, but never checks that log->size is at least log->header_size. fw_log_print_buffer() then computes: u32 data_size = log->size - log->header_size; which underflows to a near-U32_MAX value when firmware reports a log whose size is smaller than its header. That huge data_size defeats the log_start/log_end bounds clamps added by commit dd1311bcf0e6 ("accel/ivpu: Add bounds checks for firmware log indices"), so fw_log_print_lines() reads far past the small real data region of the BO. A size of 0 also makes fw_log_from_bo() advance the offset by 0, causing the callers to loop forever on the same header. Reject logs whose size is smaller than the header (which also rejects size == 0). Fixes: d4e4257afa6e ("accel/ivpu: Add firmware tracing support") Cc: stable@vger.kernel.org Signed-off-by: Jhonraushan Reviewed-by: Karol Wachowski Signed-off-by: Karol Wachowski Link: https://patch.msgid.link/20260715074206.867712-1-raushan.jhon@gmail.com --- drivers/accel/ivpu/ivpu_fw_log.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index 275baf844b56..716467aa3156 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -43,6 +43,10 @@ static int fw_log_from_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *off ivpu_dbg(vdev, FW_BOOT, "Invalid header size 0x%x\n", log->header_size); return -EINVAL; } + if (log->size < log->header_size) { + ivpu_dbg(vdev, FW_BOOT, "Invalid log size 0x%x\n", log->size); + return -EINVAL; + } if ((char *)log + log->size > (char *)ivpu_bo_vaddr(bo) + ivpu_bo_size(bo)) { ivpu_dbg(vdev, FW_BOOT, "Invalid log size 0x%x\n", log->size); return -EINVAL; From 266cddf7bd0f6c79b6c0633aef742a22bf70265b Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Wed, 3 Jun 2026 17:37:49 +0900 Subject: [PATCH 14/15] gpu: host1x: Fix use-after-free in host1x_bo_clear_cached_mappings __host1x_bo_unpin() drops the last reference to the mapping and frees it, so we can't dereference mapping afterwards. The cache itself outlives the mapping, so use the cache local variable instead. Reported-by: Dan Carpenter Closes: https://lore.kernel.org/linux-tegra/ah6ErK6f4kVudVIA@stanley.mountain/T/#u Signed-off-by: Mikko Perttunen Signed-off-by: Thierry Reding Link: https://patch.msgid.link/20260603-host1x-bocache-leak-fix-v1-1-494101dbfd30@nvidia.com --- drivers/gpu/host1x/bus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index e3884096c2fe..ea3b584990c9 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -1012,10 +1012,10 @@ void host1x_bo_clear_cached_mappings(struct host1x_bo *bo) if (WARN_ON(!cache)) continue; - mutex_lock(&mapping->cache->lock); + mutex_lock(&cache->lock); WARN_ON(kref_read(&mapping->ref) != 1); __host1x_bo_unpin(&mapping->ref); - mutex_unlock(&mapping->cache->lock); + mutex_unlock(&cache->lock); } } EXPORT_SYMBOL(host1x_bo_clear_cached_mappings); From faebb7ba1ac65fa5810b640df02ce04e509fdc11 Mon Sep 17 00:00:00 2001 From: Lizhi Hou Date: Thu, 16 Jul 2026 08:13:05 -0700 Subject: [PATCH 15/15] accel/amdxdna: Fix use-after-free of mm_struct in job scheduler amdxdna_cmd_submit() stores current->mm in job->mm without holding any reference. aie2_sched_job_run() later access job->mm from the DRM scheduler worker thread. With only a raw pointer and no structural reference, the mm_struct can be freed before the scheduler runs the job. Fix this by calling mmgrab() to hold a structural mm_count reference for the lifetime of the job, paired with mmdrop() in every cleanup path. Fixes: aac243092b70 ("accel/amdxdna: Add command execution") Reviewed-by: Max Zhen Signed-off-by: Lizhi Hou Link: https://patch.msgid.link/20260716151305.1595780-1-lizhi.hou@amd.com --- drivers/accel/amdxdna/amdxdna_ctx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/accel/amdxdna/amdxdna_ctx.c b/drivers/accel/amdxdna/amdxdna_ctx.c index bdbd3db12a6c..31a414c3f0d9 100644 --- a/drivers/accel/amdxdna/amdxdna_ctx.c +++ b/drivers/accel/amdxdna/amdxdna_ctx.c @@ -577,6 +577,7 @@ void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job) amdxdna_arg_bos_put(job); amdxdna_gem_put_obj(job->cmd_bo); dma_fence_put(job->fence); + mmdrop(job->mm); } int amdxdna_cmd_submit(struct amdxdna_client *client, @@ -642,6 +643,7 @@ int amdxdna_cmd_submit(struct amdxdna_client *client, job->hwctx = hwctx; job->mm = current->mm; + mmgrab(job->mm); job->fence = amdxdna_fence_create(hwctx); if (!job->fence) { @@ -676,6 +678,8 @@ int amdxdna_cmd_submit(struct amdxdna_client *client, cmd_put: amdxdna_gem_put_obj(job->cmd_bo); free_job: + if (job->mm) + mmdrop(job->mm); kfree(job); return ret; }